ts-loader: ts-loader with Typescript 4.5 beta: "Error: TypeScript emitted no output for .../index.mts"
Anyone have luck webpack-5-ing with the new .mts
extension? I’m able to output from tsc -p .
fine, but through webpack I’m getting “Error: TypeScript emitted no output for …/index.mts”.
Thanks!
resolve: {
// Add `.ts` and `.tsx` as a resolvable extension.
extensions: [".mts", ".ts", ".tsx", ".js"]
},
module: {
rules: [
{
test: /(\.mts$)|(\.tsx?$)/,
use: [
{
loader: 'ts-loader',
options: {
//transpileOnly: true
compilerOptions: {
noEmit: false
}
}
}
]
}
]
}
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Reactions: 1
- Comments: 47 (41 by maintainers)
@alexander-akait I put up a super simple repro showing that
.js
resolution to.ts
doesn’t work, but haven’t had time to start seeing how ts-loader could be involved here. Honestly my expectation was that this would not work; I’m not super familiar with how ts-loader contributes to Webpack’s resolution, but my impression was that this would be a Webpack-level thing, not a ts-loader thing. https://github.com/andrewbranch/nodenext-webpack@alexander-akait the issue is that in the new TypeScript module resolution modes, users must write
import "./foo.js"
even though on disk, the colocated file is./foo.ts
. This is because TypeScript expects TS code to be compiled to JS with these import paths unchanged, that way the output JS will resolve correctly at runtime. But this breaks the expectations of bundlers like Webpack, which does module resolution before a 1:1 TS→JS compilation happens. So the correct specifier for Webpack would beimport "./foo.ts"
but TypeScript doesn’t allow that. The correct specifier for TypeScript isimport "./foo.js"
but Webpack can’t resolve that by default.I just want to cross-reference https://github.com/microsoft/TypeScript/issues/37582 which is where I redirected https://github.com/microsoft/TypeScript/issues/46344 to. I would love to hear feedback there from Webpack users about
.mts
/.cts
files?node12
/nodenext
module resolution features like export maps?resolve.conditionNames
and why?@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 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
import foo from './foo.cjs'
in an ESM project, Node.js always gives you the wholemodule.exports
object and never the default export. As far as I can tell, Webpack’s output still operates by the old rules with__esModule
interop in place. Please do correct me if I’m wrong.I do not know the solution to this just yet.
this should be solved by https://github.com/webpack/enhanced-resolve/pull/351
webpack will have a new option for resolve
Good suggestions, thank you @alexander-akait.
@johnnyreilly Yes, no breaking change, now it is just broken and do not work, put
console.log
and incatch
and you will see error alwaysThanks, I will look at this
@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
I’ll give it a try this afternoon.
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
@djcsdy - feels like this might be interesting to you given your work on https://github.com/softwareventures/resolve-typescript-plugin
Yes, I believe it is because of the inclusion of the eventual extension.
import { foo } from "./misc"
works as alwaysimport { foo } from "./misc.ts"
is wrong and givesTS2691: An import path cannot end with a '.ts' extension. Consider importing './misc.js' instead.
but
import { foo } from "./misc.js";
works withtsc
but fails only in webpacking withModule not found: Error: Can't resolve './misc.js' in 'C:\example\src' resolve './misc.js'
Does ts-loader need to correct these paths for resolution? Or what?
Haven’t tried this at all - am interested with how this pans out!