Skip to content

Commit

Permalink
fix evanw#3821: allow node: prefix with es* targets
Browse files Browse the repository at this point in the history
  • Loading branch information
evanw committed Jul 3, 2024
1 parent 9d50680 commit e3f4e2d
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 3 deletions.
20 changes: 20 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,25 @@
# Changelog

## Unreleased

* Allow using the `node:` import prefix with `es*` targets ([#3821](https://github.com/evanw/esbuild/issues/3821))

The [`node:` prefix on imports](https://nodejs.org/api/esm.html#node-imports) is an alternate way to import built-in node modules. For example, `import fs from "fs"` can also be written `import fs from "node:fs"`. This only works with certain newer versions of node, so esbuild removes it when you target older versions of node such as with `--target=node14` so that your code still works. With the way esbuild's platform-specific feature compatibility table works, this was added by saying that only newer versions of node support this feature. However, that means that a target such as `--target=node18,es2022` removes the `node:` prefix because none of the `es*` targets are known to support this feature. This release adds the support for the `node:` flag to esbuild's internal compatibility table for `es*` to allow you to use compound targets like this:

```js
// Original code
import fs from 'node:fs'
fs.open

// Old output (with --bundle --format=esm --platform=node --target=node18,es2022)
import fs from "node";
fs.open;

// New output (with --bundle --format=esm --platform=node --target=node18,es2022)
import fs from "node:fs";
fs.open;
```

## 0.23.0

**_This release deliberately contains backwards-incompatible changes._** To avoid automatically picking up releases like this, you should either be pinning the exact version of `esbuild` in your `package.json` file (recommended) or be using a version range syntax that only accepts patch upgrades such as `^0.22.0` or `~0.22.0`. See npm's documentation about [semver](https://docs.npmjs.com/cli/v6/using-npm/semver/) for more information.
Expand Down
2 changes: 2 additions & 0 deletions compat-table/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,8 @@ import('./kangax').then(kangax => {
'15': { force: false },
'16': { force: true },
}
js.NodeColonPrefixImport.ES = { 0: { force: true } }
js.NodeColonPrefixRequire.ES = { 0: { force: true } }

// Arbitrary Module Namespace Names
{
Expand Down
2 changes: 2 additions & 0 deletions internal/compat/js_table.go
Original file line number Diff line number Diff line change
Expand Up @@ -651,9 +651,11 @@ var jsTable = map[JSFeature]map[Engine][]versionRange{
Safari: {{start: v{10, 0, 0}}},
},
NodeColonPrefixImport: {
ES: {{start: v{0, 0, 0}}},
Node: {{start: v{12, 20, 0}, end: v{13, 0, 0}}, {start: v{14, 13, 1}}},
},
NodeColonPrefixRequire: {
ES: {{start: v{0, 0, 0}}},
Node: {{start: v{14, 18, 0}, end: v{15, 0, 0}}, {start: v{16, 0, 0}}},
},
NullishCoalescing: {
Expand Down
9 changes: 6 additions & 3 deletions scripts/js-api-tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -3065,7 +3065,7 @@ import "after/alias";
stdin: { contents: `import fs from 'node:fs'; import('node:fs'); fs()` },
bundle: true,
platform: 'node',
target,
target: target.split(','),
format: 'esm',
write: false,
})
Expand All @@ -3079,6 +3079,7 @@ import "after/alias";
assert.strictEqual(await tryTargetESM('node12.99'), `// <stdin>\nimport fs from "node:fs";\nimport("node:fs");\nfs();\n`)
assert.strictEqual(await tryTargetESM('node12.20'), `// <stdin>\nimport fs from "node:fs";\nimport("node:fs");\nfs();\n`)
assert.strictEqual(await tryTargetESM('node12.19'), `// <stdin>\nimport fs from "fs";\nPromise.resolve().then(() => __toESM(__require("fs")));\nfs();\n`)
assert.strictEqual(await tryTargetESM('node18,es6'), `// <stdin>\nimport fs from "node:fs";\nimport("node:fs");\nfs();\n`)
},

async nodeColonPrefixRequire({ esbuild }) {
Expand All @@ -3087,7 +3088,7 @@ import "after/alias";
stdin: { contents: `require('node:fs'); require.resolve('node:fs')` },
bundle: true,
platform: 'node',
target,
target: target.split(','),
format: 'cjs',
write: false,
})
Expand All @@ -3101,6 +3102,7 @@ import "after/alias";
assert.strictEqual(await tryTargetESM('node14.99'), `// <stdin>\nrequire("node:fs");\nrequire.resolve("node:fs");\n`)
assert.strictEqual(await tryTargetESM('node14.18'), `// <stdin>\nrequire("node:fs");\nrequire.resolve("node:fs");\n`)
assert.strictEqual(await tryTargetESM('node14.17'), `// <stdin>\nrequire("fs");\nrequire.resolve("fs");\n`)
assert.strictEqual(await tryTargetESM('node18,es6'), `// <stdin>\nrequire("node:fs");\nrequire.resolve("node:fs");\n`)
},

async nodeColonPrefixImportTurnedIntoRequire({ esbuild }) {
Expand All @@ -3109,7 +3111,7 @@ import "after/alias";
stdin: { contents: `import fs from 'node:fs'; import('node:fs'); fs()` },
bundle: true,
platform: 'node',
target,
target: target.split(','),
format: 'cjs',
write: false,
})
Expand All @@ -3123,6 +3125,7 @@ import "after/alias";
assert.strictEqual(await tryTargetESM('node14.99'), `// <stdin>\nvar import_node_fs = __toESM(require("node:fs"));\nimport("node:fs");\n(0, import_node_fs.default)();\n`)
assert.strictEqual(await tryTargetESM('node14.18'), `// <stdin>\nvar import_node_fs = __toESM(require("node:fs"));\nimport("node:fs");\n(0, import_node_fs.default)();\n`)
assert.strictEqual(await tryTargetESM('node14.17'), `// <stdin>\nvar import_node_fs = __toESM(require("fs"));\nimport("fs");\n(0, import_node_fs.default)();\n`)
assert.strictEqual(await tryTargetESM('node18,es6'), `// <stdin>\nvar import_node_fs = __toESM(require("node:fs"));\nimport("node:fs");\n(0, import_node_fs.default)();\n`)
},

async zipFile({ esbuild, testDir }) {
Expand Down

0 comments on commit e3f4e2d

Please sign in to comment.