parcel: Importing typescript configured for ESM not supported by Parcel
🐛 bug report
- Because Typescript developers were super nice, they decided that if you need the generated code to be valid ESM,
import "foo"
should be written asimport "foo.js"
even if we are importingfoo.ts
. - Typescript resolution algorithm ignores the extension and imports the
.ts
file if it’s present. Otherwise it tries to import the.js
file. - Parcel’s resolution doesn’t follow this convention. If there is no
foo.js
file but there isfoo.ts
, Parcel errors out sayingfoo.js
not found.
More info:
🎛 Configuration (.babelrc, package.json, cli command)
.parcelrc
: None- Babel: None
package.json
:{ .., "type": "module", .. }
🤔 Expected Behavior
In a TS file, import "foo.js"
should try to import foo.ts
. If not present, try to import foo.js
.
😯 Current Behavior
import "foo.js"
fails if foo.js
is not present, regardless of the presence of foo.ts
@parcel/core: Failed to resolve '../lib/main.js' from './demo/index.ts'
🔦 Context
Here’s my file structure:
lib/
main.ts
demo/
index.html
index.ts
I’m trying to import main.ts
in index.ts
.
lib
is configured to compile to an ESM package, that can work on both client and server side.
So the imports inside main.ts
must have .js
extension.
Otherwise, typescript will emit it as import "foo"
, and the import will fail at runtime because ESM specs require an extension.
🧪 Minimal Repro
https://github.com/itsfarseen/repro-parcel-ts
🌍 Your Environment
Software | Version(s) |
---|---|
Parcel | 2.3.2 |
Node | v14.19.0 |
Yarn | 1.22.17 |
Operating System | Arch Linux |
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Reactions: 9
- Comments: 19 (2 by maintainers)
I moved on to esbuild. Esbuild just works with esm and is really fast.
I’ve made a tiny simple Vanilla (no dependencies) browser app in TypeScript that already runs fine in the browser after compiling TypeScript (to ESM modules). I use “.js” extensions for all TS module imports according to TypeScript documentation.
I wanted to add a bundler for minification etc, so I decided to try out Parcel for the first time. When I found that Parcel is not capable of bundling ESM compliant TypeScript source code, I gave up.
@b8kkyn parcel-resolver-typescript-esm did not work according to documentation (with the current version of parcel). For Webpack I use resolve-typescript-plugin which works fine.
I find it a bit strange that native support for ESM compliant TypeScript code is not given priority for bundlers.
I have developed a plugin which allows you to use .jsx / .js extensions inside a TypeScript module file. It should also work with all other Parcel specific things (like tilde, absolute chars etc):
parcel-resolver-typescript-esm
A resolution is much needed here. This issue is currently blocking us from migrating our Open Source repos to esm.