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 referenced files to bundle #3661

Merged
merged 2 commits into from Jul 6, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions docs/02-javascript-api.md
Expand Up @@ -44,9 +44,11 @@ async function build() {
// exports: string[], // exported variable names
// facadeModuleId: string | null, // the id of a module that this chunk corresponds to
// 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
// 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
// map: string | null, // sourcemaps if present
// modules: { // information about the modules in this chunk
// [id: string]: {
Expand All @@ -57,6 +59,7 @@ async function build() {
// };
// },
// name: string // the name of this chunk as used in naming patterns
// referencedFiles: string[] // files referenced via import.meta.ROLLUP_FILE_URL_<id>
// type: 'chunk', // signifies that this is a chunk
// }
console.log('Chunk', chunkOrAsset.modules);
Expand Down
1 change: 1 addition & 0 deletions docs/05-plugin-development.md
Expand Up @@ -309,6 +309,7 @@ Called at the end of `bundle.generate()` or immediately before the files are wri
},
},
name: string,
referencedFiles: string[],
type: 'chunk',
}
```
Expand Down
19 changes: 6 additions & 13 deletions src/Bundle.ts
Expand Up @@ -82,20 +82,12 @@ export default class Bundle {
): Promise<void> {
this.assignChunkIds(chunks, inputBase, addons, outputBundle);
for (const chunk of chunks) {
const chunkDescription = (outputBundle[
chunk.id!
] = chunk.getChunkInfoWithFileNames() as OutputChunk);
chunkDescription.fileName = chunk.id!;
outputBundle[chunk.id!] = chunk.getChunkInfoWithFileNames() as OutputChunk;
}
await Promise.all(
chunks.map(chunk => {
chunks.map(async chunk => {
const outputChunk = outputBundle[chunk.id!] as OutputChunk;
return chunk
.render(this.outputOptions, addons, outputChunk, this.pluginDriver)
.then(rendered => {
outputChunk.code = rendered.code;
outputChunk.map = rendered.map;
});
Object.assign(outputChunk, await chunk.render(this.outputOptions, addons, outputChunk));
})
);
}
Expand Down Expand Up @@ -146,7 +138,7 @@ export default class Bundle {
this.unsetOptions
);
} else {
chunk.id = chunk.generateId(addons, this.outputOptions, bundle, true, this.pluginDriver);
chunk.id = chunk.generateId(addons, this.outputOptions, bundle, true);
}
bundle[chunk.id] = FILE_PLACEHOLDER;
}
Expand Down Expand Up @@ -206,6 +198,7 @@ export default class Bundle {
this.inputOptions,
this.outputOptions,
this.unsetOptions,
this.pluginDriver,
this.graph.modulesById,
chunkByModule,
this.facadeChunkByModule,
Expand All @@ -231,7 +224,7 @@ export default class Bundle {
chunk.generateExports();
}
for (const chunk of chunks) {
chunk.preRender(this.outputOptions, inputBase, this.pluginDriver);
chunk.preRender(this.outputOptions, inputBase);
}
}
}
Expand Down
63 changes: 33 additions & 30 deletions src/Chunk.ts
Expand Up @@ -118,6 +118,7 @@ export default class Chunk {
inputOptions: NormalizedInputOptions,
outputOptions: NormalizedOutputOptions,
unsetOptions: Set<string>,
pluginDriver: PluginDriver,
modulesById: Map<string, Module | ExternalModule>,
chunkByModule: Map<Module, Chunk>,
facadeChunkByModule: Map<Module, Chunk>,
Expand All @@ -129,6 +130,7 @@ export default class Chunk {
inputOptions,
outputOptions,
unsetOptions,
pluginDriver,
modulesById,
chunkByModule,
facadeChunkByModule,
Expand Down Expand Up @@ -197,6 +199,7 @@ export default class Chunk {
private readonly inputOptions: NormalizedInputOptions,
private readonly outputOptions: NormalizedOutputOptions,
private readonly unsetOptions: Set<string>,
private readonly pluginDriver: PluginDriver,
private readonly modulesById: Map<string, Module | ExternalModule>,
private readonly chunkByModule: Map<Module, Chunk>,
private readonly facadeChunkByModule: Map<Module, Chunk>,
Expand Down Expand Up @@ -342,6 +345,7 @@ export default class Chunk {
this.inputOptions,
this.outputOptions,
this.unsetOptions,
this.pluginDriver,
this.modulesById,
this.chunkByModule,
this.facadeChunkByModule,
Expand Down Expand Up @@ -376,8 +380,7 @@ export default class Chunk {
addons: Addons,
options: NormalizedOutputOptions,
existingNames: Record<string, any>,
includeHash: boolean,
outputPluginDriver: PluginDriver
includeHash: boolean
): string {
if (this.fileName !== null) {
return this.fileName;
Expand All @@ -394,12 +397,7 @@ export default class Chunk {
format: () => options.format,
hash: () =>
includeHash
? this.computeContentHashWithDependencies(
addons,
options,
existingNames,
outputPluginDriver
)
? this.computeContentHashWithDependencies(addons, options, existingNames)
: '[hash]',
name: () => this.getChunkName()
},
Expand Down Expand Up @@ -469,7 +467,8 @@ export default class Chunk {
fileName: this.id!,
implicitlyLoadedBefore: Array.from(this.implicitlyLoadedBefore, getId),
imports: Array.from(this.dependencies, getId),
map: undefined
map: undefined,
referencedFiles: this.getReferencedFiles()
});
}

Expand All @@ -483,10 +482,10 @@ export default class Chunk {
);
}

getRenderedHash(outputPluginDriver: PluginDriver): string {
getRenderedHash(): string {
if (this.renderedHash) return this.renderedHash;
const hash = createHash();
const hashAugmentation = outputPluginDriver.hookReduceValueSync(
const hashAugmentation = this.pluginDriver.hookReduceValueSync(
'augmentChunkHash',
'',
[this.getChunkInfo()],
Expand Down Expand Up @@ -529,7 +528,7 @@ export default class Chunk {
}

// prerender allows chunk hashes and names to be generated before finalizing
preRender(options: NormalizedOutputOptions, inputBase: string, outputPluginDriver: PluginDriver) {
preRender(options: NormalizedOutputOptions, inputBase: string) {
const magicString = new MagicStringBundle({ separator: options.compact ? '' : '\n\n' });
this.usedModules = [];
this.indentString = getIndentString(this.orderedModules, options);
Expand All @@ -545,7 +544,7 @@ export default class Chunk {
freeze: options.freeze,
indent: this.indentString,
namespaceToStringTag: options.namespaceToStringTag,
outputPluginDriver,
outputPluginDriver: this.pluginDriver,
varOrConst: options.preferConst ? 'const' : 'var'
};

Expand Down Expand Up @@ -627,12 +626,7 @@ export default class Chunk {
this.exportMode === 'none' ? [] : this.getChunkExportDeclarations(options.format);
}

async render(
options: NormalizedOutputOptions,
addons: Addons,
outputChunk: RenderedChunk,
outputPluginDriver: PluginDriver
) {
async render(options: NormalizedOutputOptions, addons: Addons, outputChunk: RenderedChunk) {
timeStart('render format', 2);

const format = options.format;
Expand Down Expand Up @@ -660,7 +654,7 @@ export default class Chunk {
}

this.finaliseDynamicImports(options);
this.finaliseImportMetas(format, outputPluginDriver);
this.finaliseImportMetas(format);

const hasExports =
this.renderedExports!.length !== 0 ||
Expand Down Expand Up @@ -723,7 +717,7 @@ export default class Chunk {
let code = await renderChunk({
code: prevCode,
options,
outputPluginDriver,
outputPluginDriver: this.pluginDriver,
renderChunk: outputChunk,
sourcemapChain: chunkSourcemapChain
});
Expand Down Expand Up @@ -797,8 +791,7 @@ export default class Chunk {
private computeContentHashWithDependencies(
addons: Addons,
options: NormalizedOutputOptions,
existingNames: Record<string, any>,
outputPluginDriver: PluginDriver
existingNames: Record<string, any>
): string {
const hash = createHash();
hash.update(
Expand All @@ -810,8 +803,8 @@ export default class Chunk {
if (current instanceof ExternalModule) {
hash.update(':' + current.renderPath);
} else {
hash.update(current.getRenderedHash(outputPluginDriver));
hash.update(current.generateId(addons, options, existingNames, false, outputPluginDriver));
hash.update(current.getRenderedHash());
hash.update(current.generateId(addons, options, existingNames, false));
}
if (current instanceof ExternalModule) continue;
for (const dependency of [...current.dependencies, ...current.dynamicDependencies]) {
Expand Down Expand Up @@ -874,13 +867,10 @@ export default class Chunk {
}
}

private finaliseImportMetas(
format: InternalModuleFormat,
outputPluginDriver: PluginDriver
): void {
private finaliseImportMetas(format: InternalModuleFormat): void {
for (const [module, code] of this.renderedModuleSources) {
for (const importMeta of module.importMetas) {
importMeta.renderFinalMechanism(code, this.id!, format, outputPluginDriver);
importMeta.renderFinalMechanism(code, this.id!, format, this.pluginDriver);
}
}
}
Expand Down Expand Up @@ -1048,6 +1038,19 @@ export default class Chunk {
return getAliasName(this.orderedModules[this.orderedModules.length - 1].id);
}

private getReferencedFiles(): string[] {
const referencedFiles: string[] = [];
for (const module of this.orderedModules) {
for (const meta of module.importMetas) {
const fileName = meta.getReferencedFileName(this.pluginDriver);
if (fileName) {
referencedFiles.push(fileName);
}
}
}
return referencedFiles;
}

private getRelativePath(targetPath: string, stripJsExtension: boolean): string {
let relativePath = normalize(relative(dirname(this.id!), targetPath));
if (stripJsExtension && relativePath.endsWith('.js')) {
Expand Down
46 changes: 25 additions & 21 deletions src/ast/nodes/MetaProperty.ts
Expand Up @@ -20,6 +20,14 @@ export default class MetaProperty extends NodeBase {

private metaProperty?: string | null;

getReferencedFileName(outputPluginDriver: PluginDriver): string | null {
const metaProperty = this.metaProperty as string | null;
if (metaProperty && metaProperty.startsWith(FILE_PREFIX)) {
return outputPluginDriver.getFileName(metaProperty.substr(FILE_PREFIX.length));
}
return null;
}

hasEffects(): boolean {
return false;
}
Expand All @@ -31,37 +39,33 @@ export default class MetaProperty extends NodeBase {
include() {
if (!this.included) {
this.included = true;
const parent = this.parent;
const metaProperty = (this.metaProperty =
parent instanceof MemberExpression && typeof parent.propertyKey === 'string'
? parent.propertyKey
: null);
if (
metaProperty &&
(metaProperty.startsWith(FILE_PREFIX) ||
metaProperty.startsWith(ASSET_PREFIX) ||
metaProperty.startsWith(CHUNK_PREFIX))
) {
this.scope.addAccessedGlobalsByFormat(accessedFileUrlGlobals);
} else {
this.scope.addAccessedGlobalsByFormat(accessedMetaUrlGlobals);
if (this.meta.name === 'import') {
this.context.addImportMeta(this);
const parent = this.parent;
const metaProperty = (this.metaProperty =
parent instanceof MemberExpression && typeof parent.propertyKey === 'string'
? parent.propertyKey
: null);
if (
metaProperty &&
(metaProperty.startsWith(FILE_PREFIX) ||
metaProperty.startsWith(ASSET_PREFIX) ||
metaProperty.startsWith(CHUNK_PREFIX))
) {
this.scope.addAccessedGlobalsByFormat(accessedFileUrlGlobals);
} else {
this.scope.addAccessedGlobalsByFormat(accessedMetaUrlGlobals);
}
}
}
}

initialise() {
if (this.meta.name === 'import') {
this.context.addImportMeta(this);
}
}

renderFinalMechanism(
code: MagicString,
chunkId: string,
format: InternalModuleFormat,
outputPluginDriver: PluginDriver
): void {
if (!this.included) return;
const parent = this.parent;
const metaProperty = this.metaProperty as string | null;

Expand Down
1 change: 1 addition & 0 deletions src/rollup/types.d.ts
Expand Up @@ -681,6 +681,7 @@ export interface RenderedChunk extends PreRenderedChunk {
implicitlyLoadedBefore: string[];
imports: string[];
map?: SourceMap;
referencedFiles: string[];
}

export interface OutputChunk extends RenderedChunk {
Expand Down

This file was deleted.

This file was deleted.

@@ -0,0 +1,39 @@
const assert = require('assert');

module.exports = {
description: 'lists referenced files in the bundle',
options: {
input: 'main',
plugins: {
transform() {
return `export const asset = import.meta.ROLLUP_FILE_URL_${this.emitFile({
type: 'asset',
name: 'asset.txt',
source: 'asset'
})};\nexport const chunk = import.meta.ROLLUP_FILE_URL_${this.emitFile({
type: 'chunk',
id: 'ref.js'
})}`;
},
generateBundle(options, bundle) {
assert.deepStrictEqual(bundle['main.js'].referencedFiles, [
'assets/asset.txt',
'chunks/ref.js'
]);
}
},
output: {
assetFileNames: 'assets/[name][extname]',
chunkFileNames: 'chunks/[name].js'
}
},
context: {
__dirname: 'dir'
},
exports(exports) {
assert.deepStrictEqual(exports, {
asset: 'file:///dir/assets/asset.txt',
chunk: 'file:///dir/chunks/ref.js'
});
}
};
@@ -0,0 +1 @@
throw new Error('not executed');
@@ -0,0 +1 @@
console.log('Hello');
2 changes: 1 addition & 1 deletion test/watch/index.js
Expand Up @@ -1243,7 +1243,7 @@ describe('rollup.watch', () => {
'END',
() => {
assert.strictEqual(run('../_tmp/output/bundle.js'), 42);
assert.strictEqual(watchChangeIds.size, 0);
assert.deepStrictEqual([...watchChangeIds], []);
for (const file of watchFiles) sander.writeFileSync(file, 'changed');
},
'START',
Expand Down