From 7434b0f7037e61b5166f5ba230f7214f463880e2 Mon Sep 17 00:00:00 2001 From: Lukas Taegert-Atkinson Date: Fri, 14 Jan 2022 15:33:55 +0100 Subject: [PATCH] fix(commonjs): proxy all entries to not break legacy polyfill plugins (#1038) --- packages/commonjs/package.json | 2 +- packages/commonjs/src/generate-imports.js | 13 +- packages/commonjs/src/helpers.js | 3 +- packages/commonjs/src/index.js | 69 ++++--- packages/commonjs/src/proxies.js | 36 ++-- packages/commonjs/src/resolve-id.js | 35 ++-- .../commonjs/src/resolve-require-sources.js | 129 ++++++++----- packages/commonjs/src/transform-commonjs.js | 22 +-- .../module-side-effects-late-entry/_config.js | 22 +++ .../module-side-effects-late-entry/foo.js | 2 + .../module-side-effects-late-entry/main.js | 3 + .../function/plugin-isentry/_config.js | 36 ++++ .../fixtures/function/plugin-isentry/dep.js | 2 + .../fixtures/function/plugin-isentry/main.js | 2 + .../fixtures/function/plugin-isentry/other.js | 1 + .../function/preserve-modules/_config.js | 14 ++ .../function/preserve-modules/main.js | 4 + packages/commonjs/test/form.js | 7 +- .../commonjs/test/snapshots/function.js.md | 139 +++++++++++++- .../commonjs/test/snapshots/function.js.snap | Bin 21233 -> 21721 bytes packages/commonjs/test/snapshots/test.js.md | 170 +++++++++++++++++ packages/commonjs/test/snapshots/test.js.snap | Bin 938 -> 1346 bytes packages/commonjs/test/test.js | 174 ++++++++++++++---- 23 files changed, 718 insertions(+), 167 deletions(-) create mode 100644 packages/commonjs/test/fixtures/function/module-side-effects-late-entry/_config.js create mode 100644 packages/commonjs/test/fixtures/function/module-side-effects-late-entry/foo.js create mode 100644 packages/commonjs/test/fixtures/function/module-side-effects-late-entry/main.js create mode 100644 packages/commonjs/test/fixtures/function/plugin-isentry/_config.js create mode 100644 packages/commonjs/test/fixtures/function/plugin-isentry/dep.js create mode 100644 packages/commonjs/test/fixtures/function/plugin-isentry/main.js create mode 100644 packages/commonjs/test/fixtures/function/plugin-isentry/other.js create mode 100644 packages/commonjs/test/fixtures/function/preserve-modules/_config.js create mode 100644 packages/commonjs/test/fixtures/function/preserve-modules/main.js diff --git a/packages/commonjs/package.json b/packages/commonjs/package.json index 6f3bb2e2a..ff706eeb6 100644 --- a/packages/commonjs/package.json +++ b/packages/commonjs/package.json @@ -52,7 +52,7 @@ "require" ], "peerDependencies": { - "rollup": "^2.61.1" + "rollup": "^2.67.0" }, "dependencies": { "@rollup/pluginutils": "^3.1.0", diff --git a/packages/commonjs/src/generate-imports.js b/packages/commonjs/src/generate-imports.js index 9c3aaa02e..a9cc478fe 100644 --- a/packages/commonjs/src/generate-imports.js +++ b/packages/commonjs/src/generate-imports.js @@ -90,11 +90,12 @@ export function getRequireHandlers() { exportsName, id, exportMode, - resolveRequireSourcesAndGetMeta, + resolveRequireSourcesAndUpdateMeta, needsRequireWrapper, isEsModule, isDynamicRequireModulesEnabled, - getIgnoreTryCatchRequireStatementMode + getIgnoreTryCatchRequireStatementMode, + commonjsMeta ) { const imports = []; imports.push(`import * as ${helpersName} from "${HELPERS_ID}";`); @@ -117,9 +118,10 @@ export function getRequireHandlers() { ); } const requiresBySource = collectSources(requireExpressions); - const { requireTargets, usesRequireWrapper } = await resolveRequireSourcesAndGetMeta( + const requireTargets = await resolveRequireSourcesAndUpdateMeta( id, needsRequireWrapper ? IS_WRAPPED_COMMONJS : !isEsModule, + commonjsMeta, Object.keys(requiresBySource).map((source) => { return { source, @@ -134,10 +136,7 @@ export function getRequireHandlers() { getIgnoreTryCatchRequireStatementMode, magicString ); - return { - importBlock: imports.length ? `${imports.join('\n')}\n\n` : '', - usesRequireWrapper - }; + return imports.length ? `${imports.join('\n')}\n\n` : ''; } return { diff --git a/packages/commonjs/src/helpers.js b/packages/commonjs/src/helpers.js index d2906ecf5..94d770d38 100644 --- a/packages/commonjs/src/helpers.js +++ b/packages/commonjs/src/helpers.js @@ -7,7 +7,8 @@ export const WRAPPED_SUFFIX = '?commonjs-wrapped'; export const EXTERNAL_SUFFIX = '?commonjs-external'; export const EXPORTS_SUFFIX = '?commonjs-exports'; export const MODULE_SUFFIX = '?commonjs-module'; -export const ES_IMPORT_SUFFIX = '?es-import'; +export const ENTRY_SUFFIX = '?commonjs-entry'; +export const ES_IMPORT_SUFFIX = '?commonjs-es-import'; export const DYNAMIC_MODULES_ID = '\0commonjs-dynamic-modules'; export const HELPERS_ID = '\0commonjsHelpers.js'; diff --git a/packages/commonjs/src/index.js b/packages/commonjs/src/index.js index 639f9e92d..b53fa7fd4 100644 --- a/packages/commonjs/src/index.js +++ b/packages/commonjs/src/index.js @@ -9,6 +9,7 @@ import { getDynamicModuleRegistry, getDynamicRequireModules } from './dynamic-mo import { DYNAMIC_MODULES_ID, + ENTRY_SUFFIX, ES_IMPORT_SUFFIX, EXPORTS_SUFFIX, EXTERNAL_SUFFIX, @@ -20,13 +21,20 @@ import { unwrapId } from './helpers'; import { hasCjsKeywords } from './parse'; -import { getEsImportProxy, getStaticRequireProxy, getUnknownRequireProxy } from './proxies'; +import { + getEntryProxy, + getEsImportProxy, + getStaticRequireProxy, + getUnknownRequireProxy +} from './proxies'; import getResolveId from './resolve-id'; -import { getResolveRequireSourcesAndGetMeta } from './resolve-require-sources'; +import { getRequireResolver } from './resolve-require-sources'; import validateVersion from './rollup-version'; import transformCommonjs from './transform-commonjs'; import { getName, getStrictRequiresFilter, normalizePathSlashes } from './utils'; +const PLUGIN_NAME = 'commonjs'; + export default function commonjs(options = {}) { const { ignoreGlobal, @@ -58,11 +66,6 @@ export default function commonjs(options = {}) { : () => typeof defaultIsModuleExportsOption === 'boolean' ? defaultIsModuleExportsOption : 'auto'; - const { - resolveRequireSourcesAndGetMeta, - getWrappedIds, - isRequiredId - } = getResolveRequireSourcesAndGetMeta(extensions, detectCyclesAndConditional); const dynamicRequireRoot = typeof options.dynamicRequireRoot === 'string' ? resolve(options.dynamicRequireRoot) @@ -73,9 +76,6 @@ export default function commonjs(options = {}) { ); const isDynamicRequireModulesEnabled = dynamicRequireModules.size > 0; - const esModulesWithDefaultExport = new Set(); - const esModulesWithNamedExports = new Set(); - const ignoreRequire = typeof options.ignore === 'function' ? options.ignore @@ -103,25 +103,31 @@ export default function commonjs(options = {}) { const sourceMap = options.sourceMap !== false; + // Initialized in buildStart + let requireResolver; + function transformAndCheckExports(code, id) { const { isEsModule, hasDefaultExport, hasNamedExports, ast } = analyzeTopLevelStatements( this.parse, code, id ); + + const commonjsMeta = this.getModuleInfo(id).meta.commonjs || {}; if (hasDefaultExport) { - esModulesWithDefaultExport.add(id); + commonjsMeta.hasDefaultExport = true; } if (hasNamedExports) { - esModulesWithNamedExports.add(id); + commonjsMeta.hasNamedExports = true; } if ( !dynamicRequireModules.has(normalizePathSlashes(id)) && - (!(hasCjsKeywords(code, ignoreGlobal) || isRequiredId(id)) || + (!(hasCjsKeywords(code, ignoreGlobal) || requireResolver.isRequiredId(id)) || (isEsModule && !options.transformMixedEsModules)) ) { - return { meta: { commonjs: { isCommonJS: false } } }; + commonjsMeta.isCommonJS = false; + return { meta: { commonjs: commonjsMeta } }; } const needsRequireWrapper = @@ -160,14 +166,15 @@ export default function commonjs(options = {}) { ast, getDefaultIsModuleExports(id), needsRequireWrapper, - resolveRequireSourcesAndGetMeta(this), - isRequiredId(id), - checkDynamicRequire + requireResolver.resolveRequireSourcesAndUpdateMeta(this), + requireResolver.isRequiredId(id), + checkDynamicRequire, + commonjsMeta ); } return { - name: 'commonjs', + name: PLUGIN_NAME, version, @@ -175,7 +182,7 @@ export default function commonjs(options = {}) { // We inject the resolver in the beginning so that "catch-all-resolver" like node-resolver // do not prevent our plugin from resolving entry points ot proxies. const plugins = Array.isArray(rawOptions.plugins) - ? rawOptions.plugins + ? [...rawOptions.plugins] : rawOptions.plugins ? [rawOptions.plugins] : []; @@ -197,11 +204,12 @@ export default function commonjs(options = {}) { 'The namedExports option from "@rollup/plugin-commonjs" is deprecated. Named exports are now handled automatically.' ); } + requireResolver = getRequireResolver(extensions, detectCyclesAndConditional); }, buildEnd() { if (options.strictRequires === 'debug') { - const wrappedIds = getWrappedIds(); + const wrappedIds = requireResolver.getWrappedIds(); if (wrappedIds.length) { this.warn({ code: 'WRAPPED_IDS', @@ -250,6 +258,15 @@ export default function commonjs(options = {}) { ); } + // entry suffix is just appended to not mess up relative external resolution + if (id.endsWith(ENTRY_SUFFIX)) { + return getEntryProxy( + id.slice(0, -ENTRY_SUFFIX.length), + defaultIsModuleExports, + this.getModuleInfo + ); + } + if (isWrappedId(id, ES_IMPORT_SUFFIX)) { return getEsImportProxy(unwrapId(id, ES_IMPORT_SUFFIX), defaultIsModuleExports); } @@ -265,18 +282,16 @@ export default function commonjs(options = {}) { if (isWrappedId(id, PROXY_SUFFIX)) { const actualId = unwrapId(id, PROXY_SUFFIX); - return getStaticRequireProxy( - actualId, - getRequireReturnsDefault(actualId), - esModulesWithDefaultExport, - esModulesWithNamedExports, - this.load - ); + return getStaticRequireProxy(actualId, getRequireReturnsDefault(actualId), this.load); } return null; }, + shouldTransformCachedModule(...args) { + return requireResolver.shouldTransformCachedModule.call(this, ...args); + }, + transform(code, id) { const extName = extname(id); if (extName !== '.cjs' && (!filter(id) || !extensions.includes(extName))) { diff --git a/packages/commonjs/src/proxies.js b/packages/commonjs/src/proxies.js index 2935612ac..10e9d0894 100644 --- a/packages/commonjs/src/proxies.js +++ b/packages/commonjs/src/proxies.js @@ -1,4 +1,4 @@ -import { HELPERS_ID } from './helpers'; +import { HELPERS_ID, IS_WRAPPED_COMMONJS } from './helpers'; import { capitalize, getName } from './utils'; export function getUnknownRequireProxy(id, requireReturnsDefault) { @@ -17,21 +17,15 @@ export function getUnknownRequireProxy(id, requireReturnsDefault) { return `import * as ${name} from ${JSON.stringify(id)}; ${exported}`; } -export async function getStaticRequireProxy( - id, - requireReturnsDefault, - esModulesWithDefaultExport, - esModulesWithNamedExports, - loadModule -) { +export async function getStaticRequireProxy(id, requireReturnsDefault, loadModule) { const name = getName(id); const { meta: { commonjs: commonjsMeta } } = await loadModule({ id }); - if (commonjsMeta && commonjsMeta.isCommonJS) { - return `export { __moduleExports as default } from ${JSON.stringify(id)};`; - } else if (!commonjsMeta) { + if (!commonjsMeta) { return getUnknownRequireProxy(id, requireReturnsDefault); + } else if (commonjsMeta.isCommonJS) { + return `export { __moduleExports as default } from ${JSON.stringify(id)};`; } else if (!requireReturnsDefault) { return `import { getAugmentedNamespace } from "${HELPERS_ID}"; import * as ${name} from ${JSON.stringify( id @@ -39,14 +33,30 @@ export async function getStaticRequireProxy( } else if ( requireReturnsDefault !== true && (requireReturnsDefault === 'namespace' || - !esModulesWithDefaultExport.has(id) || - (requireReturnsDefault === 'auto' && esModulesWithNamedExports.has(id))) + !commonjsMeta.hasDefaultExport || + (requireReturnsDefault === 'auto' && commonjsMeta.hasNamedExports)) ) { return `import * as ${name} from ${JSON.stringify(id)}; export default ${name};`; } return `export { default } from ${JSON.stringify(id)};`; } +export function getEntryProxy(id, defaultIsModuleExports, getModuleInfo) { + const { + meta: { commonjs: commonjsMeta }, + hasDefaultExport + } = getModuleInfo(id); + if (!commonjsMeta || commonjsMeta.isCommonJS !== IS_WRAPPED_COMMONJS) { + const stringifiedId = JSON.stringify(id); + let code = `export * from ${stringifiedId};`; + if (hasDefaultExport) { + code += `export { default } from ${stringifiedId};`; + } + return code; + } + return getEsImportProxy(id, defaultIsModuleExports); +} + export function getEsImportProxy(id, defaultIsModuleExports) { const name = getName(id); const exportsName = `${name}Exports`; diff --git a/packages/commonjs/src/resolve-id.js b/packages/commonjs/src/resolve-id.js index 74d209e5b..1f6c874a3 100644 --- a/packages/commonjs/src/resolve-id.js +++ b/packages/commonjs/src/resolve-id.js @@ -5,6 +5,7 @@ import { dirname, resolve, sep } from 'path'; import { DYNAMIC_MODULES_ID, + ENTRY_SUFFIX, ES_IMPORT_SUFFIX, EXPORTS_SUFFIX, EXTERNAL_SUFFIX, @@ -51,11 +52,8 @@ export function resolveExtensions(importee, importer, extensions) { export default function getResolveId(extensions) { return async function resolveId(importee, importer, resolveOptions) { // We assume that all requires are pre-resolved - if ( - resolveOptions.custom && - resolveOptions.custom['node-resolve'] && - resolveOptions.custom['node-resolve'].isRequire - ) { + const customOptions = resolveOptions.custom; + if (customOptions && customOptions['node-resolve'] && customOptions['node-resolve'].isRequire) { return null; } if (isWrappedId(importee, WRAPPED_SUFFIX)) { @@ -63,6 +61,7 @@ export default function getResolveId(extensions) { } if ( + importee.endsWith(ENTRY_SUFFIX) || isWrappedId(importee, MODULE_SUFFIX) || isWrappedId(importee, EXPORTS_SUFFIX) || isWrappedId(importee, PROXY_SUFFIX) || @@ -79,7 +78,8 @@ export default function getResolveId(extensions) { importer === DYNAMIC_MODULES_ID || // Proxies are only importing resolved ids, no need to resolve again isWrappedId(importer, PROXY_SUFFIX) || - isWrappedId(importer, ES_IMPORT_SUFFIX) + isWrappedId(importer, ES_IMPORT_SUFFIX) || + importer.endsWith(ENTRY_SUFFIX) ) { return importee; } @@ -99,22 +99,27 @@ export default function getResolveId(extensions) { // If this is an entry point or ESM import, we need to figure out if the importee is wrapped and // if that is the case, we need to add a proxy. - const customOptions = resolveOptions.custom; - - // If this is a require, we do not need a proxy - if (customOptions && customOptions['node-resolve'] && customOptions['node-resolve'].isRequire) { - return null; - } - const resolved = (await this.resolve(importee, importer, Object.assign({ skipSelf: true }, resolveOptions))) || resolveExtensions(importee, importer, extensions); - if (!resolved || resolved.external) { + // Make sure that even if other plugins resolve again, we ignore our own proxies + if ( + !resolved || + resolved.external || + resolved.id.endsWith(ENTRY_SUFFIX) || + isWrappedId(resolved.id, ES_IMPORT_SUFFIX) + ) { return resolved; } + const moduleInfo = await this.load(resolved); + if (resolveOptions.isEntry) { + moduleInfo.moduleSideEffects = true; + // We must not precede entry proxies with a `\0` as that will mess up relative external resolution + return resolved.id + ENTRY_SUFFIX; + } const { meta: { commonjs: commonjsMeta } - } = await this.load(resolved); + } = moduleInfo; if (commonjsMeta && commonjsMeta.isCommonJS === IS_WRAPPED_COMMONJS) { return wrapId(resolved.id, ES_IMPORT_SUFFIX); } diff --git a/packages/commonjs/src/resolve-require-sources.js b/packages/commonjs/src/resolve-require-sources.js index 76fae132e..49dc0dc2a 100644 --- a/packages/commonjs/src/resolve-require-sources.js +++ b/packages/commonjs/src/resolve-require-sources.js @@ -7,7 +7,7 @@ import { } from './helpers'; import { resolveExtensions } from './resolve-id'; -export function getResolveRequireSourcesAndGetMeta(extensions, detectCyclesAndConditional) { +export function getRequireResolver(extensions, detectCyclesAndConditional) { const knownCjsModuleTypes = Object.create(null); const requiredIds = Object.create(null); const unconditionallyRequiredIds = Object.create(null); @@ -31,11 +31,7 @@ export function getResolveRequireSourcesAndGetMeta(extensions, detectCyclesAndCo const getTypeForFullyAnalyzedModule = (id) => { const knownType = knownCjsModuleTypes[id]; - if ( - knownType === IS_WRAPPED_COMMONJS || - !detectCyclesAndConditional || - fullyAnalyzedModules[id] - ) { + if (knownType !== true || !detectCyclesAndConditional || fullyAnalyzedModules[id]) { return knownType; } fullyAnalyzedModules[id] = true; @@ -45,26 +41,80 @@ export function getResolveRequireSourcesAndGetMeta(extensions, detectCyclesAndCo return knownType; }; + const setInitialParentType = (id, initialCommonJSType) => { + // It is possible a transformed module is already fully analyzed when using + // the cache and one dependency introduces a new cycle. Then transform is + // run for a fully analzyed module again. Fully analyzed modules may never + // change their type as importers already trust their type. + knownCjsModuleTypes[id] = fullyAnalyzedModules[id] + ? knownCjsModuleTypes[id] + : initialCommonJSType; + if ( + detectCyclesAndConditional && + knownCjsModuleTypes[id] === true && + requiredIds[id] && + !unconditionallyRequiredIds[id] + ) { + knownCjsModuleTypes[id] = IS_WRAPPED_COMMONJS; + } + }; + + const setTypesForRequiredModules = async (parentId, resolved, isConditional, loadModule) => { + const childId = resolved.id; + requiredIds[childId] = true; + if (!(isConditional || knownCjsModuleTypes[parentId] === IS_WRAPPED_COMMONJS)) { + unconditionallyRequiredIds[childId] = true; + } + + getDependencies(parentId).add(childId); + if (!isCyclic(childId)) { + // This makes sure the current transform handler waits for all direct dependencies to be + // loaded and transformed and therefore for all transitive CommonJS dependencies to be + // loaded as well so that all cycles have been found and knownCjsModuleTypes is reliable. + await loadModule(resolved); + } + }; + return { getWrappedIds: () => Object.keys(knownCjsModuleTypes).filter( (id) => knownCjsModuleTypes[id] === IS_WRAPPED_COMMONJS ), isRequiredId: (id) => requiredIds[id], - resolveRequireSourcesAndGetMeta: (rollupContext) => async ( + async shouldTransformCachedModule({ id: parentId, meta: { commonjs: parentMeta } }) { + // Ignore modules that did not pass through the original transformer in a previous build + if (!(parentMeta && parentMeta.requires)) { + return false; + } + setInitialParentType(parentId, parentMeta.initialCommonJSType); + await Promise.all( + parentMeta.requires.map(({ resolved, isConditional }) => + setTypesForRequiredModules(parentId, resolved, isConditional, this.load) + ) + ); + if (getTypeForFullyAnalyzedModule(parentId) !== parentMeta.isCommonJS) { + return true; + } + for (const { + resolved: { id } + } of parentMeta.requires) { + if (getTypeForFullyAnalyzedModule(id) !== parentMeta.isRequiredCommonJS[id]) { + return true; + } + } + return false; + }, + /* eslint-disable no-param-reassign */ + resolveRequireSourcesAndUpdateMeta: (rollupContext) => async ( parentId, isParentCommonJS, + parentMeta, sources ) => { - knownCjsModuleTypes[parentId] = isParentCommonJS; - if ( - detectCyclesAndConditional && - knownCjsModuleTypes[parentId] && - requiredIds[parentId] && - !unconditionallyRequiredIds[parentId] - ) { - knownCjsModuleTypes[parentId] = IS_WRAPPED_COMMONJS; - } + parentMeta.initialCommonJSType = isParentCommonJS; + parentMeta.requires = []; + parentMeta.isRequiredCommonJS = Object.create(null); + setInitialParentType(parentId, isParentCommonJS); const requireTargets = await Promise.all( sources.map(async ({ source, isConditional }) => { // Never analyze or proxy internal modules @@ -82,38 +132,27 @@ export function getResolveRequireSourcesAndGetMeta(extensions, detectCyclesAndCo if (resolved.external) { return { id: wrapId(childId, EXTERNAL_SUFFIX), allowProxy: false }; } - requiredIds[childId] = true; - if (!(isConditional || knownCjsModuleTypes[parentId] === IS_WRAPPED_COMMONJS)) { - unconditionallyRequiredIds[childId] = true; - } - - getDependencies(parentId).add(childId); - if (!isCyclic(childId)) { - // This makes sure the current transform handler waits for all direct dependencies to be - // loaded and transformed and therefore for all transitive CommonJS dependencies to be - // loaded as well so that all cycles have been found and knownCjsModuleTypes is reliable. - await rollupContext.load(resolved); - } else if (detectCyclesAndConditional && knownCjsModuleTypes[parentId]) { - knownCjsModuleTypes[parentId] = IS_WRAPPED_COMMONJS; - } + parentMeta.requires.push({ resolved, isConditional }); + await setTypesForRequiredModules(parentId, resolved, isConditional, rollupContext.load); return { id: childId, allowProxy: true }; }) ); - return { - requireTargets: requireTargets.map(({ id: dependencyId, allowProxy }, index) => { - const isCommonJS = getTypeForFullyAnalyzedModule(dependencyId); - return { - source: sources[index].source, - id: allowProxy - ? isCommonJS === IS_WRAPPED_COMMONJS - ? wrapId(dependencyId, WRAPPED_SUFFIX) - : wrapId(dependencyId, PROXY_SUFFIX) - : dependencyId, - isCommonJS - }; - }), - usesRequireWrapper: getTypeForFullyAnalyzedModule(parentId) === IS_WRAPPED_COMMONJS - }; + parentMeta.isCommonJS = getTypeForFullyAnalyzedModule(parentId); + return requireTargets.map(({ id: dependencyId, allowProxy }, index) => { + // eslint-disable-next-line no-multi-assign + const isCommonJS = (parentMeta.isRequiredCommonJS[ + dependencyId + ] = getTypeForFullyAnalyzedModule(dependencyId)); + return { + source: sources[index].source, + id: allowProxy + ? isCommonJS === IS_WRAPPED_COMMONJS + ? wrapId(dependencyId, WRAPPED_SUFFIX) + : wrapId(dependencyId, PROXY_SUFFIX) + : dependencyId, + isCommonJS + }; + }); } }; } diff --git a/packages/commonjs/src/transform-commonjs.js b/packages/commonjs/src/transform-commonjs.js index 851115b47..5a71d0517 100644 --- a/packages/commonjs/src/transform-commonjs.js +++ b/packages/commonjs/src/transform-commonjs.js @@ -51,9 +51,10 @@ export default async function transformCommonjs( astCache, defaultIsModuleExports, needsRequireWrapper, - resolveRequireSourcesAndGetMeta, + resolveRequireSourcesAndUpdateMeta, isRequired, - checkDynamicRequire + checkDynamicRequire, + commonjsMeta ) { const ast = astCache || tryParse(parse, code, id); const magicString = new MagicString(code); @@ -437,7 +438,7 @@ export default async function transformCommonjs( ) && (ignoreGlobal || !uses.global) ) { - return { meta: { commonjs: { isCommonJS: false, isMixedModule: false } } }; + return { meta: { commonjs: { isCommonJS: false } } }; } let leadingComment = ''; @@ -459,7 +460,7 @@ export default async function transformCommonjs( ? 'exports' : 'module'; - const { importBlock, usesRequireWrapper } = await rewriteRequireExpressionsAndGetImportBlock( + const importBlock = await rewriteRequireExpressionsAndGetImportBlock( magicString, topLevelDeclarations, reassignedNames, @@ -469,12 +470,14 @@ export default async function transformCommonjs( exportsName, id, exportMode, - resolveRequireSourcesAndGetMeta, + resolveRequireSourcesAndUpdateMeta, needsRequireWrapper, isEsModule, isDynamicRequireModulesEnabled, - getIgnoreTryCatchRequireStatementMode + getIgnoreTryCatchRequireStatementMode, + commonjsMeta ); + const usesRequireWrapper = commonjsMeta.isCommonJS === IS_WRAPPED_COMMONJS; const exportBlock = isEsModule ? '' : rewriteExportsAndGetExportsBlock( @@ -527,11 +530,6 @@ function ${requireName} () { code: magicString.toString(), map: sourceMap ? magicString.generateMap() : null, syntheticNamedExports: isEsModule || usesRequireWrapper ? false : '__moduleExports', - meta: { - commonjs: { - isCommonJS: !isEsModule && (usesRequireWrapper ? IS_WRAPPED_COMMONJS : true), - isMixedModule: isEsModule - } - } + meta: { commonjs: commonjsMeta } }; } diff --git a/packages/commonjs/test/fixtures/function/module-side-effects-late-entry/_config.js b/packages/commonjs/test/fixtures/function/module-side-effects-late-entry/_config.js new file mode 100644 index 000000000..8c1d053bd --- /dev/null +++ b/packages/commonjs/test/fixtures/function/module-side-effects-late-entry/_config.js @@ -0,0 +1,22 @@ +const path = require('path'); + +module.exports = { + description: + 'use correct side-effects flags for files that become entry points after they are loaded', + options: { + treeshake: { moduleSideEffects: false }, + plugins: [ + { + load(id) { + if (id.endsWith('foo.js')) { + this.emitFile({ type: 'chunk', id: path.join(__dirname, 'foo.js') }); + } + } + } + ], + output: { chunkFileNames: 'generated-[name].js' } + }, + global: (global, t) => { + t.is(global.foo, 'foo'); + } +}; diff --git a/packages/commonjs/test/fixtures/function/module-side-effects-late-entry/foo.js b/packages/commonjs/test/fixtures/function/module-side-effects-late-entry/foo.js new file mode 100644 index 000000000..53d1fab39 --- /dev/null +++ b/packages/commonjs/test/fixtures/function/module-side-effects-late-entry/foo.js @@ -0,0 +1,2 @@ +// This side-effect will only be respected if this is an entry point +global.foo = 'foo'; diff --git a/packages/commonjs/test/fixtures/function/module-side-effects-late-entry/main.js b/packages/commonjs/test/fixtures/function/module-side-effects-late-entry/main.js new file mode 100644 index 000000000..60af16024 --- /dev/null +++ b/packages/commonjs/test/fixtures/function/module-side-effects-late-entry/main.js @@ -0,0 +1,3 @@ +import './foo.js'; + +export default 'main'; diff --git a/packages/commonjs/test/fixtures/function/plugin-isentry/_config.js b/packages/commonjs/test/fixtures/function/plugin-isentry/_config.js new file mode 100644 index 000000000..156176ad9 --- /dev/null +++ b/packages/commonjs/test/fixtures/function/plugin-isentry/_config.js @@ -0,0 +1,36 @@ +const fs = require('fs'); +const path = require('path'); +const assert = require('assert'); + +const ID_MAIN = path.join(__dirname, 'main.js'); +const ID_OTHER = path.join(__dirname, 'other.js'); + +module.exports = { + description: 'provides correct values for ModuleInfo.isEntry to not break legacy plugins', + options: { + input: [ID_MAIN, ID_OTHER], + output: { + chunkFileNames: '[name].js' + }, + plugins: [ + { + transform(code, id) { + if (this.getModuleInfo(id).isEntry) { + return `import "polyfill";\n${code}`; + } + return null; + }, + resolveId(id) { + if (id === 'polyfill') return id; + return null; + }, + load(id) { + if (id === 'polyfill') { + return `global.entryDetected = true;`; + } + return null; + } + } + ] + } +}; diff --git a/packages/commonjs/test/fixtures/function/plugin-isentry/dep.js b/packages/commonjs/test/fixtures/function/plugin-isentry/dep.js new file mode 100644 index 000000000..2f5dc9fbe --- /dev/null +++ b/packages/commonjs/test/fixtures/function/plugin-isentry/dep.js @@ -0,0 +1,2 @@ +t.is(global.entryDetected, true); +module.exports = 'dep'; diff --git a/packages/commonjs/test/fixtures/function/plugin-isentry/main.js b/packages/commonjs/test/fixtures/function/plugin-isentry/main.js new file mode 100644 index 000000000..811a39ee5 --- /dev/null +++ b/packages/commonjs/test/fixtures/function/plugin-isentry/main.js @@ -0,0 +1,2 @@ +t.is(global.entryDetected, true); +module.exports = require('./dep.js'); diff --git a/packages/commonjs/test/fixtures/function/plugin-isentry/other.js b/packages/commonjs/test/fixtures/function/plugin-isentry/other.js new file mode 100644 index 000000000..661ce2f2e --- /dev/null +++ b/packages/commonjs/test/fixtures/function/plugin-isentry/other.js @@ -0,0 +1 @@ +export const other = true; diff --git a/packages/commonjs/test/fixtures/function/preserve-modules/_config.js b/packages/commonjs/test/fixtures/function/preserve-modules/_config.js new file mode 100644 index 000000000..dbca5a506 --- /dev/null +++ b/packages/commonjs/test/fixtures/function/preserve-modules/_config.js @@ -0,0 +1,14 @@ +module.exports = { + description: 'uses correct entry files names when preserving modules', + options: { + preserveModules: true + }, + pluginOptions: { + // Our entry is wrapped, so it will not be functional without a proper proxy + strictRequires: true + }, + // This will only work if "main" corresponds to the actual entry point that unwraps main.js + global: (global, t) => { + t.is(global.main, 'main'); + } +}; diff --git a/packages/commonjs/test/fixtures/function/preserve-modules/main.js b/packages/commonjs/test/fixtures/function/preserve-modules/main.js new file mode 100644 index 000000000..7696217a1 --- /dev/null +++ b/packages/commonjs/test/fixtures/function/preserve-modules/main.js @@ -0,0 +1,4 @@ +global.main = 'main'; +console.log('main'); + +module.exports = 'main'; diff --git a/packages/commonjs/test/form.js b/packages/commonjs/test/form.js index 270d27ccf..182498e8b 100644 --- a/packages/commonjs/test/form.js +++ b/packages/commonjs/test/form.js @@ -54,15 +54,16 @@ if (path.sep === '/') { (config.solo ? test.only : test)(dir, (t) => Promise.all( inputEntries.map(async ([outputName, id]) => { - const { transform } = commonjs(config.options); - + const { buildStart, transform } = commonjs(config.options); + buildStart.call({ meta: { rollupVersion: '99.0.0' } }, { plugins: [] }); transformContext.getModuleInfo = (moduleId) => { return { isEntry: config.entry && moduleId === id, importers: config.importers && config.importers[outputName] ? config.importers[outputName].map((x) => `fixtures/form/${dir}/${x}`) - : [] + : [], + meta: {} }; }; const input = fs.readFileSync(id, 'utf-8'); diff --git a/packages/commonjs/test/snapshots/function.js.md b/packages/commonjs/test/snapshots/function.js.md index 1e80780c8..d928b3a85 100644 --- a/packages/commonjs/test/snapshots/function.js.md +++ b/packages/commonjs/test/snapshots/function.js.md @@ -3668,15 +3668,23 @@ Generated by [AVA](https://avajs.dev). { 'main.js': `'use strict';␊ ␊ - var other = require('./other.js');␊ + var other = require('./other-aeb2ae1d.js');␊ ␊ - t.is(other, 'foo');␊ + t.is(other.other, 'foo');␊ `, - 'other.js': `'use strict';␊ + 'other-aeb2ae1d.js': `'use strict';␊ ␊ var other = 'foo';␊ ␊ - module.exports = other;␊ + exports.other = other;␊ + `, + 'other.js': `'use strict';␊ + ␊ + var other = require('./other-aeb2ae1d.js');␊ + ␊ + ␊ + ␊ + module.exports = other.other;␊ `, } @@ -4772,11 +4780,11 @@ Generated by [AVA](https://avajs.dev). { 'main.js': `'use strict';␊ ␊ - var other = require('./other.js');␊ + var other = require('./other2.js');␊ ␊ var main = {};␊ ␊ - const foo = other;␊ + const foo = other.other;␊ ␊ t.is(foo, 'foo');␊ ␊ @@ -4784,9 +4792,17 @@ Generated by [AVA](https://avajs.dev). `, 'other.js': `'use strict';␊ ␊ + var other = require('./other2.js');␊ + ␊ + ␊ + ␊ + module.exports = other.other;␊ + `, + 'other2.js': `'use strict';␊ + ␊ var other = 'foo';␊ ␊ - module.exports = other;␊ + exports.other = other;␊ `, } @@ -4895,6 +4911,36 @@ Generated by [AVA](https://avajs.dev). `, } +## module-side-effects-late-entry + +> Snapshot 1 + + { + 'generated-foo.js': `'use strict';␊ + ␊ + var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};␊ + ␊ + // This side-effect will only be respected if this is an entry point␊ + commonjsGlobal.foo = 'foo';␊ + `, + 'generated-foo2.js': `'use strict';␊ + ␊ + require('./generated-foo.js');␊ + ␊ + var foo = {};␊ + ␊ + module.exports = foo;␊ + `, + 'main.js': `'use strict';␊ + ␊ + require('./generated-foo.js');␊ + ␊ + var main = 'main';␊ + ␊ + module.exports = main;␊ + `, + } + ## module_require > Snapshot 1 @@ -5292,6 +5338,85 @@ Generated by [AVA](https://avajs.dev). `, } +## plugin-isentry + +> Snapshot 1 + + { + 'main.js': `'use strict';␊ + ␊ + require('./polyfill.js');␊ + ␊ + var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};␊ + ␊ + t.is(commonjsGlobal.entryDetected, true);␊ + var dep = 'dep';␊ + ␊ + t.is(commonjsGlobal.entryDetected, true);␊ + var main = dep;␊ + ␊ + module.exports = main;␊ + `, + 'other.js': `'use strict';␊ + ␊ + Object.defineProperty(exports, '__esModule', { value: true });␊ + ␊ + require('./polyfill.js');␊ + ␊ + const other = true;␊ + ␊ + exports.other = other;␊ + `, + 'polyfill.js': `'use strict';␊ + ␊ + global.entryDetected = true;␊ + `, + } + +## preserve-modules + +> Snapshot 1 + + { + '_virtual/_commonjsHelpers.js': `'use strict';␊ + ␊ + Object.defineProperty(exports, '__esModule', { value: true });␊ + ␊ + var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};␊ + ␊ + exports.commonjsGlobal = commonjsGlobal;␊ + `, + 'main.js': `'use strict';␊ + ␊ + var main = require('./main2.js');␊ + ␊ + var mainExports = main.__require();␊ + ␊ + module.exports = mainExports;␊ + `, + 'main2.js': `'use strict';␊ + ␊ + Object.defineProperty(exports, '__esModule', { value: true });␊ + ␊ + var _commonjsHelpers = require('./_virtual/_commonjsHelpers.js');␊ + ␊ + var main;␊ + var hasRequiredMain;␊ + ␊ + function requireMain () {␊ + if (hasRequiredMain) return main;␊ + hasRequiredMain = 1;␊ + _commonjsHelpers.commonjsGlobal.main = 'main';␊ + console.log('main');␊ + ␊ + main = 'main';␊ + return main;␊ + }␊ + ␊ + exports.__require = requireMain;␊ + `, + } + ## react-apollo > Snapshot 1 diff --git a/packages/commonjs/test/snapshots/function.js.snap b/packages/commonjs/test/snapshots/function.js.snap index 56d99191721677fa71980f018592595d6c47e358..f12cfa25e749e4f43cc6d7258e7bd2b50f3899b2 100644 GIT binary patch literal 21721 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 diff --git a/packages/commonjs/test/snapshots/test.js.md b/packages/commonjs/test/snapshots/test.js.md index 1b1ebe464..d565de262 100644 --- a/packages/commonjs/test/snapshots/test.js.md +++ b/packages/commonjs/test/snapshots/test.js.md @@ -115,3 +115,173 @@ Generated by [AVA](https://avajs.dev). ␊ export { foo as default };␊ ` + +## updates all relevant modules when using the cache and the wrapping of a module changes + +> Snapshot 1 + + `'use strict';␊ + ␊ + var first = {};␊ + ␊ + var second = {};␊ + ␊ + second.second = 'second';␊ + ␊ + first.first = 'first'; first.first += second.second;␊ + ␊ + var main = 'main' + first.first;␊ + ␊ + module.exports = main;␊ + ` + +> Snapshot 2 + + `'use strict';␊ + ␊ + var first = {};␊ + ␊ + var second = {};␊ + ␊ + var hasRequiredSecond;␊ + ␊ + function requireSecond () {␊ + if (hasRequiredSecond) return second;␊ + hasRequiredSecond = 1;␊ + second.second = 'second'; second.second += requireFirst().first;␊ + return second;␊ + }␊ + ␊ + var hasRequiredFirst;␊ + ␊ + function requireFirst () {␊ + if (hasRequiredFirst) return first;␊ + hasRequiredFirst = 1;␊ + first.first = 'first'; first.first += requireSecond().second;␊ + return first;␊ + }␊ + ␊ + var main = 'main' + requireFirst().first;␊ + ␊ + module.exports = main;␊ + ` + +> Snapshot 3 + + `'use strict';␊ + ␊ + function getAugmentedNamespace(n) {␊ + var f = n.default;␊ + if (typeof f == "function") {␊ + var a = function () {␊ + return f.apply(this, arguments);␊ + };␊ + a.prototype = f.prototype;␊ + } else a = {};␊ + Object.defineProperty(a, '__esModule', {value: true});␊ + Object.keys(n).forEach(function (k) {␊ + var d = Object.getOwnPropertyDescriptor(n, k);␊ + Object.defineProperty(a, k, d.get ? d : {␊ + enumerable: true,␊ + get: function () {␊ + return n[k];␊ + }␊ + });␊ + });␊ + return a;␊ + }␊ + ␊ + var second = {};␊ + ␊ + var hasRequiredSecond;␊ + ␊ + function requireSecond () {␊ + if (hasRequiredSecond) return second;␊ + hasRequiredSecond = 1;␊ + second.second = 'second';␊ + return second;␊ + }␊ + ␊ + let first = 'first'; if (Math.random() < 1) first += requireSecond().second;␊ + ␊ + var first$1 = /*#__PURE__*/Object.freeze({␊ + __proto__: null,␊ + get first () { return first; }␊ + });␊ + ␊ + var require$$0 = /*@__PURE__*/getAugmentedNamespace(first$1);␊ + ␊ + var main = 'main' + require$$0.first;␊ + ␊ + module.exports = main;␊ + ` + +## updates mixed modules when using the cache and the wrapping of a module changes + +> Snapshot 1 + + `'use strict';␊ + ␊ + Object.defineProperty(exports, '__esModule', { value: true });␊ + ␊ + var first = {};␊ + ␊ + first.first = 'first';␊ + ␊ + const main = 'main'; const result = first.first;␊ + ␊ + exports.main = main;␊ + exports.result = result;␊ + ` + +> Snapshot 2 + + `'use strict';␊ + ␊ + Object.defineProperty(exports, '__esModule', { value: true });␊ + ␊ + var main$1 = /*#__PURE__*/Object.freeze({␊ + __proto__: null,␊ + get main () { return main; },␊ + get result () { return result; }␊ + });␊ + ␊ + function getAugmentedNamespace(n) {␊ + var f = n.default;␊ + if (typeof f == "function") {␊ + var a = function () {␊ + return f.apply(this, arguments);␊ + };␊ + a.prototype = f.prototype;␊ + } else a = {};␊ + Object.defineProperty(a, '__esModule', {value: true});␊ + Object.keys(n).forEach(function (k) {␊ + var d = Object.getOwnPropertyDescriptor(n, k);␊ + Object.defineProperty(a, k, d.get ? d : {␊ + enumerable: true,␊ + get: function () {␊ + return n[k];␊ + }␊ + });␊ + });␊ + return a;␊ + }␊ + ␊ + var first = {};␊ + ␊ + var require$$0 = /*@__PURE__*/getAugmentedNamespace(main$1);␊ + ␊ + var hasRequiredFirst;␊ + ␊ + function requireFirst () {␊ + if (hasRequiredFirst) return first;␊ + hasRequiredFirst = 1;␊ + first.first = 'first' + require$$0.main;␊ + return first;␊ + }␊ + ␊ + const main = 'main'; const result = requireFirst().first;␊ + ␊ + exports.main = main;␊ + exports.result = result;␊ + ` diff --git a/packages/commonjs/test/snapshots/test.js.snap b/packages/commonjs/test/snapshots/test.js.snap index 68529726427894ada7fa0377b4fea98960699f33..f5ee342d78e132627bb06a3af5c206bc49e0ac24 100644 GIT binary patch literal 1346 zcmV-I1-<$~RzV*DKM6#QN=eIs(kKZBFxG1AosBo%?3&r#q-o?s zh13J$hTsH<1BXf+s#1yHN=Ow~P(ekC!~ux|L~ueJIl!Br_0QUYG@?=kwY1)uH}l@S z_vZWF%-&KI<)E_s>gnq1&Lt)I#(D3DN8bK6qp;t{_@bX&J78SSuAf;r^YfKwFTIoD z(!zwIyqh&|d4KLymrs0f|B0V29Gc+L$*g$F2NmV&m6y+ddF0~FYcIa`pndbBCo)|6 z8yorYmmBU}{h`k)i|vQs2zD}D`qCjq`Skbbi|vh_i@*BY4}5?9#?dU7KCX(VbXYux zk0{F5b4#ZCR_VD9PgcE0-*?~4aOroGiju{M*e`RRGC6TMqs1YCFrscV(ki*!xyCAK zMutrs*Cz`!=nxuh>g0SUpix)^%`{1PHn3xlXhqn9b<2y%EJQRW(9NU%x8~6~mV#o2wDN3zP-D3ZF*vbJo0R`P75x8iG z%MFkCD^Uw(pj<)e({LPLGc#g3Kr`^e2v%|SSu1K8ju!+}=S^z)cCe=Bp#ZuI$Do`? zKbcC6+pW3vqFAA}TCbyiE$Jj;w_axo-CS3MH|VojMhzCPF(^gZU>DOM6Ih$V#9FZz zP1U7dB^mlV17^9B8{D=GN$r}5K4`G`Sw5^;&>C71TMcYAwOlu~H8^4z1}gB8HNK&S z^rYw65K^|4JAf3&rRcYW3hx++NaKxuaME*)y|s$mZ%RT;CW;4i``I?6&TyW4I--#Z zbMn9)BE&R9N~v(vG#6f2oHxxvNm_O&As2|gl~YZ#LxU(V%~|kc&nxEC6(R#i_->)Y zQA~Xi4s_+P3}+AOh;9jj>WQ{te^|IDjjhQtJCo|^{C~Bj7=*sTRcRkRJF_gEQ3eP z)?jA(Jx(|v9&Uvt@c}S?E3A=C7}x`r09ER>$!3Vr8dzKAt!7K_d)@AbW8-RaKBnv3 zhM%l6N5Up`I}w%@zX)v}!>$gsi(oT-IEe;lMNWv1(Nk6eg=wY5CYh8V>f!2Ga6kR*m~>g1@U%G(H9dMDKIiP4|4$MfQP`n(tm z)R18I>_j4ZMo*}TmbUBRFj)8DSQUm03Mq1>VSz08ahiE#kfr6}wL314MX zNVs>l{@2geyO`GF_{zSSM(D#F82%P|3O|G3ANkZTbo;)&I=#X$Tmh2H>3(i2(xdz? z1%BY}a68=oeBvIr|3};ww>BO!yY=u!a_1r8+CJbe)5l-?2RE*rzx}J%UkDUcT&WTO E059*9kN^Mx literal 938 zcmV;b16BM%RzVogn_g;Hsk_CV>XTMj5h)+ByTym4mI@p!jkK%X)DCgWJEH`{>cb z_dk6xc=X+cia{T1%b$;bj&}Pm{n)uNdHFN(cg3Iwo0j$K?tveD(R}CIOWpXDZ=%mD z20j10Wo=q#P0q?0>xGSb6(>y)5+$RdayqtseQ=0F)rhKR( z!66x^VHo3ODcRg*`dxz)8z2-C+!z%^6v*ISjC`cVumi0Qp>M)P`t0oF#{q_dCkhVf z^fji&UKk4@U9*&o2V&~hpbl;XuS2UwJhe;D#O+1>MxLQ}*zc2nuiTVy)bDGD%+B)i zRyq4E^3e5qt0-ZsTauv=u(w6RvNTp({lc$Pn*J?--|E<_ZL8o~*YfJcK-aJJU~O;) zPJ>nhS`8gLTWbwjJkKKsW0{(UdIggOvs07uz|#Jq5Zk)sH(HCV1QB2ighe5^YCb~| zLK*JWZWo-C=OYz3dB@aPieun-40}>itDKu-lvL7Kq;UWP1TJ6{ivf!lafmtNuy+7C zU5DD3mCDj6Y91_sLSV?&BZ(pPe7Ogog)$+`L6zZpqwM>g)AECOO zj;6>J2Jf;dCNnlfm*;{QbtxkE3LYK1x*{f-h+-LPOZ!x-+J|ZJ%M5OgS0$=catJ*( zo5gcijiW?Q^C;EH6B4dk&Gd_TGbxnNIdqui&I~+YOog!GR|a_c-N2r>6;>_L(#{{*IFJw#?vju0kO!kYEh ze1HGF8+*QAZx)n8iTEM9l+E{z=)T_up2jh;DÍvU3rn$>3gt!2okj}_&v{r^e+ M2hUKdAEgEW03LwJqyPW_ diff --git a/packages/commonjs/test/test.js b/packages/commonjs/test/test.js index 4a297a301..2f86e9f17 100644 --- a/packages/commonjs/test/test.js +++ b/packages/commonjs/test/test.js @@ -1,11 +1,13 @@ /* eslint-disable line-comment-position, no-new-func, no-undefined */ -import * as path from 'path'; import os from 'os'; +import * as path from 'path'; + import nodeResolve from '@rollup/plugin-node-resolve'; import test from 'ava'; import { getLocator } from 'locate-character'; + import { rollup } from 'rollup'; import { SourceMapConsumer } from 'source-map'; import { install } from 'source-map-support'; @@ -19,6 +21,23 @@ install(); process.chdir(__dirname); +const loader = (modules) => { + return { + load(id) { + if (Object.hasOwnProperty.call(modules, id)) { + return modules[id]; + } + return null; + }, + resolveId(id) { + if (Object.hasOwnProperty.call(modules, id)) { + return id; + } + return null; + } + }; +}; + test('Rollup peer dependency has correct format', (t) => { t.regex(peerDependencies.rollup, /^\^\d+\.\d+\.\d+(\|\|\^\d+\.\d+\.\d+)*$/); }); @@ -449,20 +468,18 @@ test('does not warn even if the ES module does not export "default"', async (t) }); test('compiles with cache', async (t) => { - // specific commonjs require() to ensure same instance is used - // eslint-disable-next-line global-require - const commonjsInstance = require('..'); + const plugin = commonjs(); - const bundle = await rollup({ + const { cache } = await rollup({ input: 'fixtures/function/index/main.js', - plugins: [commonjsInstance()] + plugins: [plugin] }); await t.notThrowsAsync( rollup({ input: 'fixtures/function/index/main.js', - plugins: [commonjsInstance()], - cache: bundle + plugins: [plugin], + cache }) ); }); @@ -547,20 +564,10 @@ test('produces optimized code when importing esm with a known default export', a input: 'main.js', plugins: [ commonjs({ requireReturnsDefault: true }), - { - load(id) { - if (id === 'main.js') { - return 'module.exports = require("esm.js")'; - } - if (id === 'esm.js') { - return 'export const ignored = "ignored"; export default "default"'; - } - return null; - }, - resolveId(id) { - return id; - } - } + loader({ + 'main.js': 'module.exports = require("esm.js")', + 'esm.js': 'export const ignored = "ignored"; export default "default"' + }) ] }); t.snapshot(await getCodeFromBundle(bundle)); @@ -571,20 +578,10 @@ test('produces optimized code when importing esm without a default export', asyn input: 'main.js', plugins: [ commonjs(), - { - load(id) { - if (id === 'main.js') { - return 'module.exports = require("esm.js")'; - } - if (id === 'esm.js') { - return 'export const value = "value";'; - } - return null; - }, - resolveId(id) { - return id; - } - } + loader({ + 'main.js': 'module.exports = require("esm.js")', + 'esm.js': 'export const value = "value";' + }) ] }); t.snapshot(await getCodeFromBundle(bundle)); @@ -763,3 +760,108 @@ test('throws when using an inadequate node_resolve version', async (t) => { 'Insufficient @rollup/plugin-node-resolve version: "@rollup/plugin-commonjs" requires at least @rollup/plugin-node-resolve@13.0.6 but found @rollup/plugin-node-resolve@13.0.5.' }); }); + +test('updates all relevant modules when using the cache and the wrapping of a module changes', async (t) => { + const modules = {}; + const resetModules = () => { + modules['main.js'] = "module.exports = 'main' + require('first.js').first;"; + modules['first.js'] = "exports.first = 'first'; exports.first += require('second.js').second;"; + modules['second.js'] = "exports.second = 'second';"; + }; + const options = { + input: 'main.js', + plugins: [commonjs({ transformMixedEsModules: true }), loader(modules)], + onwarn(warning) { + if (warning.code !== 'CIRCULAR_DEPENDENCY') { + throw new Error(warning.message); + } + } + }; + + resetModules(); + let bundle = await rollup(options); + t.is((await executeBundle(bundle, t)).exports, 'mainfirstsecond'); + const firstCode = await getCodeFromBundle(bundle); + t.snapshot(firstCode); + + options.cache = bundle.cache; + modules['second.js'] = "exports.second = 'second'; exports.second += require('first.js').first;"; + bundle = await rollup(options); + t.is((await executeBundle(bundle, t)).exports, 'mainfirstsecondfirst'); + t.snapshot(await getCodeFromBundle(bundle)); + + options.cache = bundle.cache; + resetModules(); + bundle = await rollup(options); + t.is(await getCodeFromBundle(bundle), firstCode); + + options.cache = bundle.cache; + modules['first.js'] = + "export let first = 'first'; if (Math.random() < 1) first += require('second.js').second;"; + bundle = await rollup(options); + t.is((await executeBundle(bundle, t)).exports, 'mainfirstsecond'); + t.snapshot(await getCodeFromBundle(bundle)); + + options.cache = bundle.cache; + resetModules(); + bundle = await rollup(options); + t.is(await getCodeFromBundle(bundle), firstCode); +}); + +test('updates mixed modules when using the cache and the wrapping of a module changes', async (t) => { + const modules = {}; + const resetModules = () => { + modules['main.js'] = + "export const main = 'main'; export const result = require('first.js').first;"; + modules['first.js'] = "exports.first = 'first';"; + }; + const options = { + input: 'main.js', + plugins: [commonjs({ transformMixedEsModules: true }), loader(modules)], + onwarn(warning) { + if (warning.code !== 'CIRCULAR_DEPENDENCY') { + throw new Error(warning.message); + } + } + }; + + resetModules(); + let bundle = await rollup(options); + t.deepEqual((await executeBundle(bundle, t)).exports, { main: 'main', result: 'first' }); + const firstCode = await getCodeFromBundle(bundle); + t.snapshot(firstCode); + + options.cache = bundle.cache; + modules['first.js'] = "exports.first = 'first' + require('main.js').main"; + bundle = await rollup(options); + t.deepEqual((await executeBundle(bundle, t)).exports, { main: 'main', result: 'firstmain' }); + t.snapshot(await getCodeFromBundle(bundle)); + + options.cache = bundle.cache; + resetModules(); + bundle = await rollup(options); + t.is(await getCodeFromBundle(bundle), firstCode); +}); + +test('allows the config to be reused', async (t) => { + const config = { + preserveModules: true, + plugins: [ + commonjs({ requireReturnsDefault: true }), + loader({ + 'foo.js': "console.log('foo')", + 'bar.js': "console.log('bar')" + }) + ] + }; + let bundle = await rollup({ input: 'foo.js', ...config }); + t.deepEqual( + bundle.cache.modules.map(({ id }) => id), + ['foo.js', 'foo.js?commonjs-entry'] + ); + bundle = await rollup({ input: 'bar.js', ...config }); + t.deepEqual( + bundle.cache.modules.map(({ id }) => id), + ['bar.js', 'bar.js?commonjs-entry'] + ); +});