Skip to content

Commit

Permalink
Make sure default exports snapshot synthetic named exports (#3946)
Browse files Browse the repository at this point in the history
  • Loading branch information
lukastaegert committed Feb 1, 2021
1 parent 683cc6a commit bab3d3d
Show file tree
Hide file tree
Showing 15 changed files with 47 additions and 19 deletions.
2 changes: 1 addition & 1 deletion src/Module.ts
Expand Up @@ -199,7 +199,7 @@ function getAndExtendSideEffectModules(variable: Variable, module: Module): Set<
if (!currentVariable || referencedVariables.has(currentVariable)) {
break;
}
referencedVariables.add(variable);
referencedVariables.add(currentVariable);
sideEffectModules.add(importingModule);
const originalSideEffects = importingModule.sideEffectDependenciesByVariable.get(
currentVariable
Expand Down
4 changes: 3 additions & 1 deletion src/ast/variables/ExportDefaultVariable.ts
Expand Up @@ -55,7 +55,9 @@ export default class ExportDefaultVariable extends LocalVariable {
(this.hasId ||
!(
this.originalId.variable.isReassigned ||
this.originalId.variable instanceof UndefinedVariable
this.originalId.variable instanceof UndefinedVariable ||
// this avoids a circular dependency
'syntheticNamespace' in this.originalId.variable
))
? this.originalId.variable
: null;
Expand Down
11 changes: 0 additions & 11 deletions src/ast/variables/SyntheticNamedExportVariable.ts
@@ -1,5 +1,4 @@
import Module, { AstContext } from '../../Module';
import { error, errSyntheticNamedExportsNeedNamespaceExport } from '../../utils/error';
import { RESERVED_NAMES } from '../../utils/reservedNames';
import ExportDefaultVariable from './ExportDefaultVariable';
import Variable from './Variable';
Expand All @@ -21,12 +20,10 @@ export default class SyntheticNamedExportVariable extends Variable {
getBaseVariable(): Variable {
if (this.baseVariable) return this.baseVariable;
let baseVariable = this.syntheticNamespace;
const checkedVariables = new Set<Variable>();
while (
baseVariable instanceof ExportDefaultVariable ||
baseVariable instanceof SyntheticNamedExportVariable
) {
checkedVariables.add(baseVariable);
if (baseVariable instanceof ExportDefaultVariable) {
const original = baseVariable.getOriginalVariable();
if (original === baseVariable) break;
Expand All @@ -35,14 +32,6 @@ export default class SyntheticNamedExportVariable extends Variable {
if (baseVariable instanceof SyntheticNamedExportVariable) {
baseVariable = baseVariable.syntheticNamespace;
}
if (checkedVariables.has(baseVariable)) {
return error(
errSyntheticNamedExportsNeedNamespaceExport(
this.module.id,
this.module.info.syntheticNamedExports
)
);
}
}
return (this.baseVariable = baseVariable);
}
Expand Down
@@ -1,3 +1,3 @@
import { named } from './lib-reexport2.js';
console.log('side-effect', named);
export default named;
export { named as default };
@@ -1,3 +1,3 @@
import { named } from './lib.js';
console.log('side-effect', named);
export default named;
export { named as default };
Expand Up @@ -12,9 +12,10 @@ module.exports = {
}
]
},
generateError: {
error: {
code: 'SYNTHETIC_NAMED_EXPORTS_NEED_NAMESPACE_EXPORT',
id: path.join(__dirname, 'main.js'),
message: `Module "main.js" that is marked with 'syntheticNamedExports: "__synthetic"' needs an export named "__synthetic" that does not reexport an unresolved named export of the same module.`
message: `Module "main.js" that is marked with 'syntheticNamedExports: "__synthetic"' needs an export named "__synthetic" that does not reexport an unresolved named export of the same module.`,
watchFiles: [path.join(__dirname, 'main.js'), path.join(__dirname, 'dep.js')]
}
};
@@ -1,2 +1 @@
import { foo } from './main.js';
export default foo;
export { foo as default } from './main.js';
@@ -0,0 +1,11 @@
module.exports = {
description: 'handles circular synthetic exports',
warnings: [
{
code: 'CIRCULAR_DEPENDENCY',
cycle: ['dep1.js', 'dep2.js', 'dep1.js'],
importer: 'dep1.js',
message: 'Circular dependency: dep1.js -> dep2.js -> dep1.js'
}
]
};
@@ -0,0 +1,2 @@
import dep2 from './dep2';
export default dep2;
@@ -0,0 +1,2 @@
import dep1 from './dep1';
export default dep1;
@@ -0,0 +1,2 @@
import dep1 from './dep1';
assert.strictEqual(dep1, undefined);
@@ -0,0 +1,10 @@
module.exports = {
description: 'makes sure default exports of synthetic named exports are snapshots',
options: {
plugins: {
transform() {
return { syntheticNamedExports: '__synthetic' };
}
}
}
};
@@ -0,0 +1,2 @@
import { foo } from './synthetic';
export default foo;
@@ -0,0 +1,6 @@
import foo from './dep';
import { update } from './synthetic';

assert.strictEqual(foo, 'original');
update();
assert.strictEqual(foo, 'original');
@@ -0,0 +1,2 @@
export const __synthetic = { foo: 'original' };
export const update = () => (__synthetic.foo = 'reassigned');

0 comments on commit bab3d3d

Please sign in to comment.