Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle namespaces that reexport themselves #3077

Merged
merged 7 commits into from Aug 25, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1,016 changes: 627 additions & 389 deletions package-lock.json

Large diffs are not rendered by default.

16 changes: 8 additions & 8 deletions package.json
Expand Up @@ -66,17 +66,17 @@
"@types/micromatch": "^3.1.0",
"@types/minimist": "^1.2.0",
"acorn-import-meta": "^1.0.0",
"acorn-jsx": "^5.0.1",
"acorn-jsx": "^5.0.2",
"acorn-walk": "^7.0.0",
"buble": "^0.19.8",
"chokidar": "^2.1.6",
"chokidar": "^2.1.8",
"codecov": "^3.5.0",
"console-group": "^0.3.3",
"core-js": "^3.2.1",
"date-time": "^3.1.0",
"es5-shim": "^4.5.13",
"es6-shim": "^0.35.5",
"eslint": "^6.1.0",
"eslint": "^6.2.1",
"eslint-plugin-import": "^2.18.2",
"execa": "^2.0.4",
"fixturify": "^1.2.0",
Expand All @@ -87,7 +87,7 @@
"lint-staged": "^9.2.3",
"locate-character": "^2.0.5",
"magic-string": "^0.25.3",
"markdownlint-cli": "^0.17.0",
"markdownlint-cli": "^0.18.0",
"micromatch": "^4.0.2",
"minimist": "^1.2.0",
"mocha": "^6.2.0",
Expand All @@ -97,8 +97,8 @@
"pretty-ms": "^5.0.0",
"require-relative": "^0.8.7",
"requirejs": "^2.3.6",
"rollup": "^1.19.4",
"rollup-plugin-alias": "^1.5.2",
"rollup": "^1.20.1",
"rollup-plugin-alias": "^2.0.0",
"rollup-plugin-buble": "^0.19.8",
"rollup-plugin-commonjs": "^10.0.2",
"rollup-plugin-json": "^4.0.0",
Expand All @@ -116,9 +116,9 @@
"source-map-support": "^0.5.13",
"sourcemap-codec": "^1.4.6",
"systemjs": "^5.0.0",
"terser": "^4.1.4",
"terser": "^4.2.0",
"tslib": "^1.10.0",
"tslint": "^5.18.0",
"tslint": "^5.19.0",
"turbocolor": "^2.6.1",
"typescript": "^3.5.3",
"url-parse": "^1.4.7"
Expand Down
6 changes: 4 additions & 2 deletions rollup.config.js
Expand Up @@ -135,8 +135,10 @@ function fixAcornEsmImport() {

const moduleAliases = {
resolve: ['.js', '.json', '.md'],
'help.md': path.resolve('cli/help.md'),
'package.json': path.resolve('package.json')
entries: [
{ find: 'help.md', replacement: path.resolve('cli/help.md') },
{ find: 'package.json', replacement: path.resolve('package.json') }
]
};

const treeshake = {
Expand Down
8 changes: 5 additions & 3 deletions src/Module.ts
Expand Up @@ -342,9 +342,11 @@ export default class Module {
}

getOrCreateNamespace(): NamespaceVariable {
return (
this.namespaceVariable || (this.namespaceVariable = new NamespaceVariable(this.astContext))
);
if (!this.namespaceVariable) {
this.namespaceVariable = new NamespaceVariable(this.astContext);
this.namespaceVariable.initialise();
}
return this.namespaceVariable;
}

getReexports(): string[] {
Expand Down
11 changes: 7 additions & 4 deletions src/ast/variables/NamespaceVariable.ts
Expand Up @@ -19,10 +19,6 @@ export default class NamespaceVariable extends Variable {
super(context.getModuleName());
this.context = context;
this.module = context.module;
for (const name of this.context.getExports().concat(this.context.getReexports())) {
if (name[0] === '*' && name.length > 1) this.containsExternalNamespace = true;
this.memberVariables[name] = this.context.traceExport(name);
}
}

addReference(identifier: Identifier) {
Expand Down Expand Up @@ -69,6 +65,13 @@ export default class NamespaceVariable extends Variable {
}
}

initialise() {
for (const name of this.context.getExports().concat(this.context.getReexports())) {
if (name[0] === '*' && name.length > 1) this.containsExternalNamespace = true;
this.memberVariables[name] = this.context.traceExport(name);
}
}

renderBlock(options: RenderOptions) {
const _ = options.compact ? '' : ' ';
const n = options.compact ? '' : '\n';
Expand Down
13 changes: 9 additions & 4 deletions test/form/index.js
Expand Up @@ -21,10 +21,15 @@ runTestSuiteWithSamples('form', path.resolve(__dirname, 'samples'), (dir, config
extend(
{
input: dir + '/main.js',
onwarn: msg => {
if (/No name was provided for/.test(msg)) return;
if (/as external dependency/.test(msg)) return;
console.error(msg);
onwarn: warning => {
if (
!(config.expectedWarnings && config.expectedWarnings.indexOf(warning.code) >= 0)
) {
throw new Error(
`Unexpected warnings (${warning.code}): ${warning.message}\n` +
'If you expect warnings, list their codes in config.expectedWarnings'
);
}
},
strictDeprecations: true
},
Expand Down
@@ -1,3 +1,4 @@
module.exports = {
description: 'Tree-shake known object prototype functions'
description: 'Tree-shake known object prototype functions',
expectedWarnings: ['EMPTY_BUNDLE']
};
4 changes: 4 additions & 0 deletions test/form/samples/compact-multiple-imports/_config.js
Expand Up @@ -5,6 +5,10 @@ module.exports = {
return id.startsWith('external');
},
output: {
globals: {
'external-3': 'external3',
'external-4': 'external4'
},
compact: true
}
}
Expand Down
6 changes: 5 additions & 1 deletion test/form/samples/compact/_config.js
@@ -1,11 +1,15 @@
module.exports = {
description: 'compact output with compact: true',
expectedWarnings: ['CIRCULAR_DEPENDENCY'],
options: {
external: ['external'],
output: {
name: 'foo',
compact: true,
namespaceToStringTag: true
namespaceToStringTag: true,
globals: {
external: 'x'
}
}
}
};
8 changes: 7 additions & 1 deletion test/form/samples/conflicting-imports/_config.js
@@ -1,6 +1,12 @@
module.exports = {
description: 'ensures bundle imports are deconflicted (#659)',
options: {
external: ['foo', 'bar']
external: ['foo', 'bar'],
output: {
globals: {
bar: 'bar',
foo: 'foo'
}
}
}
};
@@ -1,5 +1,6 @@
module.exports = {
description: 'allows custom module-specific context with a function option',
expectedWarnings: ['THIS_IS_UNDEFINED'],
options: {
moduleContext(id) {
return /main\.js$/.test(id) ? 'lolwut' : 'undefined';
Expand Down
1 change: 1 addition & 0 deletions test/form/samples/custom-module-context/_config.js
@@ -1,5 +1,6 @@
module.exports = {
description: 'allows custom module-specific context',
expectedWarnings: ['THIS_IS_UNDEFINED'],
options: {
moduleContext: {
'main.js': 'lolwut'
Expand Down
Expand Up @@ -3,6 +3,7 @@ module.exports = {
options: {
external: 'external',
output: {
globals: { external: 'external' },
name: 'bundle'
}
}
Expand Down
1 change: 1 addition & 0 deletions test/form/samples/dedupes-external-imports/_config.js
Expand Up @@ -3,6 +3,7 @@ module.exports = {
options: {
external: ['external'],
output: {
globals: { external: 'external' },
name: 'myBundle'
}
}
Expand Down
@@ -1,8 +1,11 @@
module.exports = {
description: 'prunes pure unused external imports ([#1352])',
options: {
strictDeprecations: false,
external: ['external', 'other'],
treeshake: { pureExternalModules: ['external'] }
},
description: 'prunes pure unused external imports ([#1352])'
treeshake: { pureExternalModules: ['external'] },
output: {
globals: { other: 'other' }
}
}
};
@@ -1,8 +1,12 @@
module.exports = {
description: 'prunes pure unused external imports ([#1352])',
expectedWarnings: ['EMPTY_BUNDLE'],
options: {
strictDeprecations: false,
external: ['external', 'other'],
treeshake: { pureExternalModules: id => id === 'external' }
},
description: 'prunes pure unused external imports ([#1352])'
treeshake: { pureExternalModules: id => id === 'external' },
output: {
globals: { other: 'other' }
}
}
};
@@ -1,8 +1,9 @@
module.exports = {
description: 'prunes pure unused external imports ([#1352])',
expectedWarnings: ['EMPTY_BUNDLE'],
options: {
strictDeprecations: false,
external: ['external', 'other'],
treeshake: { pureExternalModules: true }
},
description: 'prunes pure unused external imports ([#1352])'
}
};
Expand Up @@ -2,6 +2,7 @@ const assert = require('assert');

module.exports = {
description: 'plugin .transformBundle gets passed options',
expectedWarnings: ['DEPRECATED_FEATURE'],
options: {
strictDeprecations: false,
plugins: [
Expand Down
@@ -1,10 +1,11 @@
module.exports = {
description: 'allows plugins to transform bundle',
expectedWarnings: ['DEPRECATED_FEATURE'],
options: {
strictDeprecations: false,
plugins: [
{
transformBundle(code) {
transformBundle() {
return '/* first plugin */';
}
},
Expand Down
5 changes: 4 additions & 1 deletion test/form/samples/export-all-before-named/_config.js
@@ -1,7 +1,10 @@
module.exports = {
description: 'external `export *` must not interfere with internal exports',
options: {
output: { name: 'exposedInternals' },
output: {
globals: { external: 'external' },
name: 'exposedInternals'
},
external: ['external']
}
};
5 changes: 4 additions & 1 deletion test/form/samples/export-default-import/_config.js
Expand Up @@ -2,6 +2,9 @@ module.exports = {
description: 'correctly exports a default import, even in ES mode (#513)',
options: {
external: ['x'],
output: { name: 'myBundle' }
output: {
globals: { x: 'x' },
name: 'myBundle'
}
}
};
1 change: 1 addition & 0 deletions test/form/samples/external-deshadowing/_config.js
Expand Up @@ -3,6 +3,7 @@ module.exports = {
options: {
external: ['a', 'b'],
output: {
globals: { a: 'a', b: 'b' },
name: 'myBundle'
}
}
Expand Down
2 changes: 1 addition & 1 deletion test/form/samples/external-deshadowing/_expected/iife.js
Expand Up @@ -16,4 +16,4 @@ var myBundle = (function (exports, a, Test$1) {

return exports;

}({}, a, Test$1));
}({}, a, b));
2 changes: 1 addition & 1 deletion test/form/samples/external-deshadowing/_expected/umd.js
@@ -1,7 +1,7 @@
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('a'), require('b')) :
typeof define === 'function' && define.amd ? define(['exports', 'a', 'b'], factory) :
(global = global || self, factory(global.myBundle = {}, global.a, global.Test$1));
(global = global || self, factory(global.myBundle = {}, global.a, global.b));
}(this, function (exports, a, Test$1) { 'use strict';

Test$1 = Test$1 && Test$1.hasOwnProperty('default') ? Test$1['default'] : Test$1;
Expand Down
1 change: 1 addition & 0 deletions test/form/samples/external-export-tracing/_config.js
Expand Up @@ -3,6 +3,7 @@ module.exports = {
options: {
external: ['external'],
output: {
globals: { external: 'external' },
name: 'myBundle'
}
}
Expand Down
5 changes: 4 additions & 1 deletion test/form/samples/external-import-alias-shadow/_config.js
@@ -1,6 +1,9 @@
module.exports = {
description: 'handles external aliased named imports that shadow another name',
options: {
external: ['acorn']
external: ['acorn'],
output: {
globals: { acorn: 'acorn' }
}
}
};
11 changes: 10 additions & 1 deletion test/form/samples/external-imports/_config.js
@@ -1,6 +1,15 @@
module.exports = {
description: 'prefixes global names with `global.` when creating UMD bundle (#57)',
expectedWarnings: ['UNUSED_EXTERNAL_IMPORT'],
options: {
external: ['factory', 'baz', 'shipping-port', 'alphabet']
external: ['factory', 'baz', 'shipping-port', 'alphabet'],
output: {
globals: {
alphabet: 'alphabet',
baz: 'baz',
factory: 'factory',
'shipping-port': 'containers'
}
}
}
};
5 changes: 4 additions & 1 deletion test/form/samples/external-namespace-and-named/_config.js
@@ -1,6 +1,9 @@
module.exports = {
description: 'Correctly handles external namespace tracing with both namespace and named exports',
options: {
external: ['foo']
external: ['foo'],
output: {
globals: { foo: 'foo' }
}
}
};
1 change: 1 addition & 0 deletions test/form/samples/external-namespace-reexport/_config.js
Expand Up @@ -3,6 +3,7 @@ module.exports = {
options: {
external: ['highcharts'],
output: {
globals: { highcharts: 'highcharts' },
name: 'myBundle'
}
}
Expand Down
15 changes: 15 additions & 0 deletions test/form/samples/guessed-global-names/_config.js
@@ -0,0 +1,15 @@
const { resolve } = require('path');

module.exports = {
description: 'guesses global names if necessary',
expectedWarnings: ['MISSING_GLOBAL_NAME'],
options: {
external: [
'unchanged',
'changed',
'special-character',
'with/slash',
resolve(__dirname, 'relative.js')
]
}
};
7 changes: 7 additions & 0 deletions test/form/samples/guessed-global-names/_expected/amd.js
@@ -0,0 +1,7 @@
define(['unchanged', 'changed', 'special-character', 'with/slash', './relative'], function (unchanged, changedName, specialCharacter, slash, relative_js) { 'use strict';

changedName = changedName && changedName.hasOwnProperty('default') ? changedName['default'] : changedName;

console.log(unchanged.foo, changedName, specialCharacter.bar, slash.baz, relative_js.quux);

});