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

Add ImportAttributesKey to choose keyword ("with" | "assert") #5474

Merged
merged 10 commits into from
Apr 20, 2024
1 change: 1 addition & 0 deletions cli/help.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ Basic options:
--generatedCode.symbols Use symbols in generated code
--hashCharacters <name> Use the specified character set for file hashes
--no-hoistTransitiveImports Do not hoist transitive imports into entry chunks
--importAttributesKey <name> Use the specified keyword for import attributes
--no-indent Don't indent result
--inlineDynamicImports Create single bundle when using dynamic imports
--no-interop Do not include interop block
Expand Down
2 changes: 2 additions & 0 deletions docs/command-line-interface/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ export default {
generatedCode,
hashCharacters,
hoistTransitiveImports,
importAttributesKey,
inlineDynamicImports,
interop,
intro,
Expand Down Expand Up @@ -417,6 +418,7 @@ Many options have command line equivalents. In those cases, any arguments passed
--generatedCode.symbols Use symbols in generated code
--hashCharacters <name> Use the specified character set for file hashes
--no-hoistTransitiveImports Do not hoist transitive imports into entry chunks
--importAttributesKey <name> Use the specified keyword for import attributes
--no-indent Don't indent result
--inlineDynamicImports Create single bundle when using dynamic imports
--no-interop Do not include interop block
Expand Down
10 changes: 10 additions & 0 deletions docs/configuration-options/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -930,6 +930,16 @@ This determines the character set that Rollup is allowed to use in file hashes.

By default, when creating multiple chunks, transitive imports of entry chunks will be added as empty imports to the entry chunks. See ["Why do additional imports turn up in my entry chunks when code-splitting?"](../faqs/index.md#why-do-additional-imports-turn-up-in-my-entry-chunks-when-code-splitting) for details and background. Setting this option to `false` will disable this behaviour. This option is ignored when using the [`output.preserveModules`](#output-preservemodules) option as here, imports will never be hoisted.

### output.importAttributesKey

| | |
| -------: | :------------------------------ |
| Type: | `"with" \| "assert"` |
| CLI: | `--importAttributesKey <name>` |
| Default: | `"assert"` |

This determines the keyword set that Rollup will use for import attributes.

### output.inlineDynamicImports

| | |
Expand Down
1 change: 1 addition & 0 deletions docs/javascript-api/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ const outputOptions = {
generatedCode,
hashCharacters,
hoistTransitiveImports,
importAttributesKey,
inlineDynamicImports,
interop,
intro,
Expand Down
6 changes: 6 additions & 0 deletions docs/repl/stores/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,11 @@ export const useOptions = defineStore('options2', () => {
defaultValue: true,
name: 'output.hoistTransitiveImports'
});
const optionOutputImportAttributesKey = getSelect({
defaultValue: 'assert',
name: 'output.importAttributesKey',
options: () => ['with', 'assert']
});
const optionOutputIndent = getBoolean({
available: () => ['amd', 'iife', 'umd', 'system'].includes(optionOutputFormat.value.value!),
defaultValue: true,
Expand Down Expand Up @@ -445,6 +450,7 @@ export const useOptions = defineStore('options2', () => {
optionOutputGlobals,
optionOutputHashCharacters,
optionOutputHoistTransitiveImports,
optionOutputImportAttributesKey,
optionOutputIndent,
optionOutputInlineDynamicImports,
optionOutputInterop,
Expand Down
14 changes: 10 additions & 4 deletions src/finalisers/es.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { Bundle as MagicStringBundle } from 'magic-string';
import type { ChunkDependency, ChunkExports, ImportSpecifier, ReexportSpecifier } from '../Chunk';
import type { NormalizedOutputOptions } from '../rollup/types';
import type { ImportAttributesKey, NormalizedOutputOptions } from '../rollup/types';
import type { GenerateCodeSnippets } from '../utils/generateCodeSnippets';
import { stringifyIdentifierIfNeeded } from '../utils/identifierHelpers';
import { getHelpersBlock } from '../utils/interopHelpers';
Expand All @@ -9,11 +9,16 @@ import type { FinaliserOptions } from './index';
export default function es(
magicString: MagicStringBundle,
{ accessedGlobals, indent: t, intro, outro, dependencies, exports, snippets }: FinaliserOptions,
{ externalLiveBindings, freeze, generatedCode: { symbols } }: NormalizedOutputOptions
{
externalLiveBindings,
freeze,
generatedCode: { symbols },
importAttributesKey
}: NormalizedOutputOptions
): void {
const { n } = snippets;

const importBlock = getImportBlock(dependencies, snippets);
const importBlock = getImportBlock(dependencies, importAttributesKey, snippets);
if (importBlock.length > 0) intro += importBlock.join(n) + n + n;
intro += getHelpersBlock(
null,
Expand All @@ -35,11 +40,12 @@ export default function es(

function getImportBlock(
dependencies: readonly ChunkDependency[],
importAttributesKey: ImportAttributesKey,
{ _ }: GenerateCodeSnippets
): string[] {
const importBlock: string[] = [];
for (const { importPath, reexports, imports, name, attributes } of dependencies) {
const assertion = attributes ? `${_}assert${_}${attributes}` : '';
const assertion = attributes ? `${_}${importAttributesKey}${_}${attributes}` : '';
const pathWithAssertion = `'${importPath}'${assertion};`;
if (!reexports && !imports) {
importBlock.push(`import${_}${pathWithAssertion}`);
Expand Down
3 changes: 3 additions & 0 deletions src/rollup/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -623,6 +623,7 @@ export interface NormalizedInputOptions {
}

export type InternalModuleFormat = 'amd' | 'cjs' | 'es' | 'iife' | 'system' | 'umd';
export type ImportAttributesKey = 'with' | 'assert';

export type ModuleFormat = InternalModuleFormat | 'commonjs' | 'esm' | 'module' | 'systemjs';

Expand Down Expand Up @@ -712,6 +713,7 @@ export interface OutputOptions {
globals?: GlobalsOption;
hashCharacters?: HashCharacters;
hoistTransitiveImports?: boolean;
importAttributesKey?: ImportAttributesKey;
indent?: string | boolean;
inlineDynamicImports?: boolean;
interop?: InteropType | GetInterop;
Expand Down Expand Up @@ -764,6 +766,7 @@ export interface NormalizedOutputOptions {
globals: GlobalsOption;
hashCharacters: HashCharacters;
hoistTransitiveImports: boolean;
importAttributesKey: ImportAttributesKey;
indent: true | string;
inlineDynamicImports: boolean;
interop: GetInterop;
Expand Down
1 change: 1 addition & 0 deletions src/utils/options/mergeOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,7 @@ async function mergeOutputOptions(
globals: getOption('globals'),
hashCharacters: getOption('hashCharacters'),
hoistTransitiveImports: getOption('hoistTransitiveImports'),
importAttributesKey: getOption('importAttributesKey'),
indent: getOption('indent'),
inlineDynamicImports: getOption('inlineDynamicImports'),
interop: getOption('interop'),
Expand Down
1 change: 1 addition & 0 deletions src/utils/options/normalizeOutputOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ export async function normalizeOutputOptions(
globals: config.globals || {},
hashCharacters: config.hashCharacters ?? 'base64',
hoistTransitiveImports: config.hoistTransitiveImports ?? true,
importAttributesKey: config.importAttributesKey ?? 'assert',
indent: getIndent(config, compact),
inlineDynamicImports,
interop: getInterop(config),
Expand Down
2 changes: 1 addition & 1 deletion test/form/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const FORMATS = ['amd', 'cjs', 'system', 'es', 'iife', 'umd'];

runTestSuiteWithSamples(
'form',
path.resolve(__dirname, 'samples'),
path.resolve(__dirname, 'samples', 'import-attributes'),
/**
* @param {import('../types').TestConfigForm} config
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
module.exports = defineTest({
description: 'keeps any import attributes on input using import attributes with "with" key',
expectedWarnings: ['UNRESOLVED_IMPORT'],
options: {
external: id => {
if (id === 'unresolved') return null;
return true;
},
output: {
name: 'bundle',
importAttributesKey: 'assert'
}
}
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
define(['exports', 'a', 'b', 'c', 'd', 'unresolved'], (function (exports, a, b, c, d$1, unresolved) { '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);
}

var b__namespace = /*#__PURE__*/_interopNamespaceDefault(b);

console.log(a.a, b__namespace, d);

Object.defineProperty(exports, "c", {
enumerable: true,
get: function () { return c.c; }
});
Object.keys(d$1).forEach(function (k) {
if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
enumerable: true,
get: function () { return d$1[k]; }
});
});

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

var a = require('a');
var b = require('b');
var c = require('c');
var d$1 = require('d');
require('unresolved');

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);
}

var b__namespace = /*#__PURE__*/_interopNamespaceDefault(b);

console.log(a.a, b__namespace, d);

Object.defineProperty(exports, "c", {
enumerable: true,
get: function () { return c.c; }
});
Object.keys(d$1).forEach(function (k) {
if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
enumerable: true,
get: function () { return d$1[k]; }
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { a } from 'a' assert { type: 'a', extra: 'extra' };
import * as b from 'b' assert { type: 'b' };
export { c } from 'c' assert { type: 'c' };
export * from 'd' assert { type: 'd' };
import 'unresolved' assert { type: 'e' };

console.log(a, b, d);
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
var bundle = (function (exports, a, b, c, d$1) {
'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);
}

var b__namespace = /*#__PURE__*/_interopNamespaceDefault(b);

console.log(a.a, b__namespace, d);

Object.defineProperty(exports, "c", {
enumerable: true,
get: function () { return c.c; }
});
Object.keys(d$1).forEach(function (k) {
if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
enumerable: true,
get: function () { return d$1[k]; }
});
});

return exports;

})({}, a, b, c, d$1);
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
System.register('bundle', ['a', 'b', 'c', 'd', 'unresolved'], (function (exports) {
'use strict';
var _starExcludes = {
__proto__: null,
default: 1,
c: 1
};
var a, b;
return {
setters: [function (module) {
a = module.a;
}, function (module) {
b = module;
}, function (module) {
exports("c", module.c);
}, function (module) {
var setter = { __proto__: null };
for (var name in module) {
if (!_starExcludes[name]) setter[name] = module[name];
}
exports(setter);
}, null],
execute: (function () {

console.log(a, b, d);

})
};
}));
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('a'), require('b'), require('c'), require('d'), require('unresolved')) :
typeof define === 'function' && define.amd ? define(['exports', 'a', 'b', 'c', 'd', 'unresolved'], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.bundle = {}, global.a, global.b, global.c, global.d$1));
})(this, (function (exports, a, b, c, d$1) { '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);
}

var b__namespace = /*#__PURE__*/_interopNamespaceDefault(b);

console.log(a.a, b__namespace, d);

Object.defineProperty(exports, "c", {
enumerable: true,
get: function () { return c.c; }
});
Object.keys(d$1).forEach(function (k) {
if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
enumerable: true,
get: function () { return d$1[k]; }
});
});

}));
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { a } from 'a' with { type: 'a', extra: 'extra' };
import * as b from 'b' with { type: 'b' };
export { c } from 'c' with { type: 'c' };
export * from 'd' with { type: 'd' };
import 'unresolved' with { type: 'e' };

console.log(a, b, d);


Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
module.exports = defineTest({
description: 'keeps any import attributes on input using import attributes with "with" key',
expectedWarnings: ['UNRESOLVED_IMPORT'],
options: {
external: id => {
if (id === 'unresolved') return null;
return true;
},
output: {
name: 'bundle'
}
}
});