-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
Support --out-extension
when without bundle
#2600
Comments
Hi, not sure if my issue is the same, but it seems related. I have typescript files (ts/tsx) and would like to publish them as cjs&esm and keep it treeshakeable (so no bundle). esbuild ./src/* --outdir=esm --out-extension:.js=.mjs It seems that out-extension is outputting the correct extensions, but it breaks the imports as these are explicit. From esbuild docs:
I think it would make more sense that if out-extension ends with .mjs, it should rewrite the import/export statements to valid imports (ending in .mjs). |
I'm not convinced doing something like this is a good idea. By design, the transform API doesn't access the file system and doesn't run import resolution, so it doesn't know where a given import will resolve. Blindly changing imports like Edit: By far the simplest solution is to just write |
If I write Note to self, conditions for adding .mjs:
Not sure if package imports have impact. Today I'm using the script below to add const { readFile, writeFile } = require('fs')
for (const filename of process.argv.slice(2)) {
readFile(filename, 'utf-8', function (err, contents) {
if (err) return console.log(err)
contents = contents
.replaceAll(/(import[{}\sa-z,A-Z0-9]+from "\.\/[^"]+)"/gm, '$1.mjs"')
.replaceAll(/(export[{}\sa-z,A-Z0-9*]+from "\.\/[^"]+)"/gm, '$1.mjs"')
.replaceAll('format from "date-fns/format', '{ format } from "date-fns')
writeFile(filename, contents, 'utf-8', err => err && console.log(err))
})
} |
The way to do this is to use the build API with a plugin that customizes the import paths to match your requirements. Documentation for the relevant plugin API is here: https://esbuild.github.io/plugins/#on-resolve. I'm closing this issue because I don't believe this behavior should be built in to esbuild, as it's error-prone and likely needs to be customized for each use case. |
I'm running into this same problem. I tried implementing the renaming from Am I misunderstanding something here? Here's the plugin I tried with const jsToMjs: Plugin = {
name: 'js-to-mjs',
setup(build) {
// Find all relative imports (starting with ".") that ends with ".js" and
// replace the file extension with ".mjs"
build.onResolve({ filter: /^..+\.js$/ }, (args) => {
return {
path: path.join(args.resolveDir, args.path.slice(0, -3) + '.mjs'),
}
})
},
} But, as I said, the callback is never called, because all the files are just (To debug I changed to regex to |
Using the Build API caused a lot of problems for us when using ESM in node.
We're running
npx esbuild `find server/src \\( -name '*.ts' -o -name '*.mts' \\)` --platform=node --format=esm --outdir=server/dist
as we've learned in #263 .
The problem is the output files are in
.js
and the emitted code contains imports to.mjs
files.Here is our tsconfig
This would've been solved if
--out-extension
was supported by the transform API.The text was updated successfully, but these errors were encountered: