Skip to content

Commit

Permalink
Add import specifiers to bundle information
Browse files Browse the repository at this point in the history
  • Loading branch information
lukastaegert committed Aug 14, 2020
1 parent 13f18ef commit 118ff10
Show file tree
Hide file tree
Showing 5 changed files with 147 additions and 12 deletions.
1 change: 1 addition & 0 deletions docs/02-javascript-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ async function build() {
// fileName: string, // the chunk file name
// implicitlyLoadedBefore: string[]; // entries that should only be loaded after this chunk
// imports: string[], // external modules imported statically by the chunk
// importSpecifiers: {[imported: string]: string[]} // list of imported bindings per dependency
// isDynamicEntry: boolean, // is this chunk a dynamic entry point
// isEntry: boolean, // is this chunk a static entry point
// isImplicitEntry: boolean, // should this chunk only be loaded after other chunks
Expand Down
1 change: 1 addition & 0 deletions docs/05-plugin-development.md
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,7 @@ Called at the end of `bundle.generate()` or immediately before the files are wri
fileName: string,
implicitlyLoadedBefore: string[],
imports: string[],
importSpecifiers: {[imported: string]: string[]},
isDynamicEntry: boolean,
isEntry: boolean,
isImplicitEntry: boolean,
Expand Down
20 changes: 20 additions & 0 deletions src/Chunk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -477,6 +477,7 @@ export default class Chunk {
fileName: this.id!,
implicitlyLoadedBefore: Array.from(this.implicitlyLoadedBefore, getId),
imports: Array.from(this.dependencies, getId),
importSpecifiers: this.getDependencyImportSpecifiers(),
map: undefined,
referencedFiles: this.getReferencedFiles()
});
Expand Down Expand Up @@ -1019,6 +1020,25 @@ export default class Chunk {
return { deconflictedDefault, deconflictedNamespace, dependencies };
}

private getDependencyImportSpecifiers(): { [imported: string]: string[] } {
const importSpecifiers: { [imported: string]: string[] } = {};
for (const [dependency, declaration] of this.renderedDependencies!) {
const specifiers = new Set<string>();
if (declaration.imports) {
for (const { imported } of declaration.imports) {
specifiers.add(imported);
}
}
if (declaration.reexports) {
for (const { imported } of declaration.reexports) {
specifiers.add(imported);
}
}
importSpecifiers[dependency.id!] = [...specifiers];
}
return importSpecifiers;
}

private getFallbackChunkName(): string {
if (this.manualChunkAlias) {
return this.manualChunkAlias;
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 @@ -684,6 +684,9 @@ export interface RenderedChunk extends PreRenderedChunk {
fileName: string;
implicitlyLoadedBefore: string[];
imports: string[];
importSpecifiers: {
[imported: string]: string[];
};
map?: SourceMap;
referencedFiles: string[];
}
Expand Down
134 changes: 122 additions & 12 deletions test/misc/bundle-information.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ describe('The bundle object', () => {
input: ['input1', 'input2'],
plugins: [
loader({
input1: 'import "shared";console.log("input1");export const out = true;',
input1:
'import shared, {used} from "shared";console.log("input1", used, shared);export const out = true;',
input2: 'import "shared";console.log("input2");export default 42',
shared: 'console.log("shared");export const unused = null;'
shared:
'console.log("shared");export const unused = null;export const used = "used"; export default "stuff";'
})
]
})
Expand All @@ -26,15 +28,15 @@ describe('The bundle object', () => {
.then(({ output }) => {
assert.deepEqual(
output.map(chunk => chunk.fileName),
['input1-3810e839.js', 'input2-14354d1f.js', 'generated-shared-f6027271.js'],
['input1-ff0de9c1.js', 'input2-28dc81ee.js', 'generated-shared-c4fdd061.js'],
'fileName'
);
assert.deepEqual(
output.map(chunk => chunk.code),
[
`import './generated-shared-f6027271.js';\n\nconsole.log("input1");const out = true;\n\nexport { out };\n`,
`import './generated-shared-f6027271.js';\n\nconsole.log("input2");var input2 = 42;\n\nexport default input2;\n`,
'console.log("shared");\n'
`import { u as used, s as shared } from './generated-shared-c4fdd061.js';\n\nconsole.log("input1", used, shared);const out = true;\n\nexport { out };\n`,
`import './generated-shared-c4fdd061.js';\n\nconsole.log("input2");var input2 = 42;\n\nexport default input2;\n`,
`console.log("shared");const used = "used"; var shared = "stuff";\n\nexport { shared as s, used as u };\n`
],
'code'
);
Expand All @@ -60,28 +62,37 @@ describe('The bundle object', () => {
);
assert.deepEqual(
output.map(chunk => chunk.imports),
[['generated-shared-f6027271.js'], ['generated-shared-f6027271.js'], []],
[['generated-shared-c4fdd061.js'], ['generated-shared-c4fdd061.js'], []],
'imports'
);
assert.deepEqual(
output.map(chunk => chunk.importSpecifiers),
[
{ 'generated-shared-c4fdd061.js': ['u', 's'] },
{ 'generated-shared-c4fdd061.js': [] },
{}
],
'importSpecifiers'
);
assert.deepEqual(
output.map(chunk => chunk.dynamicImports),
[[], [], []],
'dynamicImports'
);
assert.deepEqual(
output.map(chunk => chunk.exports),
[['out'], ['default'], []],
[['out'], ['default'], ['s', 'u']],
'exports'
);
assert.deepEqual(
output.map(chunk => chunk.modules),
[
{
input1: {
originalLength: 62,
originalLength: 96,
removedExports: [],
renderedExports: ['out'],
renderedLength: 39
renderedLength: 53
}
},
{
Expand All @@ -94,10 +105,99 @@ describe('The bundle object', () => {
},
{
shared: {
originalLength: 49,
originalLength: 100,
removedExports: ['unused'],
renderedExports: ['used', 'default'],
renderedLength: 64
}
}
],
'modules'
);
});
});

it('contains information about external imports and reexports', () => {
return rollup
.rollup({
input: ['input'],
external: ['external1', 'external2', 'external3'],
plugins: [
loader({
input:
'export {default as foo, bar} from "external1"; import * as external2 from "external2"; export * from "external3"; console.log(external2);'
})
]
})
.then(bundle =>
bundle.generate({
format: 'es',
dir: 'dist',
entryFileNames: '[name].js'
})
)
.then(({ output }) => {
assert.deepEqual(
output.map(chunk => chunk.fileName),
['input.js'],
'fileName'
);
assert.deepEqual(
output.map(chunk => chunk.code),
[
`export { bar, default as foo } from 'external1';\nimport * as external2 from 'external2';\nexport * from 'external3';\n\nconsole.log(external2);\n`
],
'code'
);
assert.deepEqual(
output.map(chunk => chunk.map),
[null],
'map'
);
assert.deepEqual(
output.map(chunk => chunk.isEntry),
[true],
'isEntry'
);
assert.deepEqual(
output.map(chunk => chunk.name),
['input'],
'name'
);
assert.deepEqual(
output.map(chunk => chunk.facadeModuleId),
['input'],
'facadeModuleId'
);
assert.deepEqual(
output.map(chunk => chunk.imports),
[['external1', 'external2', 'external3']],
'imports'
);
assert.deepEqual(
output.map(chunk => chunk.importSpecifiers),
[{ external1: ['bar', 'default'], external2: ['*'], external3: ['*'] }],
'importSpecifiers'
);
assert.deepEqual(
output.map(chunk => chunk.dynamicImports),
[[]],
'dynamicImports'
);
assert.deepEqual(
output.map(chunk => chunk.exports),
[['*external3', 'bar', 'foo']],
'exports'
);
assert.deepEqual(
output.map(chunk => chunk.modules),
[
{
input: {
originalLength: 137,
removedExports: [],
renderedExports: [],
renderedLength: 22
renderedLength: 23
}
}
],
Expand Down Expand Up @@ -323,6 +423,11 @@ describe('The bundle object', () => {
[[]],
'imports'
);
assert.deepEqual(
output.map(chunk => chunk.importSpecifiers),
[{}],
'importSpecifiers'
);
assert.deepEqual(
output.map(chunk => chunk.dynamicImports),
[[]],
Expand Down Expand Up @@ -400,6 +505,11 @@ console.log(other);Promise.all([import('./dynamic1'), import('./dynamic2')]).the
[['_virtual/other'], [], [], []],
'imports'
);
assert.deepEqual(
output.map(chunk => chunk.importSpecifiers),
[{ '_virtual/other': ['other'] }, {}, {}, {}],
'importSpecifiers'
);
assert.deepEqual(
output.map(chunk => chunk.exports),
[[], ['dynamic1'], ['other'], ['dynamic2']],
Expand Down

0 comments on commit 118ff10

Please sign in to comment.