Skip to content

Commit

Permalink
Provide synthetic namespace for dynamic imports when perserving modul…
Browse files Browse the repository at this point in the history
…es (#4913)
  • Loading branch information
lukastaegert committed Mar 20, 2023
1 parent 3682f30 commit eb9777c
Show file tree
Hide file tree
Showing 18 changed files with 133 additions and 33 deletions.
32 changes: 11 additions & 21 deletions src/Chunk.ts
Expand Up @@ -216,7 +216,7 @@ export default class Chunk {

for (const module of orderedModules) {
chunkByModule.set(module, this);
if (module.namespace.included) {
if (module.namespace.included && !outputOptions.preserveModules) {
includedNamespaces.add(module);
}
if (this.isEmpty && module.isIncluded()) {
Expand All @@ -229,7 +229,7 @@ export default class Chunk {
if (!chunkModules.has(importer)) {
this.dynamicEntryModules.push(module);
// Modules with synthetic exports need an artificial namespace for dynamic imports
if (module.info.syntheticNamedExports && !outputOptions.preserveModules) {
if (module.info.syntheticNamedExports) {
includedNamespaces.add(module);
this.exports.add(module.namespace);
}
Expand Down Expand Up @@ -407,14 +407,11 @@ export default class Chunk {
}
if (!this.facadeModule) {
const needsStrictFacade =
module.preserveSignature === 'strict' ||
(module.preserveSignature === 'exports-only' &&
module.getExportNamesByVariable().size > 0);
if (
!needsStrictFacade ||
this.outputOptions.preserveModules ||
this.canModuleBeFacade(module, exposedVariables)
) {
!this.outputOptions.preserveModules &&
(module.preserveSignature === 'strict' ||
(module.preserveSignature === 'exports-only' &&
module.getExportNamesByVariable().size > 0));
if (!needsStrictFacade || this.canModuleBeFacade(module, exposedVariables)) {
this.facadeModule = module;
this.facadeChunkByModule.set(module, this);
if (module.preserveSignature) {
Expand Down Expand Up @@ -1140,14 +1137,7 @@ export default class Chunk {
renderedModules,
snippets
} = this;
const {
compact,
dynamicImportFunction,
format,
freeze,
namespaceToStringTag,
preserveModules
} = outputOptions;
const { compact, dynamicImportFunction, format, freeze, namespaceToStringTag } = outputOptions;
const { _, cnst, n } = snippets;
this.setDynamicImportResolutions(fileName);
this.setImportMetaResolutions(fileName);
Expand Down Expand Up @@ -1188,7 +1178,7 @@ export default class Chunk {
usedModules.push(module);
}
const namespace = module.namespace;
if (includedNamespaces.has(module) && !preserveModules) {
if (includedNamespaces.has(module)) {
const rendered = namespace.renderBlock(renderOptions);
if (namespace.renderFirst()) hoistedSource += n + rendered;
else magicString.addSource(new MagicString(rendered));
Expand Down Expand Up @@ -1346,13 +1336,13 @@ export default class Chunk {
accessedGlobalsByScope,
includedNamespaces,
orderedModules,
outputOptions: { format, preserveModules }
outputOptions: { format }
} = this;
for (const module of orderedModules) {
for (const importMeta of module.importMetas) {
importMeta.setResolution(format, accessedGlobalsByScope, fileName);
}
if (includedNamespaces.has(module) && !preserveModules) {
if (includedNamespaces.has(module)) {
module.namespace.prepare(accessedGlobalsByScope);
}
}
Expand Down
Expand Up @@ -12,6 +12,7 @@ module.exports = {
}
},
output: {
exports: 'named',
preserveModules: true
}
}
Expand Down
@@ -1,8 +1,31 @@
define((function () { 'use strict';
define(['exports'], (function (exports) { 'use strict';

function _mergeNamespaces(n, m) {
m.forEach(function (e) {
e && typeof e !== 'string' && !Array.isArray(e) && Object.keys(e).forEach(function (k) {
if (k !== 'default' && !(k in n)) {
var d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: function () { return e[k]; }
});
}
});
});
return Object.freeze(n);
}

const __moduleExports = { foo: 'bar' };
var lib = 'baz';

return lib;
var lib$1 = /*#__PURE__*/_mergeNamespaces({
__proto__: null,
default: lib
}, [__moduleExports]);

exports.default = lib;
exports.lib = lib$1;

Object.defineProperty(exports, '__esModule', { value: true });

}));
@@ -1,7 +1,5 @@
define(['require'], (function (require) { 'use strict';

function _interopNamespaceDefaultOnly (e) { return Object.freeze({ __proto__: null, default: e }); }

new Promise(function (resolve, reject) { require(['./lib'], function (m) { resolve(/*#__PURE__*/_interopNamespaceDefaultOnly(m)); }, reject); }).then(console.log);
new Promise(function (resolve, reject) { require(['./lib'], resolve, reject); }).then(function (n) { return n.lib; }).then(console.log);

}));
@@ -1,6 +1,29 @@
'use strict';

Object.defineProperty(exports, '__esModule', { value: true });

function _mergeNamespaces(n, m) {
m.forEach(function (e) {
e && typeof e !== 'string' && !Array.isArray(e) && Object.keys(e).forEach(function (k) {
if (k !== 'default' && !(k in n)) {
var d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: function () { return e[k]; }
});
}
});
});
return Object.freeze(n);
}

const __moduleExports = { foo: 'bar' };
var lib = 'baz';

module.exports = lib;
var lib$1 = /*#__PURE__*/_mergeNamespaces({
__proto__: null,
default: lib
}, [__moduleExports]);

exports.default = lib;
exports.lib = lib$1;
@@ -1,5 +1,3 @@
'use strict';

function _interopNamespaceDefaultOnly (e) { return Object.freeze({ __proto__: null, default: e }); }

Promise.resolve().then(function () { return /*#__PURE__*/_interopNamespaceDefaultOnly(require('./lib.js')); }).then(console.log);
Promise.resolve().then(function () { return require('./lib.js'); }).then(function (n) { return n.lib; }).then(console.log);
@@ -1,4 +1,24 @@
function _mergeNamespaces(n, m) {
m.forEach(function (e) {
e && typeof e !== 'string' && !Array.isArray(e) && Object.keys(e).forEach(function (k) {
if (k !== 'default' && !(k in n)) {
var d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: function () { return e[k]; }
});
}
});
});
return Object.freeze(n);
}

const __moduleExports = { foo: 'bar' };
var lib = 'baz';

export { lib as default };
var lib$1 = /*#__PURE__*/_mergeNamespaces({
__proto__: null,
default: lib
}, [__moduleExports]);

export { lib as default, lib$1 as l };
@@ -1 +1 @@
import('./lib.js').then(console.log);
import('./lib.js').then(function (n) { return n.l; }).then(console.log);
Expand Up @@ -3,9 +3,30 @@ System.register([], (function (exports) {
return {
execute: (function () {

function _mergeNamespaces(n, m) {
m.forEach(function (e) {
e && typeof e !== 'string' && !Array.isArray(e) && Object.keys(e).forEach(function (k) {
if (k !== 'default' && !(k in n)) {
var d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: function () { return e[k]; }
});
}
});
});
return Object.freeze(n);
}

const __moduleExports = { foo: 'bar' };
var lib = exports('default', 'baz');

var lib$1 = /*#__PURE__*/_mergeNamespaces({
__proto__: null,
default: lib
}, [__moduleExports]);
exports('l', lib$1);

})
};
}));
Expand Up @@ -3,7 +3,7 @@ System.register([], (function (exports, module) {
return {
execute: (function () {

module.import('./lib.js').then(console.log);
module.import('./lib.js').then(function (n) { return n.l; }).then(console.log);

})
};
Expand Down
@@ -0,0 +1,24 @@
const assert = require('node:assert');

module.exports = {
description: 'handles a dynamic import with synthetic named exports in preserveModules mode',
options: {
output: {
preserveModules: true
},
plugins: [
{
name: 'test',
transform() {
return {
syntheticNamedExports: '__synthetic'
};
}
}
]
},
async exports(exports) {
const { foo } = await exports.promise;
assert.strictEqual(foo, 'bar');
}
};
@@ -0,0 +1 @@
export const promise = import('./other');
@@ -0,0 +1 @@
export const __synthetic = { foo: 'bar' };

0 comments on commit eb9777c

Please sign in to comment.