feat: support RegExp in external

This commit is contained in:
EGOIST 2021-02-23 22:04:27 +08:00
parent 29e5e240c8
commit ef8e2c6dff
3 changed files with 67 additions and 3 deletions

View File

@ -16,6 +16,7 @@ import { FSWatcher } from 'chokidar'
import glob from 'globby'
import { PrettyError } from './errors'
import { postcssPlugin } from './plugins/postcss'
import { externalPlugin } from './plugins/external'
const textDecoder = new TextDecoder('utf-8')
@ -58,7 +59,7 @@ export type Options = {
}
sourcemap?: boolean
/** Don't bundle these packages */
external?: string[]
external?: (string | RegExp)[]
/** Transform the result with `@babel/core` */
babel?: boolean
/**
@ -136,7 +137,12 @@ export async function runEsbuild(
jsxFragment: options.jsxFragment,
sourcemap: options.sourcemap,
target: options.target === 'es5' ? 'es2016' : options.target,
plugins: [postcssPlugin],
plugins: [
// esbuild's `external` option doesn't support RegExp
// So here we use a custom plugin to implement it
externalPlugin(external),
postcssPlugin,
],
define: {
...options.define,
...Object.keys(env).reduce((res, key) => {
@ -146,7 +152,6 @@ export async function runEsbuild(
}
}, {}),
},
external,
outdir:
options.legacyOutput && format !== 'cjs'
? join(outDir, format)

25
src/plugins/external.ts Normal file
View File

@ -0,0 +1,25 @@
import { Plugin } from 'esbuild'
export const externalPlugin = (patterns?: (string | RegExp)[]): Plugin => {
return {
name: `external`,
setup(build) {
if (!patterns || patterns.length === 0) return
build.onResolve({ filter: /.*/ }, (args) => {
const external = patterns.some((p) => {
if (p instanceof RegExp) {
return p.test(args.path)
}
return args.path === p
})
if (external) {
return { path: args.path, external }
}
// return without `path` to use default path resolution logic
return {}
})
},
}
}

View File

@ -363,3 +363,37 @@ test('import css', async () => {
]
`)
})
test('external', async () => {
const { output } = await run(getTestName(), {
'input.ts': `export {foo} from 'foo'
export {bar} from 'bar'
export {baz} from 'baz'
`,
'node_modules/foo/index.ts': `export const foo = 'foo'`,
'node_modules/foo/package.json': `{"name":"foo","version":"0.0.0"}`,
'node_modules/bar/index.ts': `export const bar = 'bar'`,
'node_modules/bar/package.json': `{"name":"bar","version":"0.0.0"}`,
'node_modules/baz/index.ts': `export const baz = 'baz'`,
'node_modules/baz/package.json': `{"name":"baz","version":"0.0.0"}`,
'tsup.config.ts': `
export default {
external: [/f/, 'bar']
}
`,
})
expect(output).toMatchInlineSnapshot(`
"\\"use strict\\";Object.defineProperty(exports, \\"__esModule\\", {value: true});// input.ts
var _foo = require('foo');
var _bar = require('bar');
// node_modules/baz/index.ts
var baz = \\"baz\\";
exports.bar = _bar.bar; exports.baz = baz; exports.foo = _foo.foo;
"
`)
})