From 4b0b32b65d4ec5e168e70d981dc9c49c2e1fb6cb Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Sun, 6 May 2018 19:48:01 +0200 Subject: [PATCH 1/3] add failing test for default import exportMode check --- .../samples/entry-chunk-export-mode/_config.js | 6 ++++++ .../entry-chunk-export-mode/_expected/amd/main1.js | 5 +++++ .../entry-chunk-export-mode/_expected/amd/main2.js | 9 +++++++++ .../entry-chunk-export-mode/_expected/cjs/main1.js | 5 +++++ .../entry-chunk-export-mode/_expected/cjs/main2.js | 7 +++++++ .../entry-chunk-export-mode/_expected/es/main1.js | 3 +++ .../entry-chunk-export-mode/_expected/es/main2.js | 5 +++++ .../_expected/system/main1.js | 14 ++++++++++++++ .../_expected/system/main2.js | 13 +++++++++++++ .../samples/entry-chunk-export-mode/main1.js | 4 ++++ .../samples/entry-chunk-export-mode/main2.js | 3 +++ 11 files changed, 74 insertions(+) create mode 100644 test/chunking-form/samples/entry-chunk-export-mode/_config.js create mode 100644 test/chunking-form/samples/entry-chunk-export-mode/_expected/amd/main1.js create mode 100644 test/chunking-form/samples/entry-chunk-export-mode/_expected/amd/main2.js create mode 100644 test/chunking-form/samples/entry-chunk-export-mode/_expected/cjs/main1.js create mode 100644 test/chunking-form/samples/entry-chunk-export-mode/_expected/cjs/main2.js create mode 100644 test/chunking-form/samples/entry-chunk-export-mode/_expected/es/main1.js create mode 100644 test/chunking-form/samples/entry-chunk-export-mode/_expected/es/main2.js create mode 100644 test/chunking-form/samples/entry-chunk-export-mode/_expected/system/main1.js create mode 100644 test/chunking-form/samples/entry-chunk-export-mode/_expected/system/main2.js create mode 100644 test/chunking-form/samples/entry-chunk-export-mode/main1.js create mode 100644 test/chunking-form/samples/entry-chunk-export-mode/main2.js diff --git a/test/chunking-form/samples/entry-chunk-export-mode/_config.js b/test/chunking-form/samples/entry-chunk-export-mode/_config.js new file mode 100644 index 00000000000..e1044841bf5 --- /dev/null +++ b/test/chunking-form/samples/entry-chunk-export-mode/_config.js @@ -0,0 +1,6 @@ +module.exports = { + description: 'entry chunk export mode checks', + options: { + input: ['main1.js', 'main2.js'] + } +}; diff --git a/test/chunking-form/samples/entry-chunk-export-mode/_expected/amd/main1.js b/test/chunking-form/samples/entry-chunk-export-mode/_expected/amd/main1.js new file mode 100644 index 00000000000..cb06afa3a2b --- /dev/null +++ b/test/chunking-form/samples/entry-chunk-export-mode/_expected/amd/main1.js @@ -0,0 +1,5 @@ +define(['./main2.js'], function (main2) { 'use strict'; + + main2(); + +}); diff --git a/test/chunking-form/samples/entry-chunk-export-mode/_expected/amd/main2.js b/test/chunking-form/samples/entry-chunk-export-mode/_expected/amd/main2.js new file mode 100644 index 00000000000..faf5c00a55b --- /dev/null +++ b/test/chunking-form/samples/entry-chunk-export-mode/_expected/amd/main2.js @@ -0,0 +1,9 @@ +define(function () { 'use strict'; + + function fn () { + console.log('main fn'); + } + + return fn; + +}); diff --git a/test/chunking-form/samples/entry-chunk-export-mode/_expected/cjs/main1.js b/test/chunking-form/samples/entry-chunk-export-mode/_expected/cjs/main1.js new file mode 100644 index 00000000000..549e5cc55cf --- /dev/null +++ b/test/chunking-form/samples/entry-chunk-export-mode/_expected/cjs/main1.js @@ -0,0 +1,5 @@ +'use strict'; + +var main2 = require('./main2.js'); + +main2(); diff --git a/test/chunking-form/samples/entry-chunk-export-mode/_expected/cjs/main2.js b/test/chunking-form/samples/entry-chunk-export-mode/_expected/cjs/main2.js new file mode 100644 index 00000000000..dc04e7bbf8a --- /dev/null +++ b/test/chunking-form/samples/entry-chunk-export-mode/_expected/cjs/main2.js @@ -0,0 +1,7 @@ +'use strict'; + +function fn () { + console.log('main fn'); +} + +module.exports = fn; diff --git a/test/chunking-form/samples/entry-chunk-export-mode/_expected/es/main1.js b/test/chunking-form/samples/entry-chunk-export-mode/_expected/es/main1.js new file mode 100644 index 00000000000..b177800c866 --- /dev/null +++ b/test/chunking-form/samples/entry-chunk-export-mode/_expected/es/main1.js @@ -0,0 +1,3 @@ +import fn from './main2.js'; + +fn(); diff --git a/test/chunking-form/samples/entry-chunk-export-mode/_expected/es/main2.js b/test/chunking-form/samples/entry-chunk-export-mode/_expected/es/main2.js new file mode 100644 index 00000000000..83b8044f5b7 --- /dev/null +++ b/test/chunking-form/samples/entry-chunk-export-mode/_expected/es/main2.js @@ -0,0 +1,5 @@ +function fn () { + console.log('main fn'); +} + +export default fn; diff --git a/test/chunking-form/samples/entry-chunk-export-mode/_expected/system/main1.js b/test/chunking-form/samples/entry-chunk-export-mode/_expected/system/main1.js new file mode 100644 index 00000000000..e920523e670 --- /dev/null +++ b/test/chunking-form/samples/entry-chunk-export-mode/_expected/system/main1.js @@ -0,0 +1,14 @@ +System.register(['./main2.js'], function (exports, module) { + 'use strict'; + var fn; + return { + setters: [function (module) { + fn = module.default; + }], + execute: function () { + + fn(); + + } + }; +}); diff --git a/test/chunking-form/samples/entry-chunk-export-mode/_expected/system/main2.js b/test/chunking-form/samples/entry-chunk-export-mode/_expected/system/main2.js new file mode 100644 index 00000000000..0453fcd34d3 --- /dev/null +++ b/test/chunking-form/samples/entry-chunk-export-mode/_expected/system/main2.js @@ -0,0 +1,13 @@ +System.register([], function (exports, module) { + 'use strict'; + return { + execute: function () { + + exports('default', fn); + function fn () { + console.log('main fn'); + } + + } + }; +}); diff --git a/test/chunking-form/samples/entry-chunk-export-mode/main1.js b/test/chunking-form/samples/entry-chunk-export-mode/main1.js new file mode 100644 index 00000000000..282652ca6a3 --- /dev/null +++ b/test/chunking-form/samples/entry-chunk-export-mode/main1.js @@ -0,0 +1,4 @@ +import fn from './main2.js'; + + +fn(); diff --git a/test/chunking-form/samples/entry-chunk-export-mode/main2.js b/test/chunking-form/samples/entry-chunk-export-mode/main2.js new file mode 100644 index 00000000000..cbb844c50ff --- /dev/null +++ b/test/chunking-form/samples/entry-chunk-export-mode/main2.js @@ -0,0 +1,3 @@ +export default function fn () { + console.log('main fn'); +} From c084d4a2b5d503e6f1c148d1643cb4bb17c6de9b Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Sun, 6 May 2018 21:03:35 +0200 Subject: [PATCH 2/3] handle namedExportsMode switch on entrypoint dependencies --- src/Chunk.ts | 27 +++++--- src/finalisers/amd.ts | 9 +-- src/finalisers/cjs.ts | 62 +++++++++++++------ src/finalisers/iife.ts | 21 +++++-- src/finalisers/index.ts | 3 +- src/finalisers/shared/getExportBlock.ts | 8 +-- src/finalisers/shared/getInteropBlock.ts | 4 +- src/finalisers/umd.ts | 27 +++++--- .../_expected/amd/chunk-849a022f.js | 2 +- .../_expected/amd/main1.js | 4 +- .../_expected/cjs/main1.js | 4 +- .../_expected/amd/head.js | 2 + .../_expected/amd/main1.js | 2 + .../_expected/amd/main2.js | 2 + .../_expected/cjs/head.js | 2 +- .../_expected/cjs/main1.js | 2 +- 16 files changed, 123 insertions(+), 58 deletions(-) diff --git a/src/Chunk.ts b/src/Chunk.ts index 859e8becc26..e467bb042ff 100644 --- a/src/Chunk.ts +++ b/src/Chunk.ts @@ -31,6 +31,7 @@ export interface ModuleDeclarations { export interface ModuleDeclarationDependency { id: string; + namedExportsMode: boolean; name: string; globalName: string; isChunk: boolean; @@ -83,6 +84,7 @@ function getGlobalName( export default class Chunk { hasDynamicImport: boolean = false; indentString: string = undefined; + namedExportsMode: boolean = true; usedModules: Module[] = undefined; id: string = undefined; name: string; @@ -618,10 +620,9 @@ export default class Chunk { } } - // id is left undefined for other chunks for now - // this will be populated on render dependencies.push({ - id, + id, // chunk id updated on render + namedExportsMode: true, // default mode updated on render globalName, name: dep.name, isChunk: !(dep).isExternal, @@ -799,9 +800,12 @@ export default class Chunk { }); } + const exportMode = this.isEntryModuleFacade && getExportMode(this, options); + this.namedExportsMode = exportMode !== 'default'; + this.renderedDeclarations = { dependencies: this.getChunkDependencyDeclarations(options, inputBase), - exports: this.getChunkExportDeclarations() + exports: exportMode === 'none' ? [] : this.getChunkExportDeclarations() }; timeEnd('render modules', 3); @@ -966,9 +970,6 @@ export default class Chunk { if (!this.renderedSource) throw new Error('Internal error: Chunk render called before preRender'); - // Determine export mode - 'default', 'named', 'none' - const exportMode = this.isEntryModuleFacade ? getExportMode(this, options) : 'named'; - const finalise = finalisers[options.format]; if (!finalise) { error({ @@ -984,22 +985,32 @@ export default class Chunk { for (let i = 0; i < this.dependencies.length; i++) { const dep = this.dependencies[i]; if (dep instanceof ExternalModule && !dep.renormalizeRenderPath) continue; + const renderedDependency = this.renderedDeclarations.dependencies[i]; + let depId = dep instanceof ExternalModule ? renderedDependency.id : dep.id; let relPath = this.id ? normalize(relative(dirname(this.id), depId)) : depId; if (!relPath.startsWith('../')) relPath = './' + relPath; + + if (dep instanceof Chunk) renderedDependency.namedExportsMode = dep.namedExportsMode; renderedDependency.id = relPath; } if (this.graph.dynamicImport) this.finaliseDynamicImports(); const hasImportMeta = this.orderedModules.some(module => module.hasImportMeta); + const hasExports = + this.renderedDeclarations.exports.length !== 0 || + this.renderedDeclarations.dependencies.some( + dep => dep.reexports && dep.reexports.length !== 0 + ); const magicString = finalise( this.renderedSource, { - exportMode, indentString: this.indentString, + namedExportsMode: this.namedExportsMode, + hasExports, intro: addons.intro, outro: addons.outro, dynamicImport: this.hasDynamicImport, diff --git a/src/finalisers/amd.ts b/src/finalisers/amd.ts index fe060627c41..e3e184f3a32 100644 --- a/src/finalisers/amd.ts +++ b/src/finalisers/amd.ts @@ -10,7 +10,8 @@ export default function amd( magicString: MagicStringBundle, { graph, - exportMode, + namedExportsMode, + hasExports, indentString, intro, outro, @@ -27,7 +28,7 @@ export default function amd( const deps = dependencies.map(m => `'${m.id}'`); const args = dependencies.map(m => m.name); - if (exportMode === 'named') { + if (namedExportsMode && hasExports) { args.unshift(`exports`); deps.unshift(`'exports'`); } @@ -57,9 +58,9 @@ export default function amd( if (intro) magicString.prepend(intro); - const exportBlock = getExportBlock(exports, dependencies, exportMode, options.interop); + const exportBlock = getExportBlock(exports, dependencies, namedExportsMode, options.interop); if (exportBlock) magicString.append('\n\n' + exportBlock); - if (exportMode === 'named' && options.legacy !== true && isEntryModuleFacade) + if (namedExportsMode && hasExports && options.legacy !== true && isEntryModuleFacade) magicString.append(`\n\n${esModuleExport}`); if (outro) magicString.append(outro); diff --git a/src/finalisers/cjs.ts b/src/finalisers/cjs.ts index 95595b42da6..658d2aa7e03 100644 --- a/src/finalisers/cjs.ts +++ b/src/finalisers/cjs.ts @@ -6,12 +6,21 @@ import { FinaliserOptions } from './index'; export default function cjs( magicString: MagicStringBundle, - { graph, isEntryModuleFacade, exportMode, intro, outro, dependencies, exports }: FinaliserOptions, + { + graph, + isEntryModuleFacade, + namedExportsMode, + hasExports, + intro, + outro, + dependencies, + exports + }: FinaliserOptions, options: OutputOptions ) { intro = (options.strict === false ? intro : `'use strict';\n\n${intro}`) + - (exportMode === 'named' && options.legacy !== true && isEntryModuleFacade + (namedExportsMode && hasExports && options.legacy !== true && isEntryModuleFacade ? `${esModuleExport}\n\n` : ''); @@ -21,26 +30,41 @@ export default function cjs( const interop = options.interop !== false; const importBlock = dependencies - .map(({ id, isChunk, name, reexports, imports, exportsNames, exportsDefault }) => { - if (!reexports && !imports) { - return `require('${id}');`; - } + .map( + ({ + id, + namedExportsMode, + isChunk, + name, + reexports, + imports, + exportsNames, + exportsDefault + }) => { + if (!reexports && !imports) { + return `require('${id}');`; + } - if (!interop || isChunk || !exportsDefault) { - return `${varOrConst} ${name} = require('${id}');`; - } + if (!namedExportsMode) { + return `${varOrConst} ${name} = { default: require('${id}') };`; + } - needsInterop = true; + if (!interop || isChunk || !exportsDefault) { + return `${varOrConst} ${name} = require('${id}');`; + } - if (exportsNames) { - return ( - `${varOrConst} ${name} = require('${id}');` + - `\n${varOrConst} ${name}__default = _interopDefault(${name});` - ); - } + needsInterop = true; + + if (exportsNames) { + return ( + `${varOrConst} ${name} = require('${id}');` + + `\n${varOrConst} ${name}__default = _interopDefault(${name});` + ); + } - return `${varOrConst} ${name} = _interopDefault(require('${id}'));`; - }) + return `${varOrConst} ${name} = _interopDefault(require('${id}'));`; + } + ) .join('\n'); if (needsInterop) { @@ -54,7 +78,7 @@ export default function cjs( const exportBlock = getExportBlock( exports, dependencies, - exportMode, + namedExportsMode, options.interop, 'module.exports =' ); diff --git a/src/finalisers/iife.ts b/src/finalisers/iife.ts index d14bff43814..9fd50464481 100644 --- a/src/finalisers/iife.ts +++ b/src/finalisers/iife.ts @@ -14,7 +14,16 @@ const thisProp = (name: string) => `this${keypath(name)}`; export default function iife( magicString: MagicStringBundle, - { graph, exportMode, indentString, intro, outro, dependencies, exports }: FinaliserOptions, + { + graph, + namedExportsMode, + hasExports, + indentString, + intro, + outro, + dependencies, + exports + }: FinaliserOptions, options: OutputOptions ) { const { extend, name } = options; @@ -34,7 +43,7 @@ export default function iife( const deps = external.map(dep => dep.globalName || 'null'); const args = external.map(m => m.name); - if (exportMode !== 'none' && !name) { + if (hasExports && !name) { error({ code: 'INVALID_OPTION', message: `You must supply output.name for IIFE bundles` @@ -44,7 +53,7 @@ export default function iife( if (extend) { deps.unshift(`(${thisProp(name)} = ${thisProp(name)} || {})`); args.unshift('exports'); - } else if (exportMode === 'named') { + } else if (namedExportsMode && hasExports) { deps.unshift('{}'); args.unshift('exports'); } @@ -53,7 +62,7 @@ export default function iife( let wrapperIntro = `(function (${args}) {\n${useStrict}`; - if (exportMode !== 'none' && !extend) { + if (hasExports && !extend) { wrapperIntro = (isNamespaced ? thisProp(name) : `${graph.varOrConst} ${name}`) + ` = ${wrapperIntro}`; } @@ -64,7 +73,7 @@ export default function iife( let wrapperOutro = `\n\n}(${deps}));`; - if (!extend && exportMode === 'named') { + if (!extend && namedExportsMode && hasExports) { wrapperOutro = `\n\n${indentString}return exports;${wrapperOutro}`; } @@ -74,7 +83,7 @@ export default function iife( if (intro) magicString.prepend(intro); - const exportBlock = getExportBlock(exports, dependencies, exportMode, options.interop); + const exportBlock = getExportBlock(exports, dependencies, namedExportsMode, options.interop); if (exportBlock) magicString.append('\n\n' + exportBlock); if (outro) magicString.append(outro); diff --git a/src/finalisers/index.ts b/src/finalisers/index.ts index 86adaf6bb29..999f29f351d 100644 --- a/src/finalisers/index.ts +++ b/src/finalisers/index.ts @@ -10,8 +10,9 @@ import { OutputOptions } from '../rollup/types'; import Graph from '../Graph'; export interface FinaliserOptions { - exportMode: string; indentString: string; + namedExportsMode: boolean; + hasExports: boolean; intro: string; outro: string; dynamicImport: boolean; diff --git a/src/finalisers/shared/getExportBlock.ts b/src/finalisers/shared/getExportBlock.ts index 07dd3bbbdc6..b0e2daac41b 100644 --- a/src/finalisers/shared/getExportBlock.ts +++ b/src/finalisers/shared/getExportBlock.ts @@ -3,11 +3,11 @@ import { ChunkExports, ChunkDependencies } from '../../Chunk'; export default function getExportBlock( exports: ChunkExports, dependencies: ChunkDependencies, - exportMode: string, + namedExportsMode: boolean, interop: boolean, mechanism = 'return' ) { - if (exportMode === 'default') { + if (!namedExportsMode) { let local; exports.some(expt => { if (expt.exported === 'default') { @@ -36,7 +36,7 @@ export default function getExportBlock( // star exports must always output first for precedence dependencies.forEach(({ name, reexports }) => { - if (reexports && exportMode !== 'default') { + if (reexports && namedExportsMode) { reexports.forEach(specifier => { if (specifier.reexported === '*') { exportBlock += `${ @@ -48,7 +48,7 @@ export default function getExportBlock( }); dependencies.forEach(({ name, imports, reexports, isChunk }) => { - if (reexports && exportMode !== 'default') { + if (reexports && namedExportsMode) { reexports.forEach(specifier => { if (specifier.imported === 'default' && !isChunk) { const exportsNamesOrNamespace = diff --git a/src/finalisers/shared/getInteropBlock.ts b/src/finalisers/shared/getInteropBlock.ts index b9b4d5818d6..d5fea521297 100644 --- a/src/finalisers/shared/getInteropBlock.ts +++ b/src/finalisers/shared/getInteropBlock.ts @@ -7,7 +7,9 @@ export default function getInteropBlock( varOrConst: string ) { return dependencies - .map(({ name, exportsNames, exportsDefault }) => { + .map(({ name, exportsNames, exportsDefault, namedExportsMode }) => { + if (!namedExportsMode) return `${name} = { default: ${name} };`; + if (!exportsDefault || options.interop === false) return null; if (exportsNames) diff --git a/src/finalisers/umd.ts b/src/finalisers/umd.ts index 0b4d161843f..05561032316 100644 --- a/src/finalisers/umd.ts +++ b/src/finalisers/umd.ts @@ -26,10 +26,19 @@ const wrapperOutro = '\n\n})));'; export default function umd( magicString: MagicStringBundle, - { graph, exportMode, indentString, intro, outro, dependencies, exports }: FinaliserOptions, + { + graph, + namedExportsMode, + hasExports, + indentString, + intro, + outro, + dependencies, + exports + }: FinaliserOptions, options: OutputOptions ) { - if (exportMode !== 'none' && !options.name) { + if (hasExports && !options.name) { error({ code: 'INVALID_OPTION', message: 'You must supply output.name for UMD bundles' @@ -45,7 +54,7 @@ export default function umd( const globalDeps = trimmed.map(module => globalProp(module.globalName)); const args = trimmed.map(m => m.name); - if (exportMode === 'named') { + if (namedExportsMode && hasExports) { amdDeps.unshift(`'exports'`); cjsDeps.unshift(`exports`); globalDeps.unshift( @@ -65,9 +74,9 @@ export default function umd( const define = amdOptions.define || 'define'; - const cjsExport = exportMode === 'default' ? `module.exports = ` : ``; + const cjsExport = !namedExportsMode && hasExports ? `module.exports = ` : ``; const defaultExport = - exportMode === 'default' + !namedExportsMode && hasExports ? `${setupNamespace(options.name, 'global', true, options.globals)} = ` : ''; @@ -78,9 +87,9 @@ export default function umd( if (options.noConflict === true) { let factory; - if (exportMode === 'default') { + if (!namedExportsMode && hasExports) { factory = `var exports = factory(${globalDeps});`; - } else if (exportMode === 'named') { + } else if (namedExportsMode) { const module = globalDeps.shift(); factory = `var exports = ${module}; factory(${['exports'].concat(globalDeps)});`; @@ -113,9 +122,9 @@ export default function umd( if (intro) magicString.prepend(intro); - const exportBlock = getExportBlock(exports, dependencies, exportMode, options.interop); + const exportBlock = getExportBlock(exports, dependencies, namedExportsMode, options.interop); if (exportBlock) magicString.append('\n\n' + exportBlock); - if (exportMode === 'named' && options.legacy !== true) + if (namedExportsMode && hasExports && options.legacy !== true) magicString.append(`\n\n${esModuleExport}`); if (outro) magicString.append(outro); diff --git a/test/chunking-form/samples/chunking-reexport/_expected/amd/chunk-849a022f.js b/test/chunking-form/samples/chunking-reexport/_expected/amd/chunk-849a022f.js index 65fb5ac5f6d..f906bb861ce 100644 --- a/test/chunking-form/samples/chunking-reexport/_expected/amd/chunk-849a022f.js +++ b/test/chunking-form/samples/chunking-reexport/_expected/amd/chunk-849a022f.js @@ -1,4 +1,4 @@ -define(['exports', 'external'], function (exports, external) { 'use strict'; +define(['external'], function (external) { 'use strict'; console.log('dep'); diff --git a/test/chunking-form/samples/entry-chunk-export-mode/_expected/amd/main1.js b/test/chunking-form/samples/entry-chunk-export-mode/_expected/amd/main1.js index cb06afa3a2b..936380fe4e2 100644 --- a/test/chunking-form/samples/entry-chunk-export-mode/_expected/amd/main1.js +++ b/test/chunking-form/samples/entry-chunk-export-mode/_expected/amd/main1.js @@ -1,5 +1,7 @@ define(['./main2.js'], function (main2) { 'use strict'; - main2(); + main2 = { default: main2 }; + + main2.default(); }); diff --git a/test/chunking-form/samples/entry-chunk-export-mode/_expected/cjs/main1.js b/test/chunking-form/samples/entry-chunk-export-mode/_expected/cjs/main1.js index 549e5cc55cf..07c7f0c4665 100644 --- a/test/chunking-form/samples/entry-chunk-export-mode/_expected/cjs/main1.js +++ b/test/chunking-form/samples/entry-chunk-export-mode/_expected/cjs/main1.js @@ -1,5 +1,5 @@ 'use strict'; -var main2 = require('./main2.js'); +var main2 = { default: require('./main2.js') }; -main2(); +main2.default(); diff --git a/test/chunking-form/samples/import-variable-duplicates/_expected/amd/head.js b/test/chunking-form/samples/import-variable-duplicates/_expected/amd/head.js index 137120ec451..457888df18b 100644 --- a/test/chunking-form/samples/import-variable-duplicates/_expected/amd/head.js +++ b/test/chunking-form/samples/import-variable-duplicates/_expected/amd/head.js @@ -1,5 +1,7 @@ define(['./first.js'], function (first) { 'use strict'; + first = { default: first }; + return first.default; diff --git a/test/chunking-form/samples/import-variable-duplicates/_expected/amd/main1.js b/test/chunking-form/samples/import-variable-duplicates/_expected/amd/main1.js index b863673066b..442dc3bef62 100644 --- a/test/chunking-form/samples/import-variable-duplicates/_expected/amd/main1.js +++ b/test/chunking-form/samples/import-variable-duplicates/_expected/amd/main1.js @@ -1,5 +1,7 @@ define(['./first.js'], function (first) { 'use strict'; + first = { default: first }; + console.log(first.default); console.log(first.default); diff --git a/test/chunking-form/samples/import-variable-duplicates/_expected/amd/main2.js b/test/chunking-form/samples/import-variable-duplicates/_expected/amd/main2.js index 7ad9926838b..52f7cbc688f 100644 --- a/test/chunking-form/samples/import-variable-duplicates/_expected/amd/main2.js +++ b/test/chunking-form/samples/import-variable-duplicates/_expected/amd/main2.js @@ -1,5 +1,7 @@ define(['./first.js'], function (first) { 'use strict'; + first = { default: first }; + }); diff --git a/test/chunking-form/samples/import-variable-duplicates/_expected/cjs/head.js b/test/chunking-form/samples/import-variable-duplicates/_expected/cjs/head.js index d669d5f58a2..92a7ebcc74c 100644 --- a/test/chunking-form/samples/import-variable-duplicates/_expected/cjs/head.js +++ b/test/chunking-form/samples/import-variable-duplicates/_expected/cjs/head.js @@ -1,6 +1,6 @@ 'use strict'; -var first = require('./first.js'); +var first = { default: require('./first.js') }; diff --git a/test/chunking-form/samples/import-variable-duplicates/_expected/cjs/main1.js b/test/chunking-form/samples/import-variable-duplicates/_expected/cjs/main1.js index cb061de6f45..b7b3e412502 100644 --- a/test/chunking-form/samples/import-variable-duplicates/_expected/cjs/main1.js +++ b/test/chunking-form/samples/import-variable-duplicates/_expected/cjs/main1.js @@ -1,6 +1,6 @@ 'use strict'; -var first = require('./first.js'); +var first = { default: require('./first.js') }; console.log(first.default); console.log(first.default); From 32913d0cc21352860d1e5b7a612d60d711ef8cf7 Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Mon, 14 May 2018 18:13:04 +0200 Subject: [PATCH 3/3] early exportMode detection, remove default indirection --- src/Chunk.ts | 16 +++++++--------- src/finalisers/cjs.ts | 6 +----- src/finalisers/shared/getExportBlock.ts | 2 +- src/finalisers/shared/getInteropBlock.ts | 2 +- src/rollup/index.ts | 9 ++++++--- .../_expected/amd/main1.js | 4 +--- .../_expected/cjs/main1.js | 4 ++-- .../_expected/amd/head.js | 4 +--- .../_expected/amd/main1.js | 6 ++---- .../_expected/amd/main2.js | 2 -- .../_expected/cjs/head.js | 4 ++-- .../_expected/cjs/main1.js | 6 +++--- 12 files changed, 27 insertions(+), 38 deletions(-) diff --git a/src/Chunk.ts b/src/Chunk.ts index e467bb042ff..b2f823f9142 100644 --- a/src/Chunk.ts +++ b/src/Chunk.ts @@ -2,7 +2,6 @@ import { timeEnd, timeStart } from './utils/timers'; import MagicString, { Bundle as MagicStringBundle, SourceMap } from 'magic-string'; import Module from './Module'; import finalisers from './finalisers/index'; -import getExportMode from './utils/getExportMode'; import getIndentString from './utils/getIndentString'; import transformBundle from './utils/transformBundle'; import collapseSourcemaps from './utils/collapseSourcemaps'; @@ -84,7 +83,7 @@ function getGlobalName( export default class Chunk { hasDynamicImport: boolean = false; indentString: string = undefined; - namedExportsMode: boolean = true; + exportMode: string = 'named'; usedModules: Module[] = undefined; id: string = undefined; name: string; @@ -505,7 +504,9 @@ export default class Chunk { safeName = getSafeName(variable.name); toDeshadow.add(safeName); } else { - safeName = `${(module).chunk.name}.${module.chunk.getVariableExportName(variable)}`; + const chunk = (module).chunk; + if (chunk.exportMode === 'default') safeName = chunk.name; + else safeName = `${chunk.name}.${module.chunk.getVariableExportName(variable)}`; } if (safeName) variable.setSafeName(safeName); }); @@ -800,12 +801,9 @@ export default class Chunk { }); } - const exportMode = this.isEntryModuleFacade && getExportMode(this, options); - this.namedExportsMode = exportMode !== 'default'; - this.renderedDeclarations = { dependencies: this.getChunkDependencyDeclarations(options, inputBase), - exports: exportMode === 'none' ? [] : this.getChunkExportDeclarations() + exports: this.exportMode === 'none' ? [] : this.getChunkExportDeclarations() }; timeEnd('render modules', 3); @@ -992,7 +990,7 @@ export default class Chunk { let relPath = this.id ? normalize(relative(dirname(this.id), depId)) : depId; if (!relPath.startsWith('../')) relPath = './' + relPath; - if (dep instanceof Chunk) renderedDependency.namedExportsMode = dep.namedExportsMode; + if (dep instanceof Chunk) renderedDependency.namedExportsMode = dep.exportMode !== 'default'; renderedDependency.id = relPath; } @@ -1009,7 +1007,7 @@ export default class Chunk { this.renderedSource, { indentString: this.indentString, - namedExportsMode: this.namedExportsMode, + namedExportsMode: this.exportMode !== 'default', hasExports, intro: addons.intro, outro: addons.outro, diff --git a/src/finalisers/cjs.ts b/src/finalisers/cjs.ts index 658d2aa7e03..a11072478a5 100644 --- a/src/finalisers/cjs.ts +++ b/src/finalisers/cjs.ts @@ -45,11 +45,7 @@ export default function cjs( return `require('${id}');`; } - if (!namedExportsMode) { - return `${varOrConst} ${name} = { default: require('${id}') };`; - } - - if (!interop || isChunk || !exportsDefault) { + if (!interop || isChunk || !exportsDefault || !namedExportsMode) { return `${varOrConst} ${name} = require('${id}');`; } diff --git a/src/finalisers/shared/getExportBlock.ts b/src/finalisers/shared/getExportBlock.ts index b0e2daac41b..68de34c6d63 100644 --- a/src/finalisers/shared/getExportBlock.ts +++ b/src/finalisers/shared/getExportBlock.ts @@ -22,7 +22,7 @@ export default function getExportBlock( if (!dep.reexports) return false; return dep.reexports.some(expt => { if (expt.reexported === 'default') { - local = `${dep.name}.${expt.imported}`; + local = dep.namedExportsMode ? `${dep.name}.${expt.imported}` : dep.name; return true; } return false; diff --git a/src/finalisers/shared/getInteropBlock.ts b/src/finalisers/shared/getInteropBlock.ts index d5fea521297..9ccdaa673eb 100644 --- a/src/finalisers/shared/getInteropBlock.ts +++ b/src/finalisers/shared/getInteropBlock.ts @@ -8,7 +8,7 @@ export default function getInteropBlock( ) { return dependencies .map(({ name, exportsNames, exportsDefault, namedExportsMode }) => { - if (!namedExportsMode) return `${name} = { default: ${name} };`; + if (!namedExportsMode) return; if (!exportsDefault || options.interop === false) return null; diff --git a/src/rollup/index.ts b/src/rollup/index.ts index b00c1a74140..6f2784df319 100644 --- a/src/rollup/index.ts +++ b/src/rollup/index.ts @@ -21,6 +21,7 @@ import { Plugin, ModuleJSON } from './types'; +import getExportMode from '../utils/getExportMode'; export const VERSION = '<@VERSION@>'; @@ -169,6 +170,7 @@ export default function rollup( .then(addons => { chunk.generateInternalExports(outputOptions); const inputBase = dirname(resolve(inputOptions.input)); + chunk.exportMode = getExportMode(chunk, outputOptions); chunk.preRender(outputOptions, inputBase); chunk.id = basename(inputOptions.input); return chunk.render(outputOptions, addons); @@ -336,10 +338,11 @@ export default function rollup( return ( Promise.resolve() .then(() => { - if (!inputOptions.experimentalPreserveModules) { - for (let chunk of chunks) { + for (let chunk of chunks) { + if (!inputOptions.experimentalPreserveModules) chunk.generateInternalExports(outputOptions); - } + if (chunk.isEntryModuleFacade) + chunk.exportMode = getExportMode(chunk, outputOptions); } for (let chunk of chunks) { chunk.preRender(outputOptions, inputBase); diff --git a/test/chunking-form/samples/entry-chunk-export-mode/_expected/amd/main1.js b/test/chunking-form/samples/entry-chunk-export-mode/_expected/amd/main1.js index 936380fe4e2..cb06afa3a2b 100644 --- a/test/chunking-form/samples/entry-chunk-export-mode/_expected/amd/main1.js +++ b/test/chunking-form/samples/entry-chunk-export-mode/_expected/amd/main1.js @@ -1,7 +1,5 @@ define(['./main2.js'], function (main2) { 'use strict'; - main2 = { default: main2 }; - - main2.default(); + main2(); }); diff --git a/test/chunking-form/samples/entry-chunk-export-mode/_expected/cjs/main1.js b/test/chunking-form/samples/entry-chunk-export-mode/_expected/cjs/main1.js index 07c7f0c4665..549e5cc55cf 100644 --- a/test/chunking-form/samples/entry-chunk-export-mode/_expected/cjs/main1.js +++ b/test/chunking-form/samples/entry-chunk-export-mode/_expected/cjs/main1.js @@ -1,5 +1,5 @@ 'use strict'; -var main2 = { default: require('./main2.js') }; +var main2 = require('./main2.js'); -main2.default(); +main2(); diff --git a/test/chunking-form/samples/import-variable-duplicates/_expected/amd/head.js b/test/chunking-form/samples/import-variable-duplicates/_expected/amd/head.js index 457888df18b..17ef0fc0c25 100644 --- a/test/chunking-form/samples/import-variable-duplicates/_expected/amd/head.js +++ b/test/chunking-form/samples/import-variable-duplicates/_expected/amd/head.js @@ -1,9 +1,7 @@ define(['./first.js'], function (first) { 'use strict'; - first = { default: first }; - - return first.default; + return first; }); diff --git a/test/chunking-form/samples/import-variable-duplicates/_expected/amd/main1.js b/test/chunking-form/samples/import-variable-duplicates/_expected/amd/main1.js index 442dc3bef62..ffbe8de995b 100644 --- a/test/chunking-form/samples/import-variable-duplicates/_expected/amd/main1.js +++ b/test/chunking-form/samples/import-variable-duplicates/_expected/amd/main1.js @@ -1,8 +1,6 @@ define(['./first.js'], function (first) { 'use strict'; - first = { default: first }; - - console.log(first.default); - console.log(first.default); + console.log(first); + console.log(first); }); diff --git a/test/chunking-form/samples/import-variable-duplicates/_expected/amd/main2.js b/test/chunking-form/samples/import-variable-duplicates/_expected/amd/main2.js index 52f7cbc688f..7ad9926838b 100644 --- a/test/chunking-form/samples/import-variable-duplicates/_expected/amd/main2.js +++ b/test/chunking-form/samples/import-variable-duplicates/_expected/amd/main2.js @@ -1,7 +1,5 @@ define(['./first.js'], function (first) { 'use strict'; - first = { default: first }; - }); diff --git a/test/chunking-form/samples/import-variable-duplicates/_expected/cjs/head.js b/test/chunking-form/samples/import-variable-duplicates/_expected/cjs/head.js index 92a7ebcc74c..9c138ca6d30 100644 --- a/test/chunking-form/samples/import-variable-duplicates/_expected/cjs/head.js +++ b/test/chunking-form/samples/import-variable-duplicates/_expected/cjs/head.js @@ -1,7 +1,7 @@ 'use strict'; -var first = { default: require('./first.js') }; +var first = require('./first.js'); -module.exports = first.default; +module.exports = first; diff --git a/test/chunking-form/samples/import-variable-duplicates/_expected/cjs/main1.js b/test/chunking-form/samples/import-variable-duplicates/_expected/cjs/main1.js index b7b3e412502..f7881b5d294 100644 --- a/test/chunking-form/samples/import-variable-duplicates/_expected/cjs/main1.js +++ b/test/chunking-form/samples/import-variable-duplicates/_expected/cjs/main1.js @@ -1,6 +1,6 @@ 'use strict'; -var first = { default: require('./first.js') }; +var first = require('./first.js'); -console.log(first.default); -console.log(first.default); +console.log(first); +console.log(first);