Something went wrong. Try again.
[READ-ONLY] Mirror of https://github.com/vitest-dev/vitest. Next generation testing framework powered by Vite. vitest.dev
test testing-tools vite
Something went wrong. Try again.
TypeScript
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687import type { SourceMap } from 'magic-string'import type { Environment, Plugin, Rollup } from 'vite'import type { Expression, Positioned } from './esmWalker'import MagicString from 'magic-string'import { esmWalker } from './esmWalker'
const regexDynamicImport = /import\s*\(/
export interface DynamicImportPluginOptions { /** * @default `"__vitest_mocker__"` */ globalThisAccessor?: string filter?: (id: string, environment: Environment) => boolean}
export function dynamicImportPlugin(options: DynamicImportPluginOptions = {}): Plugin { return { name: 'vitest:browser:esm-injector', enforce: 'post', transform: { order: 'post', handler(source, id) { // TODO: test is not called for static imports if (!regexDynamicImport.test(source)) { return } if (options.filter && !options.filter(id, this.environment)) { return } return injectDynamicImport(source, id, this.parse, options) }, }, }}
export interface DynamicImportInjectorResult { code: string map: SourceMap}
export function injectDynamicImport( code: string, id: string, parse: Rollup.PluginContext['parse'], options: DynamicImportPluginOptions = {},): DynamicImportInjectorResult | undefined { if (code.includes('wrapDynamicImport')) { return }
const s = new MagicString(code)
let ast: ReturnType<Rollup.PluginContext['parse']> try { ast = parse(code) } catch (err) { console.error(`Cannot parse ${id}:\n${(err as any).message}`) return }
// 3. convert references to import bindings & import.meta references esmWalker(ast, { // TODO: make env updatable onImportMeta() { // s.update(node.start, node.end, viImportMetaKey) }, onDynamicImport(node) { const globalThisAccessor = options.globalThisAccessor || '"__vitest_mocker__"' const replaceString = `globalThis[${globalThisAccessor}].wrapDynamicImport(async () => import(` const importSubstring = code.substring(node.start, node.end) const hasIgnore = importSubstring.includes('/* @vite-ignore */') s.overwrite( node.start, (node.source as Positioned<Expression>).start, replaceString + (hasIgnore ? '/* @vite-ignore */ ' : ''), ) s.overwrite(node.end - 1, node.end, '))') }, })
return { code: s.toString(), map: s.generateMap({ hires: 'boundary', source: id }), }}