Skip to content
Permalink
Browse files
handle namedExportsMode switch on entrypoint dependencies
  • Loading branch information
guybedford authored and lukastaegert committed May 15, 2018
1 parent 4b0b32b commit c084d4a2b5d503e6f1c148d1643cb4bb17c6de9b
Showing 16 changed files with 123 additions and 58 deletions.
@@ -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: !(<ExternalModule>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,
@@ -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);

@@ -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 ='
);
@@ -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);

@@ -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;
@@ -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 =
@@ -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)
@@ -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);

@@ -1,4 +1,4 @@
define(['exports', 'external'], function (exports, external) { 'use strict';
define(['external'], function (external) { 'use strict';

console.log('dep');

0 comments on commit c084d4a

Please sign in to comment.