Skip to content
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

feat(minor): support node: import in older node versions #460

Merged
merged 1 commit into from Nov 20, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 0 additions & 4 deletions src/esbuild/external.ts
Expand Up @@ -6,18 +6,14 @@ const NON_NODE_MODULE_RE = /^[^.\/]|^\.[^.\/]|^\.\.[^\/]/
export const externalPlugin = ({
patterns,
skipNodeModulesBundle,
disabled,
}: {
patterns?: (string | RegExp)[]
skipNodeModulesBundle?: boolean
disabled?: boolean
}): Plugin => {
return {
name: `external`,

setup(build) {
if (disabled) return

if (skipNodeModulesBundle) {
build.onResolve({ filter: NON_NODE_MODULE_RE }, (args) => ({
path: args.path,
Expand Down
8 changes: 4 additions & 4 deletions src/esbuild/index.ts
Expand Up @@ -12,6 +12,7 @@ import {
import { NormalizedOptions, Format } from '..'
import { getDeps, loadPkg } from '../load'
import { log } from '../log'
import { nodeProtocolPlugin } from './node-protocol'
import { externalPlugin } from './external'
import { postcssPlugin } from './postcss'
import { sveltePlugin } from './svelte'
Expand Down Expand Up @@ -94,6 +95,7 @@ export async function runEsbuild(
? ['module', 'main']
: ['browser', 'module', 'main'],
plugins: [
...(format === 'cjs' ? [nodeProtocolPlugin()] : []),
{
name: 'modify-options',
setup(build) {
Expand All @@ -104,12 +106,10 @@ export async function runEsbuild(
},
// esbuild's `external` option doesn't support RegExp
// So here we use a custom plugin to implement it
externalPlugin({
// everything should be bundled for iife format
disabled: format === 'iife',
...(format !== 'iife' ? [externalPlugin({
patterns: external,
skipNodeModulesBundle: options.skipNodeModulesBundle,
}),
})] : []),
postcssPlugin({ css }),
sveltePlugin({ css }),
...(options.esbuildPlugins || []),
Expand Down
21 changes: 21 additions & 0 deletions src/esbuild/node-protocol.ts
@@ -0,0 +1,21 @@
import { Plugin } from 'esbuild'

/**
* The node: protocol was added to require in Node v14.18.0
* https://nodejs.org/api/esm.html#node-imports
*/
export const nodeProtocolPlugin = (): Plugin => {
const nodeProtocol = 'node:'

return {
name: 'node-protocol-plugin',
setup({ onResolve }) {
onResolve({
filter: /^node:/,
}, ({ path }) => ({
path: path.slice(nodeProtocol.length),
external: true
}))
}
}
}
31 changes: 31 additions & 0 deletions test/index.test.ts
Expand Up @@ -556,6 +556,37 @@ test('import css in --dts', async () => {
`)
})

test('node protocol', async () => {
const { output } = await run(getTestName(), {
'input.ts': `import fs from 'node:fs'; console.log(fs)`,
})
expect(output).toMatchInlineSnapshot(`
"var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __markAsModule = (target) => __defProp(target, \\"__esModule\\", { value: true });
var __reExport = (target, module2, desc) => {
if (module2 && typeof module2 === \\"object\\" || typeof module2 === \\"function\\") {
for (let key of __getOwnPropNames(module2))
if (!__hasOwnProp.call(target, key) && key !== \\"default\\")
__defProp(target, key, { get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable });
}
return target;
};
var __toModule = (module2) => {
return __reExport(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, \\"default\\", module2 && module2.__esModule && \\"default\\" in module2 ? { get: () => module2.default, enumerable: true } : { value: module2, enumerable: true })), module2);
};

// input.ts
var import_node_fs = __toModule(require(\\"fs\\"));
console.log(import_node_fs.default);
"
`)
})

test('external', async () => {
const { output } = await run(getTestName(), {
'input.ts': `export {foo} from 'foo'
Expand Down