Skip to content

Commit

Permalink
support for changing the attributes key for dynamic imports (#5818)
Browse files Browse the repository at this point in the history
  • Loading branch information
TrickyPi authored Feb 1, 2025
1 parent caeffb3 commit 93c9c0e
Show file tree
Hide file tree
Showing 29 changed files with 161 additions and 27 deletions.
32 changes: 22 additions & 10 deletions src/Chunk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import LocalVariable from './ast/variables/LocalVariable';
import NamespaceVariable from './ast/variables/NamespaceVariable';
import SyntheticNamedExportVariable from './ast/variables/SyntheticNamedExportVariable';
import type Variable from './ast/variables/Variable';
import ExternalChunk from './ExternalChunk';
import ExternalChunk, { formatAttributes } from './ExternalChunk';
import ExternalModule from './ExternalModule';
import finalisers from './finalisers/index';
import Module from './Module';
Expand All @@ -27,6 +27,7 @@ import type {
RenderedModule
} from './rollup/types';
import { createAddons } from './utils/addons';
import { EMPTY_OBJECT } from './utils/blank';
import { deconflictChunk, type DependenciesToBeDeconflicted } from './utils/deconflictChunk';
import { escapeId } from './utils/escapeId';
import { assignExportsToMangledNames, assignExportsToNames } from './utils/exportNames';
Expand Down Expand Up @@ -56,6 +57,7 @@ import {
} from './utils/logs';
import type { OutputBundleWithPlaceholders } from './utils/outputBundle';
import { FILE_PLACEHOLDER } from './utils/outputBundle';
import { getAttributesFromImportExpression } from './utils/parseImportAttributes';
import { basename, extname, isAbsolute, normalize, resolve } from './utils/path';
import type { PluginDriver } from './utils/PluginDriver';
import { getAliasName, getImportPath } from './utils/relativeId';
Expand Down Expand Up @@ -958,18 +960,25 @@ export default class Chunk {

private getDynamicImportStringAndAttributes(
resolution: ExternalModule | string | null,
fileName: string
fileName: string,
node: ImportExpression
): [importPath: string, attributes: string | null | true] {
if (resolution instanceof ExternalModule) {
const chunk = this.externalChunkByModule.get(resolution)!;
return [`'${chunk.getImportPath(fileName)}'`, chunk.getImportAttributes(this.snippets)];
}
return [
resolution || '',
(['es', 'cjs'].includes(this.outputOptions.format) &&
this.outputOptions.externalImportAttributes) ||
null
];
let attributes: string | true | null = null;
if (
['es', 'cjs'].includes(this.outputOptions.format) &&
this.outputOptions.externalImportAttributes
) {
const attributesFromImportAttributes = getAttributesFromImportExpression(node);
attributes =
attributesFromImportAttributes === EMPTY_OBJECT
? true
: formatAttributes(attributesFromImportAttributes, this.snippets);
}
return [resolution || '', attributes];
}

private getFallbackChunkName(): string {
Expand Down Expand Up @@ -1216,7 +1225,8 @@ export default class Chunk {
compact,
format,
freeze,
generatedCode: { symbols }
generatedCode: { symbols },
importAttributesKey
} = outputOptions;
const { _, cnst, n } = snippets;
this.setDynamicImportResolutions(fileName);
Expand All @@ -1235,6 +1245,7 @@ export default class Chunk {
exportNamesByVariable,
format,
freeze,
importAttributesKey,
indent,
pluginDriver,
snippets,
Expand Down Expand Up @@ -1326,7 +1337,8 @@ export default class Chunk {
const { node, resolution } = resolvedDynamicImport;
const [resolutionString, attributes] = this.getDynamicImportStringAndAttributes(
resolution,
fileName
fileName,
node
);
node.setExternalResolution(
'external',
Expand Down
2 changes: 1 addition & 1 deletion src/ExternalChunk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ export default class ExternalChunk {
}
}

function formatAttributes(
export function formatAttributes(
attributes: Record<string, string> | null | void | false,
{ getObject }: GenerateCodeSnippets
): string | null {
Expand Down
5 changes: 3 additions & 2 deletions src/ast/nodes/ImportExpression.ts
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,8 @@ export default class ImportExpression extends NodeBase {

render(code: MagicString, options: RenderOptions): void {
const {
snippets: { _, getDirectReturnFunction, getObject, getPropertyAccess }
snippets: { _, getDirectReturnFunction, getObject, getPropertyAccess },
importAttributesKey
} = options;
if (this.inlineNamespace) {
const [left, right] = getDirectReturnFunction([], {
Expand Down Expand Up @@ -215,7 +216,7 @@ export default class ImportExpression extends NodeBase {
if (this.attributes) {
code.appendLeft(
this.end - 1,
`,${_}${getObject([['assert', this.attributes]], {
`,${_}${getObject([[importAttributesKey, this.attributes]], {
lineBreakIndent: null
})}`
);
Expand Down
3 changes: 2 additions & 1 deletion src/utils/renderHelpers.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type MagicString from 'magic-string';
import type { Node, StatementNode } from '../ast/nodes/shared/Node';
import type Variable from '../ast/variables/Variable';
import type { InternalModuleFormat } from '../rollup/types';
import type { ImportAttributesKey, InternalModuleFormat } from '../rollup/types';
import type { GenerateCodeSnippets } from './generateCodeSnippets';
import type { PluginDriver } from './PluginDriver';
import { treeshakeNode } from './treeshakeNode';
Expand All @@ -12,6 +12,7 @@ export interface RenderOptions {
format: InternalModuleFormat;
freeze: boolean;
indent: string;
importAttributesKey: ImportAttributesKey;
pluginDriver: PluginDriver;
snippets: GenerateCodeSnippets;
symbols: boolean;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
module.exports = defineTest({
description: 'keep import attributes for dynamic imports with "assert" key',
expectedWarnings: ['UNRESOLVED_IMPORT'],
options: {
output: {
importAttributesKey: 'assert'
},
external: id => {
if (id === 'unresolved') return null;
return true;
},
plugins: [
{
name: 'test',
resolveDynamicImport(specifier) {
if (typeof specifier === 'object') {
if (specifier.type === 'TemplateLiteral') {
return "'resolvedString'";
}
if (specifier.type === 'BinaryExpression') {
return { id: 'resolved-id', external: true };
}
} else if (specifier === 'external-resolved') {
return { id: 'resolved-different', external: true };
}
return null;
}
}
]
}
});
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import('external', { assert: { type: 'special' } });
import(globalThis.unknown, { assert: { type: 'special' } });
import(`external-${globalThis.unknown}`, { assert: { type: 'special' } });
import(`external-${globalThis.unknown}`, { with: { type: 'special' } });
import('external' + globalThis.unknown, { assert: { type: 'special' } });
import('external-resolved', { assert: { type: 'special' } });
import('external-resolved', { with: { type: 'special' } });
import('unresolved', { assert: { type: 'special' } });
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
'use strict';

import('external', { assert: { type: 'special' } });
import(globalThis.unknown, { with: { type: 'special' } });
import('resolvedString', { with: { type: 'special' } });
import(globalThis.unknown, { assert: { type: 'special' } });
import('resolvedString', { assert: { type: 'special' } });
import('resolved-id', { assert: { type: 'special' } });
import('resolved-different', { assert: { type: 'special' } });
import('unresolved', { assert: { type: 'special' } });
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import('external', { assert: { type: 'special' } });
import(globalThis.unknown, { with: { type: 'special' } });
import('resolvedString', { with: { type: 'special' } });
import(globalThis.unknown, { assert: { type: 'special' } });
import('resolvedString', { assert: { type: 'special' } });
import('resolved-id', { assert: { type: 'special' } });
import('resolved-different', { assert: { type: 'special' } });
import('unresolved', { assert: { type: 'special' } });
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import('external', { assert: { type: 'special' } });
import(globalThis.unknown, { assert: { type: 'special' } });
import(`external-${globalThis.unknown}`, { with: { type: 'special' } });
import('external' + globalThis.unknown, { assert: { type: 'special' } });
import('external-resolved', { with: { type: 'special' } });
import('unresolved', { assert: { type: 'special' } });
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
module.exports = defineTest({
description: 'keep import attributes for dynamic imports',
description: 'keep import attributes for dynamic imports with "with" key',
expectedWarnings: ['UNRESOLVED_IMPORT'],
options: {
output: {
importAttributesKey: 'with'
},
external: id => {
if (id === 'unresolved') return null;
return true;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
define(['require'], (function (require) { 'use strict';

function _interopNamespaceDefault(e) {
var n = Object.create(null);
if (e) {
Object.keys(e).forEach(function (k) {
if (k !== 'default') {
var d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: function () { return e[k]; }
});
}
});
}
n.default = e;
return Object.freeze(n);
}

new Promise(function (resolve, reject) { require(['external'], function (m) { resolve(/*#__PURE__*/_interopNamespaceDefault(m)); }, reject); });
(function (t) { return new Promise(function (resolve, reject) { require([t], function (m) { resolve(/*#__PURE__*/_interopNamespaceDefault(m)); }, reject); }); })(globalThis.unknown);
(function (t) { return new Promise(function (resolve, reject) { require([t], function (m) { resolve(/*#__PURE__*/_interopNamespaceDefault(m)); }, reject); }); })('resolvedString');
new Promise(function (resolve, reject) { require(['resolved-id'], function (m) { resolve(/*#__PURE__*/_interopNamespaceDefault(m)); }, reject); });
new Promise(function (resolve, reject) { require(['resolved-different'], function (m) { resolve(/*#__PURE__*/_interopNamespaceDefault(m)); }, reject); });
new Promise(function (resolve, reject) { require(['unresolved'], function (m) { resolve(/*#__PURE__*/_interopNamespaceDefault(m)); }, reject); });

}));
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
'use strict';

import('external', { with: { type: 'special' } });
import(globalThis.unknown, { with: { type: 'special' } });
import('resolvedString', { with: { type: 'special' } });
import('resolved-id', { with: { type: 'special' } });
import('resolved-different', { with: { type: 'special' } });
import('unresolved', { with: { type: 'special' } });
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import('external', { with: { type: 'special' } });
import(globalThis.unknown, { with: { type: 'special' } });
import('resolvedString', { with: { type: 'special' } });
import('resolved-id', { with: { type: 'special' } });
import('resolved-different', { with: { type: 'special' } });
import('unresolved', { with: { type: 'special' } });
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
(function () {
'use strict';

import('external');
import(globalThis.unknown);
import('resolvedString');
import('resolved-id');
import('resolved-different');
import('unresolved');

})();
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
System.register([], (function (exports, module) {
'use strict';
return {
execute: (function () {

module.import('external');
module.import(globalThis.unknown);
module.import('resolvedString');
module.import('resolved-id');
module.import('resolved-different');
module.import('unresolved');

})
};
}));
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
(function (factory) {
typeof define === 'function' && define.amd ? define(factory) :
factory();
})((function () { 'use strict';

import('external');
import(globalThis.unknown);
import('resolvedString');
import('resolved-id');
import('resolved-different');
import('unresolved');

}));
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import('external', { assert: { type: 'special' } });
import(globalThis.unknown, { assert: { type: 'special' } });
import(`external-${globalThis.unknown}`, { with: { type: 'special' } });
import('external' + globalThis.unknown, { assert: { type: 'special' } });
import('external-resolved', { with: { type: 'special' } });
import('unresolved', { assert: { type: 'special' } });

This file was deleted.

0 comments on commit 93c9c0e

Please sign in to comment.