-
-
Notifications
You must be signed in to change notification settings - Fork 431
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ts-loader with Typescript 4.5 beta: "Error: TypeScript emitted no output for .../index.mts" #1383
Comments
Haven't tried this at all - am interested with how this pans out! |
Yes, I believe it is because of the inclusion of the eventual extension.
but
Does ts-loader need to correct these paths for resolution? Or what? |
I'm not sure - webpack may need to be configured directly to support modules. Probably worth checking that out first. It may be that ts-loader just works with appropriate config. Or tweaks may be required. Please feel free to investigate; I'll assist where I can. |
I suspect this issue may be interesting to you @JasonKleban webpack/webpack#13252 |
It's possible that @alexander-akait's advice here may be what you need: webpack/webpack#13252 (comment)
|
I just want to cross-reference microsoft/TypeScript#37582 which is where I redirected microsoft/TypeScript#46344 to. I would love to hear feedback there from Webpack users about
|
Thanks @andrewbranch - much appreciated! |
@djcsdy - feels like this might be interesting to you given your work on https://github.com/softwareventures/resolve-typescript-plugin |
I think we don't need a plugin here, webpack already do the same for cjs/mjs, https://github.com/webpack/webpack/blob/main/lib/config/defaults.js#L490, somebody can shortly write problems places with resolving and what is expected and I will show/send a PR with implement |
@alexander-akait the issue is that in the new TypeScript module resolution modes, users must write |
@andrewbranch Thanks @johnnyreilly Does we support |
So people don't specify extensions when they're writing TypeScript with ts-loader at present. An import would be extensionless like so: import { faqsPath } from './misc/FAQs'; Even though the underlying file is |
Shorty:
Also we should respect |
For better setup we can use
so developer can setup it better using:
|
Ideally we should go away from the common |
Here only one edge case, if developer has |
@andersekdahl @johnnyreilly And another question, is typescript exports resolution logic (like function or class), because we can emulate it here, but in future, it can be changed more, maybe we can reuse resolution logic and avoid any problems in future? |
It’s internal API, but it looks like it’s already used here: Line 1290 in 8bc7b8b
|
hm, weird, it means |
I’ll give it a try this afternoon. |
@andrewbranch Feel free to ping me, I some busy today/tomorrow, but will be free on this weekends, and look at this deeply, will be glad to any investigations so we can fix it faster |
@alexander-akait I put up a super simple repro showing that |
Thanks, I will look at this |
@johnnyreilly We have a bug inside
Just put |
Also interesting when I use |
I don't fully understand the error to be honest. |
Solved: import { fileURLToPath } from "url";
import { dirname, join } from "path";
class NodeNextTSPlugin {
apply(resolver) {
const target = resolver.ensureHook("file");
resolver
.getHook("raw-file")
.tapAsync("NodeNextTSPlugin", (request, resolveContext, callback) => {
const obj = {
...request,
path: request.path.replace(/\.js(x?)/, '.ts$1'),
relativePath:
request.relativePath && request.relativePath.replace(/\.js(x?)/, '.ts$1')
};
resolver.doResolve(
target,
obj,
this.appending,
resolveContext,
callback
);
});
}
}
/** @type {import("webpack").Configuration} */
const config = {
mode: "development",
entry: "./src/main.ts",
output: {
path: join(dirname(fileURLToPath(import.meta.url)), "dist"),
},
module: {
rules: [{ test: /\.(m|c)?ts$/, use: "ts-loader" }]
},
resolve: {
plugins: [new NodeNextTSPlugin()],
extensions: [],
},
};
export default config; Also we can put it inside import { NodeNextTSPlugin } from "ts-loader"
export default {
// Developer options
resolver: {
plugins: [ new NodeNextTSPlugin() ].
}.
}; Regarding |
That's fast work! I think we'd be open to a PR that added this in. However I think work is still ongoing on how nodenext etc works in TypeScript and maybe we should be holding on for that? @andrewbranch may have a view
If you wanted to PR this fix now there's no reason we couldn't land it I think |
@johnnyreilly Anyway I strongly recommend do not use
https://webpack.js.org/configuration/resolve/#resolvebydependency module.exports = {
// ...
resolve: {
byDependency: {
// ...
typescript: {
// Other options
extensions: ['.my-strange-extension-for-ts'],
},
},
},
}; also it is cachable, now we spend time on creating
So my solutions:
|
@johnnyreilly Unfortunately, I don't have enough time right now (I am working on some great Anyway we can put solution in README (even it doesn't finished yet), so developer can start to use extensions in their imports like in ESM |
Thanks for sharing your thoughts @alexander-akait - I don't quite follow all the things you've suggested. If you wanted to start a PR maybe I'd be able to complete it for you? Or someone else too! |
Are you suggesting replacing: const originalFileName = resolveSync(
undefined,
path.normalize(path.dirname(containingFile)),
moduleName
); With: const originalFileName = resolveSync(path.normalize(path.dirname(containingFile)), moduleName); ?
It looks like this would be a non-breaking change? |
@johnnyreilly Yes, no breaking change, now it is just broken and do not work, put |
fwiw @alexander-akait's code is pretty close to what @softwareventures/resolve-typescript-plugin does. I do need to add support for @johnnyreilly If you're happy to take PRs to merge this kind of functionality into ts-loader, I can help with that, and remove the need for resolve-typescript-plugin in the process :-) |
@djcsdy Yep, anyway we can improve perf more, we don't need to rewrite it for all extensions https://github.com/softwareventures/resolve-typescript-plugin/blob/main/index.ts#L28, only for You register two hooks https://github.com/softwareventures/resolve-typescript-plugin/blob/main/index.ts#L24, it can be bad for perf if you have a lot of ts files, better to improve regexp and use only one hook |
Good suggestions, thank you @alexander-akait. |
@djcsdy - yup we're up for PRs! All help appreciated ❤️🌻 |
this should be solved by webpack/enhanced-resolve#351 webpack will have a new option for resolve
|
Temporary WorkaroundIn order to apply this fix, your Quick GuideI just gave it a try and temporarily changed your Lines 17 to 18 in 69a9c23
I was able to reach this goal using import { createSandbox } from "sinon";
import constants = require("ts-loader/dist/constants");
let sandbox = createSandbox();
sandbox.replace(constants, "jsJsx", /\.[cm]?js(x)?$/);
sandbox.replace(constants, "jsJsxMap", /\.[cm]?js(x)?\.map/); Then, I updated the test: /\.[cm]?tsx?$/, Furthermore, I had to add the resolve: {
extensionAlias: {
".js": [
".js",
".ts"
],
".mjs": [
".mjs",
".mts"
],
".cjs": [
".cjs",
".cts"
]
} After adding all this to my webpack-config, I was able to build my project despite the fact that it uses So, as far as I can tell, replacing said constants might fix ExplanationWhen using To tell However - after doing so, I faced the issuse that Lines 474 to 481 in 69a9c23
As you can see, This is why I came up with the solution to replace the regex patterns in the constants with However - using this workaround, I found myself able to successfully build my TypeScript project. The TL;DR VersionI think If file extensions such as |
What's still not working is importing |
@johnnyreilly I managed it to get importing Should I just open up a PR introducing these changes and hope a maintainer will add tests for the changes and make sure all is still working as expected? |
Do it - let's see where it goes |
Thanks @johnnyreilly |
I want to add, I've been doing a deep dive on this topic, and if all you're doing is a map of .js to .ts, you're probably going to have a bad day. Node16/NodeNext module resolution in TypeScript also specifies that you're importing CommonJS modules from ESM the way Node.js does, which is to say that if you're asking for I do not know the solution to this just yet. |
Let's hope this won't ever be an issue, then 🥲 |
@fluggo that’s exactly right. Node16/NodeNext were not designed for use in a bundler (hence the name). A mode designed for bundlers is in the works. |
I've had some success so far using an override tsconfig.json specifying Edit: Or, to be able to tell webpack what kind of resolution is going on. |
Anyone have luck webpack-5-ing with the new
.mts
extension? I'm able to output fromtsc -p .
fine, but through webpack I'm getting "Error: TypeScript emitted no output for .../index.mts".Thanks!
The text was updated successfully, but these errors were encountered: