diff --git a/packages/commonjs/package.json b/packages/commonjs/package.json index ff706eeb6..e4643da9b 100644 --- a/packages/commonjs/package.json +++ b/packages/commonjs/package.json @@ -52,7 +52,7 @@ "require" ], "peerDependencies": { - "rollup": "^2.67.0" + "rollup": "^2.68.0" }, "dependencies": { "@rollup/pluginutils": "^3.1.0", @@ -68,7 +68,7 @@ "@rollup/plugin-node-resolve": "^13.1.0", "locate-character": "^2.0.5", "require-relative": "^0.8.7", - "rollup": "^2.67.3", + "rollup": "^2.68.0", "shx": "^0.3.2", "source-map": "^0.7.3", "source-map-support": "^0.5.19", diff --git a/packages/commonjs/src/proxies.js b/packages/commonjs/src/proxies.js index 10e9d0894..eb6ff9ea5 100644 --- a/packages/commonjs/src/proxies.js +++ b/packages/commonjs/src/proxies.js @@ -73,7 +73,6 @@ export function getEsImportProxy(id, defaultIsModuleExports) { } return { code, - syntheticNamedExports: '__moduleExports', - meta: { commonjs: { isCommonJS: false } } + syntheticNamedExports: '__moduleExports' }; } diff --git a/packages/commonjs/src/resolve-id.js b/packages/commonjs/src/resolve-id.js index 1f6c874a3..43066afad 100644 --- a/packages/commonjs/src/resolve-id.js +++ b/packages/commonjs/src/resolve-id.js @@ -121,7 +121,7 @@ export default function getResolveId(extensions) { meta: { commonjs: commonjsMeta } } = moduleInfo; if (commonjsMeta && commonjsMeta.isCommonJS === IS_WRAPPED_COMMONJS) { - return wrapId(resolved.id, ES_IMPORT_SUFFIX); + return { id: wrapId(resolved.id, ES_IMPORT_SUFFIX), meta: { commonjs: { resolved } } }; } return resolved; }; diff --git a/packages/commonjs/src/resolve-require-sources.js b/packages/commonjs/src/resolve-require-sources.js index 49dc0dc2a..11647e010 100644 --- a/packages/commonjs/src/resolve-require-sources.js +++ b/packages/commonjs/src/resolve-require-sources.js @@ -1,6 +1,8 @@ import { + ES_IMPORT_SUFFIX, EXTERNAL_SUFFIX, IS_WRAPPED_COMMONJS, + isWrappedId, PROXY_SUFFIX, wrapId, WRAPPED_SUFFIX @@ -27,6 +29,9 @@ export function getRequireResolver(extensions, detectCyclesAndConditional) { return false; }; + // Once a module is listed here, its type (wrapped or not) is fixed and may + // not change for the rest of the current build, to not break already + // transformed modules. const fullyAnalyzedModules = Object.create(null); const getTypeForFullyAnalyzedModule = (id) => { @@ -34,7 +39,6 @@ export function getRequireResolver(extensions, detectCyclesAndConditional) { if (knownType !== true || !detectCyclesAndConditional || fullyAnalyzedModules[id]) { return knownType; } - fullyAnalyzedModules[id] = true; if (isCyclic(id)) { return (knownCjsModuleTypes[id] = IS_WRAPPED_COMMONJS); } @@ -42,13 +46,11 @@ export function getRequireResolver(extensions, detectCyclesAndConditional) { }; 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; + // Fully analyzed modules may never change type + if (fullyAnalyzedModules[id]) { + return; + } + knownCjsModuleTypes[id] = initialCommonJSType; if ( detectCyclesAndConditional && knownCjsModuleTypes[id] === true && @@ -59,7 +61,7 @@ export function getRequireResolver(extensions, detectCyclesAndConditional) { } }; - const setTypesForRequiredModules = async (parentId, resolved, isConditional, loadModule) => { + const analyzeRequiredModule = async (parentId, resolved, isConditional, loadModule) => { const childId = resolved.id; requiredIds[childId] = true; if (!(isConditional || knownCjsModuleTypes[parentId] === IS_WRAPPED_COMMONJS)) { @@ -68,41 +70,85 @@ export function getRequireResolver(extensions, detectCyclesAndConditional) { 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. + // 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); } }; + const getTypeForImportedModule = async (resolved, loadModule) => { + if (resolved.id in knownCjsModuleTypes) { + // This handles cyclic ES dependencies + return knownCjsModuleTypes[resolved.id]; + } + const { + meta: { commonjs } + } = await loadModule(resolved); + return (commonjs && commonjs.isCommonJS) || false; + }; + return { getWrappedIds: () => Object.keys(knownCjsModuleTypes).filter( (id) => knownCjsModuleTypes[id] === IS_WRAPPED_COMMONJS ), isRequiredId: (id) => requiredIds[id], - 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]) { + async shouldTransformCachedModule({ + id: parentId, + resolvedSources, + meta: { commonjs: parentMeta } + }) { + // We explicitly track ES modules to handle ciruclar imports + if (!(parentMeta && parentMeta.isCommonJS)) knownCjsModuleTypes[parentId] = false; + if (isWrappedId(parentId, ES_IMPORT_SUFFIX)) return false; + const parentRequires = parentMeta && parentMeta.requires; + if (parentRequires) { + setInitialParentType(parentId, parentMeta.initialCommonJSType); + await Promise.all( + parentRequires.map(({ resolved, isConditional }) => + analyzeRequiredModule(parentId, resolved, isConditional, this.load) + ) + ); + if (getTypeForFullyAnalyzedModule(parentId) !== parentMeta.isCommonJS) { return true; } + for (const { + resolved: { id } + } of parentRequires) { + if (getTypeForFullyAnalyzedModule(id) !== parentMeta.isRequiredCommonJS[id]) { + return true; + } + } + // Now that we decided to go with the cached copy, neither the parent + // module nor any of its children may change types anymore + fullyAnalyzedModules[parentId] = true; + for (const { + resolved: { id } + } of parentRequires) { + fullyAnalyzedModules[id] = true; + } } - return false; + const parentRequireSet = new Set((parentRequires || []).map(({ resolved: { id } }) => id)); + return ( + await Promise.all( + Object.keys(resolvedSources) + .map((source) => resolvedSources[source]) + .filter(({ id }) => !parentRequireSet.has(id)) + .map(async (resolved) => { + if (isWrappedId(resolved.id, ES_IMPORT_SUFFIX)) { + return ( + (await getTypeForImportedModule( + (await this.load({ id: resolved.id })).meta.commonjs.resolved, + this.load + )) !== IS_WRAPPED_COMMONJS + ); + } + return (await getTypeForImportedModule(resolved, this.load)) === IS_WRAPPED_COMMONJS; + }) + ) + ).some((shouldTransform) => shouldTransform); }, /* eslint-disable no-param-reassign */ resolveRequireSourcesAndUpdateMeta: (rollupContext) => async ( @@ -133,16 +179,18 @@ export function getRequireResolver(extensions, detectCyclesAndConditional) { return { id: wrapId(childId, EXTERNAL_SUFFIX), allowProxy: false }; } parentMeta.requires.push({ resolved, isConditional }); - await setTypesForRequiredModules(parentId, resolved, isConditional, rollupContext.load); + await analyzeRequiredModule(parentId, resolved, isConditional, rollupContext.load); return { id: childId, allowProxy: true }; }) ); parentMeta.isCommonJS = getTypeForFullyAnalyzedModule(parentId); + fullyAnalyzedModules[parentId] = true; return requireTargets.map(({ id: dependencyId, allowProxy }, index) => { // eslint-disable-next-line no-multi-assign const isCommonJS = (parentMeta.isRequiredCommonJS[ dependencyId ] = getTypeForFullyAnalyzedModule(dependencyId)); + fullyAnalyzedModules[dependencyId] = true; return { source: sources[index].source, id: allowProxy diff --git a/packages/commonjs/src/transform-commonjs.js b/packages/commonjs/src/transform-commonjs.js index 5a71d0517..5287c5f79 100644 --- a/packages/commonjs/src/transform-commonjs.js +++ b/packages/commonjs/src/transform-commonjs.js @@ -95,6 +95,7 @@ export default async function transformCommonjs( const topLevelDefineCompiledEsmExpressions = []; const replacedGlobal = []; const replacedDynamicRequires = []; + const importedVariables = new Set(); walk(ast, { enter(node, parent) { @@ -208,6 +209,11 @@ export default async function transformCommonjs( } if (!isRequireExpression(node, scope)) { + const keypath = getKeypath(node.callee); + if (keypath && importedVariables.has(keypath.name)) { + // Heuristic to deoptimize requires after a required function has been called + currentConditionalNodeEnd = Infinity; + } return; } @@ -236,6 +242,11 @@ export default async function transformCommonjs( currentConditionalNodeEnd !== null, parent.type === 'ExpressionStatement' ? parent : node ); + if (parent.type === 'VariableDeclarator' && parent.id.type === 'Identifier') { + for (const name of extractAssignedNames(parent.id)) { + importedVariables.add(name); + } + } } return; } @@ -448,7 +459,9 @@ export default async function transformCommonjs( magicString.remove(0, commentEnd).trim(); } - const exportMode = shouldWrap + const exportMode = isEsModule + ? 'none' + : shouldWrap ? uses.module ? 'module' : 'exports' diff --git a/packages/commonjs/test/fixtures/form/unambiguous-with-default-export/output.js b/packages/commonjs/test/fixtures/form/unambiguous-with-default-export/output.js index b2a41f38e..2d6dac42c 100644 --- a/packages/commonjs/test/fixtures/form/unambiguous-with-default-export/output.js +++ b/packages/commonjs/test/fixtures/form/unambiguous-with-default-export/output.js @@ -1,5 +1,4 @@ import * as commonjsHelpers from "_commonjsHelpers.js"; -import { __exports as input } from "\u0000fixtures/form/unambiguous-with-default-export/input.js?commonjs-exports" import "\u0000CWD/fixtures/form/unambiguous-with-default-export/foo.js?commonjs-proxy"; export default {}; diff --git a/packages/commonjs/test/fixtures/form/unambiguous-with-import/output.js b/packages/commonjs/test/fixtures/form/unambiguous-with-import/output.js index 76b7883b0..0a89b5bf6 100644 --- a/packages/commonjs/test/fixtures/form/unambiguous-with-import/output.js +++ b/packages/commonjs/test/fixtures/form/unambiguous-with-import/output.js @@ -1,5 +1,4 @@ import * as commonjsHelpers from "_commonjsHelpers.js"; -import { __exports as input } from "\u0000fixtures/form/unambiguous-with-import/input.js?commonjs-exports" import "\u0000CWD/fixtures/form/unambiguous-with-import/foo.js?commonjs-proxy"; import './bar.js'; diff --git a/packages/commonjs/test/fixtures/form/unambiguous-with-named-export/output.js b/packages/commonjs/test/fixtures/form/unambiguous-with-named-export/output.js index a31cc3202..13bee26c4 100644 --- a/packages/commonjs/test/fixtures/form/unambiguous-with-named-export/output.js +++ b/packages/commonjs/test/fixtures/form/unambiguous-with-named-export/output.js @@ -1,5 +1,4 @@ import * as commonjsHelpers from "_commonjsHelpers.js"; -import { __exports as input } from "\u0000fixtures/form/unambiguous-with-named-export/input.js?commonjs-exports" import "\u0000CWD/fixtures/form/unambiguous-with-named-export/foo.js?commonjs-proxy"; export {}; diff --git a/packages/commonjs/test/fixtures/function/call-non-local-function-semantics/_config.js b/packages/commonjs/test/fixtures/function/call-non-local-function-semantics/_config.js new file mode 100644 index 000000000..ac0ea14e6 --- /dev/null +++ b/packages/commonjs/test/fixtures/function/call-non-local-function-semantics/_config.js @@ -0,0 +1,4 @@ +module.exports = { + description: + 'uses strict require semantics for all modules that are required after an imported function is called' +}; diff --git a/packages/commonjs/test/fixtures/function/call-non-local-function-semantics/browser.js b/packages/commonjs/test/fixtures/function/call-non-local-function-semantics/browser.js new file mode 100644 index 000000000..842765579 --- /dev/null +++ b/packages/commonjs/test/fixtures/function/call-non-local-function-semantics/browser.js @@ -0,0 +1 @@ +module.exports = 'browser'; diff --git a/packages/commonjs/test/fixtures/function/call-non-local-function-semantics/main.js b/packages/commonjs/test/fixtures/function/call-non-local-function-semantics/main.js new file mode 100644 index 000000000..f9e23dd6c --- /dev/null +++ b/packages/commonjs/test/fixtures/function/call-non-local-function-semantics/main.js @@ -0,0 +1,7 @@ +// simplified from dd-trace +const platform = require('./platform'); +const browser = require('./browser'); + +platform.use(browser); + +require('./proxy'); diff --git a/packages/commonjs/test/fixtures/function/call-non-local-function-semantics/platform.js b/packages/commonjs/test/fixtures/function/call-non-local-function-semantics/platform.js new file mode 100644 index 000000000..93634d9df --- /dev/null +++ b/packages/commonjs/test/fixtures/function/call-non-local-function-semantics/platform.js @@ -0,0 +1 @@ +exports.use = (platform) => (exports.platform = platform); diff --git a/packages/commonjs/test/fixtures/function/call-non-local-function-semantics/proxy.js b/packages/commonjs/test/fixtures/function/call-non-local-function-semantics/proxy.js new file mode 100644 index 000000000..e490667ea --- /dev/null +++ b/packages/commonjs/test/fixtures/function/call-non-local-function-semantics/proxy.js @@ -0,0 +1,3 @@ +const { platform } = require('./platform.js'); + +t.is(platform, 'browser'); diff --git a/packages/commonjs/test/snapshots/function.js.md b/packages/commonjs/test/snapshots/function.js.md index d928b3a85..a49552585 100644 --- a/packages/commonjs/test/snapshots/function.js.md +++ b/packages/commonjs/test/snapshots/function.js.md @@ -87,6 +87,46 @@ Generated by [AVA](https://avajs.dev). `, } +## call-non-local-function-semantics + +> Snapshot 1 + + { + 'main.js': `'use strict';␊ + ␊ + var main = {};␊ + ␊ + var platform$1 = {};␊ + ␊ + platform$1.use = (platform) => (platform$1.platform = platform);␊ + ␊ + var browser$1 = 'browser';␊ + ␊ + var proxy = {};␊ + ␊ + var hasRequiredProxy;␊ + ␊ + function requireProxy () {␊ + if (hasRequiredProxy) return proxy;␊ + hasRequiredProxy = 1;␊ + const { platform } = platform$1;␊ + ␊ + t.is(platform, 'browser');␊ + return proxy;␊ + }␊ + ␊ + // simplified from dd-trace␊ + const platform = platform$1;␊ + const browser = browser$1;␊ + ␊ + platform.use(browser);␊ + ␊ + requireProxy();␊ + ␊ + module.exports = main;␊ + `, + } + ## circular-dependencies > Snapshot 1 diff --git a/packages/commonjs/test/snapshots/function.js.snap b/packages/commonjs/test/snapshots/function.js.snap index f12cfa25e..ee77041b1 100644 Binary files a/packages/commonjs/test/snapshots/function.js.snap and b/packages/commonjs/test/snapshots/function.js.snap differ diff --git a/packages/commonjs/test/snapshots/test.js.md b/packages/commonjs/test/snapshots/test.js.md index d565de262..684f9bc65 100644 --- a/packages/commonjs/test/snapshots/test.js.md +++ b/packages/commonjs/test/snapshots/test.js.md @@ -116,57 +116,51 @@ 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 +## handles when an imported dependency of an ES module changes type > Snapshot 1 `'use strict';␊ ␊ - var first = {};␊ + const dep = 'esm';␊ ␊ - var second = {};␊ - ␊ - second.second = 'second';␊ - ␊ - first.first = 'first'; first.first += second.second;␊ - ␊ - var main = 'main' + first.first;␊ - ␊ - module.exports = main;␊ + module.exports = dep;␊ ` > Snapshot 2 `'use strict';␊ ␊ - var first = {};␊ + var dep_1 = 'cjs';␊ ␊ - var second = {};␊ - ␊ - var hasRequiredSecond;␊ + module.exports = dep_1;␊ + ` + +> Snapshot 3 + + `'use strict';␊ ␊ - function requireSecond () {␊ - if (hasRequiredSecond) return second;␊ - hasRequiredSecond = 1;␊ - second.second = 'second'; second.second += requireFirst().first;␊ - return second;␊ - }␊ + var dep$1 = {};␊ ␊ - var hasRequiredFirst;␊ + var hasRequiredDep;␊ ␊ - function requireFirst () {␊ - if (hasRequiredFirst) return first;␊ - hasRequiredFirst = 1;␊ - first.first = 'first'; first.first += requireSecond().second;␊ - return first;␊ + function requireDep () {␊ + if (hasRequiredDep) return dep$1;␊ + hasRequiredDep = 1;␊ + dep$1.dep = 'cjs'; dep$1.dep += requireDep().dep;␊ + return dep$1;␊ }␊ ␊ - var main = 'main' + requireFirst().first;␊ + var depExports = requireDep();␊ ␊ - module.exports = main;␊ + var dep = depExports.dep;␊ + ␊ + module.exports = dep;␊ ` -> Snapshot 3 +## handles when a required dependency of a CJS module changes type + +> Snapshot 1 `'use strict';␊ ␊ @@ -191,60 +185,58 @@ Generated by [AVA](https://avajs.dev). return a;␊ }␊ ␊ - var second = {};␊ + const dep = 'esm';␊ ␊ - 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({␊ + var dep$1 = /*#__PURE__*/Object.freeze({␊ __proto__: null,␊ - get first () { return first; }␊ + dep: dep␊ });␊ ␊ - var require$$0 = /*@__PURE__*/getAugmentedNamespace(first$1);␊ + var require$$0 = /*@__PURE__*/getAugmentedNamespace(dep$1);␊ ␊ - var main = 'main' + require$$0.first;␊ + var main = require$$0.dep;␊ ␊ module.exports = main;␊ ` -## updates mixed modules when using the cache and the wrapping of a module changes - -> Snapshot 1 +> Snapshot 2 `'use strict';␊ ␊ - Object.defineProperty(exports, '__esModule', { value: true });␊ - ␊ - var first = {};␊ + var dep = {};␊ ␊ - first.first = 'first';␊ + dep.dep = 'cjs';␊ ␊ - const main = 'main'; const result = first.first;␊ + var main = dep.dep;␊ ␊ - exports.main = main;␊ - exports.result = result;␊ + module.exports = main;␊ ` -> Snapshot 2 +> Snapshot 3 `'use strict';␊ ␊ - Object.defineProperty(exports, '__esModule', { value: true });␊ + var dep = {};␊ ␊ - var main$1 = /*#__PURE__*/Object.freeze({␊ - __proto__: null,␊ - get main () { return main; },␊ - get result () { return result; }␊ - });␊ + var hasRequiredDep;␊ + ␊ + function requireDep () {␊ + if (hasRequiredDep) return dep;␊ + hasRequiredDep = 1;␊ + dep.dep = 'cjs'; dep.dep += requireDep().dep;␊ + return dep;␊ + }␊ + ␊ + var main = requireDep().dep;␊ + ␊ + module.exports = main;␊ + ` + +## handles when a required dependency of a mixed ES module changes type + +> Snapshot 1 + + `'use strict';␊ ␊ function getAugmentedNamespace(n) {␊ var f = n.default;␊ @@ -267,21 +259,60 @@ Generated by [AVA](https://avajs.dev). return a;␊ }␊ ␊ - var first = {};␊ + const dep = 'esm';␊ + ␊ + var dep$1 = /*#__PURE__*/Object.freeze({␊ + __proto__: null,␊ + dep: dep␊ + });␊ + ␊ + var require$$0 = /*@__PURE__*/getAugmentedNamespace(dep$1);␊ + ␊ + var main = require$$0.dep;␊ + ␊ + module.exports = main;␊ + ` + +> Snapshot 2 + + `'use strict';␊ + ␊ + var dep = {};␊ ␊ - var require$$0 = /*@__PURE__*/getAugmentedNamespace(main$1);␊ + dep.dep = 'cjs';␊ ␊ - var hasRequiredFirst;␊ + var main = dep.dep;␊ ␊ - function requireFirst () {␊ - if (hasRequiredFirst) return first;␊ - hasRequiredFirst = 1;␊ - first.first = 'first' + require$$0.main;␊ - return first;␊ + module.exports = main;␊ + ` + +> Snapshot 3 + + `'use strict';␊ + ␊ + var dep = {};␊ + ␊ + var hasRequiredDep;␊ + ␊ + function requireDep () {␊ + if (hasRequiredDep) return dep;␊ + hasRequiredDep = 1;␊ + dep.dep = 'cjs'; dep.dep += requireDep().dep;␊ + return dep;␊ }␊ ␊ - const main = 'main'; const result = requireFirst().first;␊ + var main = requireDep().dep;␊ + ␊ + module.exports = main;␊ + ` + +## handles ESM cycles when using the cache + +> Snapshot 1 + + `'use strict';␊ + ␊ + console.log('dep');␊ ␊ - exports.main = main;␊ - exports.result = result;␊ + console.log('main');␊ ` diff --git a/packages/commonjs/test/snapshots/test.js.snap b/packages/commonjs/test/snapshots/test.js.snap index f5ee342d7..46745cca1 100644 Binary files a/packages/commonjs/test/snapshots/test.js.snap and b/packages/commonjs/test/snapshots/test.js.snap differ diff --git a/packages/commonjs/test/test.js b/packages/commonjs/test/test.js index 2f86e9f17..138ee2e06 100644 --- a/packages/commonjs/test/test.js +++ b/packages/commonjs/test/test.js @@ -761,86 +761,390 @@ test('throws when using an inadequate node_resolve version', async (t) => { }); }); -test('updates all relevant modules when using the cache and the wrapping of a module changes', async (t) => { +const onwarn = (warning) => { + if (warning.code !== 'CIRCULAR_DEPENDENCY') { + throw new Error(warning.message); + } +}; + +const getTransformTracker = (trackedId) => { + const trackedTransforms = []; + const meta = {}; + return { + meta, + trackedTransforms, + tracker: { + name: 'transform-tracker', + transform(code, id) { + trackedTransforms.push(id); + }, + moduleParsed({ id, meta: { commonjs: commonjsMeta } }) { + if (id === trackedId) { + Object.assign(meta, commonjsMeta); + } + } + } + }; +}; + +test('handles when an imported dependency of an ES module changes type', async (t) => { + const { meta, tracker, trackedTransforms } = getTransformTracker('dep.js'); 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';"; + modules['main.js'] = "import {dep} from 'dep.js';export default dep;"; + modules['dep.js'] = "export const dep = 'esm';"; }; const options = { input: 'main.js', - plugins: [commonjs({ transformMixedEsModules: true }), loader(modules)], - onwarn(warning) { - if (warning.code !== 'CIRCULAR_DEPENDENCY') { - throw new Error(warning.message); - } - } + plugins: [commonjs(), loader(modules), tracker], + onwarn }; resetModules(); let bundle = await rollup(options); - t.is((await executeBundle(bundle, t)).exports, 'mainfirstsecond'); - const firstCode = await getCodeFromBundle(bundle); - t.snapshot(firstCode); + t.is(meta.isCommonJS, false); + t.deepEqual((await executeBundle(bundle, t)).exports, 'esm'); + t.deepEqual(trackedTransforms, ['main.js', 'dep.js', 'main.js?commonjs-entry']); + trackedTransforms.length = 0; + const esCode = await getCodeFromBundle(bundle); + t.snapshot(esCode); + + modules['dep.js'] = "exports.dep = 'cjs';"; + options.cache = bundle.cache; + bundle = await rollup(options); + t.is(meta.isCommonJS, true); + t.deepEqual((await executeBundle(bundle, t)).exports, 'cjs'); + t.deepEqual(trackedTransforms, ['dep.js', '\0commonjsHelpers.js', '\0dep.js?commonjs-exports']); + trackedTransforms.length = 0; + const cjsCode = await getCodeFromBundle(bundle); + t.snapshot(cjsCode); + + modules['dep.js'] = "exports.dep = 'cjs'; exports.dep += require('dep.js').dep;"; + options.cache = bundle.cache; + bundle = await rollup(options); + t.is(meta.isCommonJS, 'withRequireFunction'); + t.deepEqual((await executeBundle(bundle, t)).exports, 'cjscjs'); + t.deepEqual(trackedTransforms, ['dep.js', 'main.js', '\0dep.js?commonjs-es-import']); + trackedTransforms.length = 0; + const wrappedCode = await getCodeFromBundle(bundle); + t.snapshot(wrappedCode); + resetModules(); 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)); + t.is(meta.isCommonJS, false); + t.deepEqual((await executeBundle(bundle, t)).exports, 'esm'); + t.deepEqual(trackedTransforms, ['dep.js', 'main.js']); + trackedTransforms.length = 0; + t.is(await getCodeFromBundle(bundle), esCode); + modules['dep.js'] = "exports.dep = 'cjs'; exports.dep += require('dep.js').dep;"; options.cache = bundle.cache; + bundle = await rollup(options); + t.is(meta.isCommonJS, 'withRequireFunction'); + t.deepEqual((await executeBundle(bundle, t)).exports, 'cjscjs'); + t.deepEqual(trackedTransforms, [ + 'dep.js', + 'main.js', + '\0dep.js?commonjs-es-import', + '\0commonjsHelpers.js', + '\0dep.js?commonjs-exports' + ]); + trackedTransforms.length = 0; + t.is(await getCodeFromBundle(bundle), wrappedCode); + + modules['dep.js'] = "exports.dep = 'cjs';"; + options.cache = bundle.cache; + bundle = await rollup(options); + t.is(meta.isCommonJS, true); + t.deepEqual((await executeBundle(bundle, t)).exports, 'cjs'); + t.deepEqual(trackedTransforms, ['dep.js', 'main.js']); + trackedTransforms.length = 0; + t.is(await getCodeFromBundle(bundle), cjsCode); + + resetModules(); + options.cache = bundle.cache; + bundle = await rollup(options); + t.is(meta.isCommonJS, false); + t.deepEqual((await executeBundle(bundle, t)).exports, 'esm'); + t.deepEqual(trackedTransforms, ['dep.js']); + trackedTransforms.length = 0; + t.is(await getCodeFromBundle(bundle), esCode); +}); + +test('handles when a dynamically imported dependency of an ES module changes type', async (t) => { + const { meta, tracker, trackedTransforms } = getTransformTracker('dep.js'); + const modules = {}; + const resetModules = () => { + modules['main.js'] = "export default import('dep.js').then(({dep}) => dep);"; + modules['dep.js'] = "export const dep = 'esm';"; + }; + const options = { + input: 'main.js', + plugins: [commonjs(), loader(modules), tracker], + onwarn + }; + resetModules(); + let bundle = await rollup(options); + t.is(meta.isCommonJS, false); + t.deepEqual(await (await executeBundle(bundle, t)).exports, 'esm'); + t.deepEqual(trackedTransforms, ['main.js', 'main.js?commonjs-entry', 'dep.js']); + trackedTransforms.length = 0; + + modules['dep.js'] = "exports.dep = 'cjs';"; + options.cache = bundle.cache; bundle = await rollup(options); - t.is(await getCodeFromBundle(bundle), firstCode); + t.is(meta.isCommonJS, true); + t.deepEqual(await (await executeBundle(bundle, t)).exports, 'cjs'); + t.deepEqual(trackedTransforms, ['dep.js', '\0commonjsHelpers.js', '\0dep.js?commonjs-exports']); + trackedTransforms.length = 0; + modules['dep.js'] = "exports.dep = 'cjs'; exports.dep += require('dep.js').dep;"; 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)); + t.is(meta.isCommonJS, 'withRequireFunction'); + t.deepEqual(await (await executeBundle(bundle, t)).exports, 'cjscjs'); + t.deepEqual(trackedTransforms, ['dep.js', 'main.js', '\0dep.js?commonjs-es-import']); + trackedTransforms.length = 0; + resetModules(); options.cache = bundle.cache; + bundle = await rollup(options); + t.is(meta.isCommonJS, false); + t.deepEqual(await (await executeBundle(bundle, t)).exports, 'esm'); + t.deepEqual(trackedTransforms, ['dep.js', 'main.js']); + trackedTransforms.length = 0; + + modules['dep.js'] = "exports.dep = 'cjs'; exports.dep += require('dep.js').dep;"; + options.cache = bundle.cache; + bundle = await rollup(options); + t.is(meta.isCommonJS, 'withRequireFunction'); + t.deepEqual(await (await executeBundle(bundle, t)).exports, 'cjscjs'); + t.deepEqual(trackedTransforms, [ + 'dep.js', + 'main.js', + '\0dep.js?commonjs-es-import', + '\0commonjsHelpers.js', + '\0dep.js?commonjs-exports' + ]); + trackedTransforms.length = 0; + + modules['dep.js'] = "exports.dep = 'cjs';"; + options.cache = bundle.cache; + bundle = await rollup(options); + t.is(meta.isCommonJS, true); + t.deepEqual(await (await executeBundle(bundle, t)).exports, 'cjs'); + t.deepEqual(trackedTransforms, ['dep.js', 'main.js']); + trackedTransforms.length = 0; + resetModules(); + options.cache = bundle.cache; bundle = await rollup(options); - t.is(await getCodeFromBundle(bundle), firstCode); + t.is(meta.isCommonJS, false); + t.deepEqual(await (await executeBundle(bundle, t)).exports, 'esm'); + t.deepEqual(trackedTransforms, ['dep.js']); + trackedTransforms.length = 0; }); -test('updates mixed modules when using the cache and the wrapping of a module changes', async (t) => { +test('handles when a required dependency of a CJS module changes type', async (t) => { + const { meta, tracker, trackedTransforms } = getTransformTracker('dep.js'); const modules = {}; const resetModules = () => { - modules['main.js'] = - "export const main = 'main'; export const result = require('first.js').first;"; - modules['first.js'] = "exports.first = 'first';"; + modules['main.js'] = "module.exports = require('dep.js').dep;"; + modules['dep.js'] = "export const dep = 'esm';"; }; const options = { input: 'main.js', - plugins: [commonjs({ transformMixedEsModules: true }), loader(modules)], - onwarn(warning) { - if (warning.code !== 'CIRCULAR_DEPENDENCY') { - throw new Error(warning.message); - } - } + plugins: [commonjs(), loader(modules), tracker], + onwarn + }; + + resetModules(); + let bundle = await rollup(options); + t.is(meta.isCommonJS, false); + t.deepEqual((await executeBundle(bundle, t)).exports, 'esm'); + t.deepEqual(trackedTransforms, [ + 'dep.js', + 'main.js', + 'main.js?commonjs-entry', + '\0commonjsHelpers.js', + '\0dep.js?commonjs-proxy' + ]); + trackedTransforms.length = 0; + const esCode = await getCodeFromBundle(bundle); + t.snapshot(esCode); + + modules['dep.js'] = "exports.dep = 'cjs';"; + options.cache = bundle.cache; + bundle = await rollup(options); + t.is(meta.isCommonJS, true); + t.deepEqual((await executeBundle(bundle, t)).exports, 'cjs'); + t.deepEqual(trackedTransforms, [ + 'dep.js', + 'main.js', + '\0dep.js?commonjs-proxy', + '\0dep.js?commonjs-exports' + ]); + trackedTransforms.length = 0; + const cjsCode = await getCodeFromBundle(bundle); + t.snapshot(cjsCode); + + modules['dep.js'] = "exports.dep = 'cjs'; exports.dep += require('dep.js').dep;"; + options.cache = bundle.cache; + bundle = await rollup(options); + t.is(meta.isCommonJS, 'withRequireFunction'); + t.deepEqual((await executeBundle(bundle, t)).exports, 'cjscjs'); + t.deepEqual(trackedTransforms, ['dep.js', 'main.js']); + trackedTransforms.length = 0; + const wrappedCode = await getCodeFromBundle(bundle); + t.snapshot(wrappedCode); + + resetModules(); + options.cache = bundle.cache; + bundle = await rollup(options); + t.is(meta.isCommonJS, false); + t.deepEqual((await executeBundle(bundle, t)).exports, 'esm'); + t.deepEqual(trackedTransforms, ['dep.js', 'main.js', '\0dep.js?commonjs-proxy']); + trackedTransforms.length = 0; + t.is(await getCodeFromBundle(bundle), esCode); + + modules['dep.js'] = "exports.dep = 'cjs'; exports.dep += require('dep.js').dep;"; + options.cache = bundle.cache; + bundle = await rollup(options); + t.is(meta.isCommonJS, 'withRequireFunction'); + t.deepEqual((await executeBundle(bundle, t)).exports, 'cjscjs'); + t.deepEqual(trackedTransforms, ['dep.js', 'main.js', '\0dep.js?commonjs-exports']); + trackedTransforms.length = 0; + t.is(await getCodeFromBundle(bundle), wrappedCode); + + modules['dep.js'] = "exports.dep = 'cjs';"; + options.cache = bundle.cache; + bundle = await rollup(options); + t.is(meta.isCommonJS, true); + t.deepEqual((await executeBundle(bundle, t)).exports, 'cjs'); + t.deepEqual(trackedTransforms, ['dep.js', 'main.js', '\0dep.js?commonjs-proxy']); + trackedTransforms.length = 0; + t.is(await getCodeFromBundle(bundle), cjsCode); + + resetModules(); + options.cache = bundle.cache; + bundle = await rollup(options); + t.is(meta.isCommonJS, false); + t.deepEqual((await executeBundle(bundle, t)).exports, 'esm'); + t.deepEqual(trackedTransforms, ['dep.js', 'main.js', '\0dep.js?commonjs-proxy']); + trackedTransforms.length = 0; + t.is(await getCodeFromBundle(bundle), esCode); +}); + +test('handles when a required dependency of a mixed ES module changes type', async (t) => { + const { meta, tracker, trackedTransforms } = getTransformTracker('dep.js'); + const modules = {}; + const resetModules = () => { + modules['main.js'] = "export default require('dep.js').dep;"; + modules['dep.js'] = "export const dep = 'esm';"; + }; + const options = { + input: 'main.js', + plugins: [commonjs({ transformMixedEsModules: true }), loader(modules), tracker], + onwarn }; 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); + t.is(meta.isCommonJS, false); + t.deepEqual((await executeBundle(bundle, t)).exports, 'esm'); + t.deepEqual(trackedTransforms, [ + 'dep.js', + 'main.js', + 'main.js?commonjs-entry', + '\0commonjsHelpers.js', + '\0dep.js?commonjs-proxy' + ]); + trackedTransforms.length = 0; + const esCode = await getCodeFromBundle(bundle); + t.snapshot(esCode); + + modules['dep.js'] = "exports.dep = 'cjs';"; + options.cache = bundle.cache; + bundle = await rollup(options); + t.is(meta.isCommonJS, true); + t.deepEqual((await executeBundle(bundle, t)).exports, 'cjs'); + t.deepEqual(trackedTransforms, [ + 'dep.js', + 'main.js', + '\0dep.js?commonjs-proxy', + '\0dep.js?commonjs-exports' + ]); + trackedTransforms.length = 0; + const cjsCode = await getCodeFromBundle(bundle); + t.snapshot(cjsCode); + + modules['dep.js'] = "exports.dep = 'cjs'; exports.dep += require('dep.js').dep;"; + options.cache = bundle.cache; + bundle = await rollup(options); + t.is(meta.isCommonJS, 'withRequireFunction'); + t.deepEqual((await executeBundle(bundle, t)).exports, 'cjscjs'); + t.deepEqual(trackedTransforms, ['dep.js', 'main.js']); + trackedTransforms.length = 0; + const wrappedCode = await getCodeFromBundle(bundle); + t.snapshot(wrappedCode); + resetModules(); 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)); + t.is(meta.isCommonJS, false); + t.deepEqual((await executeBundle(bundle, t)).exports, 'esm'); + t.deepEqual(trackedTransforms, ['dep.js', 'main.js', '\0dep.js?commonjs-proxy']); + trackedTransforms.length = 0; + t.is(await getCodeFromBundle(bundle), esCode); + + modules['dep.js'] = "exports.dep = 'cjs'; exports.dep += require('dep.js').dep;"; + options.cache = bundle.cache; + bundle = await rollup(options); + t.is(meta.isCommonJS, 'withRequireFunction'); + t.deepEqual((await executeBundle(bundle, t)).exports, 'cjscjs'); + t.deepEqual(trackedTransforms, ['dep.js', 'main.js', '\0dep.js?commonjs-exports']); + trackedTransforms.length = 0; + t.is(await getCodeFromBundle(bundle), wrappedCode); + modules['dep.js'] = "exports.dep = 'cjs';"; options.cache = bundle.cache; + bundle = await rollup(options); + t.is(meta.isCommonJS, true); + t.deepEqual((await executeBundle(bundle, t)).exports, 'cjs'); + t.deepEqual(trackedTransforms, ['dep.js', 'main.js', '\0dep.js?commonjs-proxy']); + trackedTransforms.length = 0; + t.is(await getCodeFromBundle(bundle), cjsCode); + resetModules(); + options.cache = bundle.cache; bundle = await rollup(options); - t.is(await getCodeFromBundle(bundle), firstCode); + t.is(meta.isCommonJS, false); + t.deepEqual((await executeBundle(bundle, t)).exports, 'esm'); + t.deepEqual(trackedTransforms, ['dep.js', 'main.js', '\0dep.js?commonjs-proxy']); + trackedTransforms.length = 0; + t.is(await getCodeFromBundle(bundle), esCode); +}); + +test('handles ESM cycles when using the cache', async (t) => { + const modules = {}; + const resetModules = () => { + modules['main.js'] = "import 'dep.js';console.log('main');"; + modules['dep.js'] = "import 'main.js';console.log('dep');"; + }; + const options = { + input: 'main.js', + plugins: [commonjs(), loader(modules)], + onwarn + }; + + resetModules(); + let bundle = await rollup(options); + + options.cache = bundle.cache; + bundle = await rollup(options); + t.snapshot(await getCodeFromBundle(bundle)); }); test('allows the config to be reused', async (t) => { diff --git a/packages/json/src/index.js b/packages/json/src/index.js index 9767e83ca..63e37c280 100755 --- a/packages/json/src/index.js +++ b/packages/json/src/index.js @@ -8,11 +8,11 @@ export default function json(options = {}) { name: 'json', // eslint-disable-next-line no-shadow - transform(json, id) { + transform(code, id) { if (id.slice(-5) !== '.json' || !filter(id)) return null; try { - const parsed = JSON.parse(json); + const parsed = JSON.parse(code); return { code: dataToEsm(parsed, { preferConst: options.preferConst, diff --git a/packages/node-resolve/src/index.js b/packages/node-resolve/src/index.js index ddb1ffb78..8daafcffe 100644 --- a/packages/node-resolve/src/index.js +++ b/packages/node-resolve/src/index.js @@ -242,14 +242,14 @@ export function nodeResolve(opts = {}) { version, - buildStart(options) { - rollupOptions = options; + buildStart(buildOptions) { + rollupOptions = buildOptions; for (const warning of warnings) { this.warn(warning); } - ({ preserveSymlinks } = options); + ({ preserveSymlinks } = buildOptions); }, generateBundle() { diff --git a/packages/run/test/test.js b/packages/run/test/test.js index fdbc808ff..ffba8ea18 100644 --- a/packages/run/test/test.js +++ b/packages/run/test/test.js @@ -99,13 +99,13 @@ test('throws an error when bundle is not written to disk', async (t) => { test('detects changes - forks a new child process and kills older process', async (t) => { // eslint-disable-next-line no-shadow - const input = join(cwd, 'change-detect-input.js'); + const testInput = join(cwd, 'change-detect-input.js'); const bundle = await rollup({ - input, + input: testInput, plugins: [run()] }); await bundle.write(outputOptions); - await writeFile(input, "export const Greeting = () => 'Hola'; // eslint-disable-line"); + await writeFile(testInput, "export const Greeting = () => 'Hola'; // eslint-disable-line"); await bundle.write(outputOptions); t.true(mockChildProcess.calledWithExactly(outputOptions.file, [], {})); t.is(mockChildProcess().kill.callCount, 1); diff --git a/packages/typescript/test/fixtures/export-namespace-export-class/test.ts b/packages/typescript/test/fixtures/export-namespace-export-class/test.ts index 43fc12c68..6565f7c69 100644 --- a/packages/typescript/test/fixtures/export-namespace-export-class/test.ts +++ b/packages/typescript/test/fixtures/export-namespace-export-class/test.ts @@ -2,6 +2,6 @@ // test.ts export namespace MODE { - // eslint-disable-next-line no-shadow + // eslint-disable-next-line no-shadow,@typescript-eslint/no-shadow export class MODE {} } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 48bd29f8d..41304a331 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -99,18 +99,6 @@ importers: rollup: 2.67.3 typescript: 4.1.2 - packages/auto-install/test/fixtures/pnpm: - specifiers: - node-noop: ^1.0.0 - dependencies: - node-noop: 1.0.0 - - packages/auto-install/test/fixtures/pnpm-bare: - specifiers: - node-noop: ^1.0.0 - dependencies: - node-noop: 1.0.0 - packages/babel: specifiers: '@babel/core': ^7.10.5 @@ -184,13 +172,13 @@ importers: magic-string: ^0.25.7 require-relative: ^0.8.7 resolve: ^1.17.0 - rollup: ^2.67.3 + rollup: ^2.68.0 shx: ^0.3.2 source-map: ^0.7.3 source-map-support: ^0.5.19 typescript: ^3.9.7 dependencies: - '@rollup/pluginutils': 3.1.0_rollup@2.67.3 + '@rollup/pluginutils': 3.1.0_rollup@2.68.0 commondir: 1.0.1 estree-walker: 2.0.1 glob: 7.1.6 @@ -198,11 +186,11 @@ importers: magic-string: 0.25.7 resolve: 1.18.1 devDependencies: - '@rollup/plugin-json': 4.1.0_rollup@2.67.3 - '@rollup/plugin-node-resolve': 13.1.0_rollup@2.67.3 + '@rollup/plugin-json': 4.1.0_rollup@2.68.0 + '@rollup/plugin-node-resolve': 13.1.3_rollup@2.68.0 locate-character: 2.0.5 require-relative: 0.8.7 - rollup: 2.67.3 + rollup: 2.68.0 shx: 0.3.3 source-map: 0.7.3 source-map-support: 0.5.19 @@ -2166,6 +2154,15 @@ packages: rollup: 2.67.3 dev: true + /@rollup/plugin-json/4.1.0_rollup@2.68.0: + resolution: {integrity: sha512-yfLbTdNS6amI/2OpmbiBoW12vngr5NW2jCJVZSBEz+H5KfUJZ2M7sDjk0U6GOOdCWFVScShte29o9NezJ53TPw==} + peerDependencies: + rollup: ^1.20.0 || ^2.0.0 + dependencies: + '@rollup/pluginutils': 3.1.0_rollup@2.68.0 + rollup: 2.68.0 + dev: true + /@rollup/plugin-node-resolve/10.0.0_rollup@2.67.3: resolution: {integrity: sha512-sNijGta8fqzwA1VwUEtTvWCx2E7qC70NMsDh4ZG13byAXYigBNZMxALhKUSycBks5gupJdq0lFrKumFrRZ8H3A==} engines: {node: '>= 10.0.0'} @@ -2181,6 +2178,21 @@ packages: rollup: 2.67.3 dev: true + /@rollup/plugin-node-resolve/13.1.3_rollup@2.68.0: + resolution: {integrity: sha512-BdxNk+LtmElRo5d06MGY4zoepyrXX1tkzX2hrnPEZ53k78GuOMWLqmJDGIIOPwVRIFZrLQOo+Yr6KtCuLIA0AQ==} + engines: {node: '>= 10.0.0'} + peerDependencies: + rollup: ^2.42.0 + dependencies: + '@rollup/pluginutils': 3.1.0_rollup@2.68.0 + '@types/resolve': 1.17.1 + builtin-modules: 3.2.0 + deepmerge: 4.2.2 + is-module: 1.0.0 + resolve: 1.20.0 + rollup: 2.68.0 + dev: true + /@rollup/plugin-node-resolve/8.4.0_rollup@2.67.3: resolution: {integrity: sha512-LFqKdRLn0ShtQyf6SBYO69bGE1upV6wUhBX0vFOUnLAyzx5cwp8svA0eHUnu8+YU57XOkrMtfG63QOpQx25pHQ==} engines: {node: '>= 8.0.0'} @@ -2288,6 +2300,17 @@ packages: picomatch: 2.2.2 rollup: 2.67.3 + /@rollup/pluginutils/3.1.0_rollup@2.68.0: + resolution: {integrity: sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==} + engines: {node: '>= 8.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0 + dependencies: + '@types/estree': 0.0.39 + estree-walker: 1.0.1 + picomatch: 2.2.2 + rollup: 2.68.0 + /@rollup/pluginutils/4.1.2: resolution: {integrity: sha512-ROn4qvkxP9SyPeHaf7uQC/GPFY6L/OWy9+bd9AwcjOAWQwxRscoEyAUD8qCY5o5iL4jqQwoLk2kaTKJPb/HwzQ==} engines: {node: '>= 8.0.0'} @@ -6190,6 +6213,7 @@ packages: /node-noop/1.0.0: resolution: {integrity: sha1-R6Pn2Az/qmRYNkvSLthcqzMHvnk=} + dev: true /node-preload/0.2.1: resolution: {integrity: sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==} @@ -7469,6 +7493,14 @@ packages: fsevents: 2.3.2 dev: true + /rollup/2.68.0: + resolution: {integrity: sha512-XrMKOYK7oQcTio4wyTz466mucnd8LzkiZLozZ4Rz0zQD+HeX4nUK4B8GrTX/2EvN2/vBF/i2WnaXboPxo0JylA==} + engines: {node: '>=10.0.0'} + hasBin: true + optionalDependencies: + fsevents: 2.3.2 + dev: true + /run-parallel/1.1.9: resolution: {integrity: sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==} dev: true