Skip to content

Commit

Permalink
feat: add dynamicImportFunction option
Browse files Browse the repository at this point in the history
This option allows users of `es` format to rename the `import()`
function, which right now has mixed support in browsers. By allowing
this function to be renamed we can have polyfills (which cannot use the
reserved `import` keyword but could go by a different name like
`importModule`).
  • Loading branch information
keithamus committed Feb 26, 2019
1 parent c8380cd commit 9a17e68
Show file tree
Hide file tree
Showing 13 changed files with 54 additions and 10 deletions.
3 changes: 2 additions & 1 deletion src/Chunk.ts
Expand Up @@ -659,7 +659,8 @@ export default class Chunk {
freeze: options.freeze !== false,
indent: this.indentString,
namespaceToStringTag: options.namespaceToStringTag === true,
varOrConst: options.preferConst ? 'const' : 'var'
varOrConst: options.preferConst ? 'const' : 'var',
dynamicImportFunction: options.dynamicImportFunction || 'import'
};

// Make sure the direct dependencies of a chunk are present to maintain execution order
Expand Down
19 changes: 12 additions & 7 deletions src/ast/nodes/Import.ts
Expand Up @@ -11,10 +11,10 @@ interface DynamicImportMechanism {
interopRight?: string;
}

const getDynamicImportMechanism = (format: string, compact: boolean): DynamicImportMechanism => {
switch (format) {
const getDynamicImportMechanism = (options: RenderOptions): DynamicImportMechanism => {
switch (options.format) {
case 'cjs': {
const _ = compact ? '' : ' ';
const _ = options.compact ? '' : ' ';
return {
left: 'Promise.resolve(require(',
right: '))',
Expand All @@ -23,9 +23,9 @@ const getDynamicImportMechanism = (format: string, compact: boolean): DynamicImp
};
}
case 'amd': {
const _ = compact ? '' : ' ';
const resolve = compact ? 'c' : 'resolve';
const reject = compact ? 'e' : 'reject';
const _ = options.compact ? '' : ' ';
const resolve = options.compact ? 'c' : 'resolve';
const reject = options.compact ? 'e' : 'reject';
return {
left: `new Promise(function${_}(${resolve},${_}${reject})${_}{${_}require([`,
right: `],${_}${resolve},${_}${reject})${_}})`,
Expand All @@ -38,6 +38,11 @@ const getDynamicImportMechanism = (format: string, compact: boolean): DynamicImp
left: 'module.import(',
right: ')'
};
case 'es':
return {
left: `${options.dynamicImportFunction}(`,
right: ')'
};
}
};

Expand Down Expand Up @@ -78,7 +83,7 @@ export default class Import extends NodeBase {
return;
}

const importMechanism = getDynamicImportMechanism(options.format, options.compact);
const importMechanism = getDynamicImportMechanism(options);
if (importMechanism) {
const leftMechanism =
(this.resolutionInterop && importMechanism.interopLeft) || importMechanism.left;
Expand Down
1 change: 1 addition & 0 deletions src/rollup/types.d.ts
Expand Up @@ -321,6 +321,7 @@ export interface OutputOptions {
sourcemapFile?: string;
sourcemapPathTransform?: (sourcePath: string) => string;
strict?: boolean;
dynamicImportFunction?: string;
}

export type WarningHandler = (warning: string | RollupWarning) => void;
Expand Down
3 changes: 2 additions & 1 deletion src/utils/mergeOptions.ts
Expand Up @@ -260,6 +260,7 @@ function getOutputOptions(
sourcemapExcludeSources: getOption('sourcemapExcludeSources'),
sourcemapFile: getOption('sourcemapFile'),
sourcemapPathTransform: getOption('sourcemapPathTransform'),
strict: getOption('strict', true)
strict: getOption('strict', true),
dynamicImportFunction: getOption('dynamicImportFunction', 'import')
};
}
1 change: 1 addition & 0 deletions src/utils/renderHelpers.ts
Expand Up @@ -9,6 +9,7 @@ export interface RenderOptions {
indent: string;
namespaceToStringTag: boolean;
varOrConst: 'var' | 'const';
dynamicImportFunction: string;
}

export interface NodeRenderOptions {
Expand Down
14 changes: 14 additions & 0 deletions test/chunking-form/samples/dynamic-import-name/_config.js
@@ -0,0 +1,14 @@
module.exports = {
description: 'marks dynamic imports as external when resolveDynamicImport returns false',
options: {
input: 'main.js',
plugins: {
resolveDynamicImport(specifier) {
return false;
}
},
output: {
dynamicImportFunction: 'foobar'
}
}
};
@@ -0,0 +1,5 @@
define(['require'], function (require) { 'use strict';

new Promise(function (resolve, reject) { require(['./foo.js'], resolve, reject) });

});
@@ -0,0 +1,3 @@
'use strict';

Promise.resolve(require('./foo.js'));
@@ -0,0 +1 @@
foobar('./foo.js');
@@ -0,0 +1,10 @@
System.register([], function (exports, module) {
'use strict';
return {
execute: function () {

module.import('./foo.js');

}
};
});
1 change: 1 addition & 0 deletions test/chunking-form/samples/dynamic-import-name/foo.js
@@ -0,0 +1 @@
console.log('foo');
1 change: 1 addition & 0 deletions test/chunking-form/samples/dynamic-import-name/main.js
@@ -0,0 +1 @@
import('./foo.js');
2 changes: 1 addition & 1 deletion test/misc/optionList.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 9a17e68

Please sign in to comment.