Skip to content

Commit

Permalink
[v2.0.0] Remove experimentalOptimizeChunks (#3343)
Browse files Browse the repository at this point in the history
* [v2.0.0] Update minimum required Node version to 10 (#3346)

* Update CI to only run on Node 10 and 12, add engines to package.json

* Update TypeScript target

* Remove Bublé as a transpilation option from tests (it is still needed in sourcemap tests)

* Remove minNodeVersion form tests

* Reformat package.json

* [v2.0.0] Bundle chokidar (#3331)

* Create a separate chunk for watch mode via a dynamic import

* Bundle chokidar

* Handle conditional fsevents import

* Only run tests on Node 10 and 12 as we want to do this anyway and chokidar depends on utils.promisify

* Improve chunking

* Refactor and simplify watcher

* Make watcher a proper parameter

* Only unwatch and watch on Linux systems

* No longer run JS files through TypeScript for improved bundling performance

* [v2.0.0] Remove active deprecations (#3352)

* Remove active deprecations

* Make inactive deprecations active

* Improve coverage

* Improve coverage

* Refine transformer

* Improve coverage

* Refactoring option normalization

* Improve coverage

* Remove experimentalOptimizeChunks

* Remove more unused code
  • Loading branch information
lukastaegert committed Mar 6, 2020
1 parent 54220eb commit 4132844
Show file tree
Hide file tree
Showing 68 changed files with 68 additions and 716 deletions.
23 changes: 23 additions & 0 deletions build-plugins/fix-acorn-esm-import.js
@@ -0,0 +1,23 @@
const expectedAcornImport = "import acorn, { Parser } from 'acorn';";
const newAcornImport = "import * as acorn from 'acorn';\nimport { Parser } from 'acorn';";

// by default, rollup-plugin-commonjs will translate require statements as default imports
// which can cause issues for secondary tools that use the ESM version of acorn
export default function fixAcornEsmImport() {
let found = false;

return {
name: 'fix-acorn-esm-import',
renderChunk(code) {
return code.replace(expectedAcornImport, () => {
found = true;
return newAcornImport;
});
},
writeBundle() {
if (!found) {
this.error('Could not find expected acorn import, please examine generated code.');
}
}
};
}
2 changes: 0 additions & 2 deletions docs/01-command-line-reference.md
Expand Up @@ -53,9 +53,7 @@ export default { // can be an array (for multiple inputs)
treeshake,

// experimental
chunkGroupingSize,
experimentalCacheExpiry,
experimentalOptimizeChunks,
perf,

output: { // required (can be an array, for multiple outputs)
Expand Down
2 changes: 0 additions & 2 deletions docs/02-javascript-api.md
Expand Up @@ -96,9 +96,7 @@ const inputOptions = {
treeshake,

// experimental
chunkGroupingSize,
experimentalCacheExpiry,
experimentalOptimizeChunks,
perf
};
```
Expand Down
14 changes: 0 additions & 14 deletions docs/999-big-list-of-options.md
Expand Up @@ -1053,27 +1053,13 @@ In the example, the last line is always retained as accessing the `element` prop

These options reflect new features that have not yet been fully finalized. Availability, behaviour and usage may therefore be subject to change between minor versions.

#### chunkGroupingSize
Type: `number`<br>
CLI: `--chunkGroupingSize <size>`<br>
Default: `5000`

The total source length allowed to be loaded unnecessarily when using `experimentalOptimizeChunks`.

#### experimentalCacheExpiry
Type: `number`<br>
CLI: `--experimentalCacheExpiry <numberOfRuns>`<br>
Default: `10`

Determines after how many runs cached assets that are no longer used by plugins should be removed.

#### experimentalOptimizeChunks
Type: `boolean`<br>
CLI: `--experimentalOptimizeChunks`/`--no-experimentalOptimizeChunks`<br>
Default: `false`

Experimental feature to optimize chunk groupings. When a large number of chunks are generated, this allows smaller chunks to group together as long as they are within the `chunkGroupingSize` limit. It results in unnecessary code being loaded in some cases in order to have a smaller number of chunks overall. Disabled by default as it may cause unwanted side effects when loading unexpected code.

#### perf
Type: `boolean`<br>
CLI: `--perf`/`--no-perf`<br>
Expand Down
137 changes: 0 additions & 137 deletions src/Chunk.ts
Expand Up @@ -167,7 +167,6 @@ export default class Chunk {
private renderedHash: string = undefined as any;
private renderedModuleSources = new Map<Module, MagicString>();
private renderedSource: MagicStringBundle | null = null;
private renderedSourceLength: number = undefined as any;
private sortedExportNames: string[] | null = null;

constructor(graph: Graph, orderedModules: Module[]) {
Expand Down Expand Up @@ -383,11 +382,6 @@ export default class Chunk {
return (this.renderedHash = hash.digest('hex'));
}

getRenderedSourceLength() {
if (this.renderedSourceLength !== undefined) return this.renderedSourceLength;
return (this.renderedSourceLength = (this.renderedSource as MagicStringBundle).length());
}

getVariableExportName(variable: Variable): string {
if (this.graph.preserveModules && variable instanceof NamespaceVariable) {
return '*';
Expand All @@ -406,119 +400,6 @@ export default class Chunk {
}
}

/*
* Performs a full merge of another chunk into this chunk
* chunkList allows updating references in other chunks for the merged chunk to this chunk
* A new facade will be added to chunkList if tainting exports of either as an entry point
*/
merge(chunk: Chunk, chunkList: Chunk[], options: OutputOptions, inputBase: string) {
if (this.facadeModule !== null || chunk.facadeModule !== null)
throw new Error('Internal error: Code splitting chunk merges not supported for facades');

for (const module of chunk.orderedModules) {
module.chunk = this;
this.orderedModules.push(module);
}

for (const variable of chunk.imports) {
if (!this.imports.has(variable) && (variable.module as Module).chunk !== this) {
this.imports.add(variable);
}
}

// NB detect when exported variables are orphaned by the merge itself
// (involves reverse tracing dependents)
for (const variable of chunk.exports) {
if (!this.exports.has(variable)) {
this.exports.add(variable);
}
}

const thisOldExportNames = this.exportNames;

// regenerate internal names
this.generateInternalExports(options);

const updateRenderedDeclaration = (
dep: ModuleDeclarationDependency,
oldExportNames: Record<string, Variable>
) => {
if (dep.imports) {
for (const impt of dep.imports) {
impt.imported = this.getVariableExportName(oldExportNames[impt.imported]);
}
}
if (dep.reexports) {
for (const reexport of dep.reexports) {
reexport.imported = this.getVariableExportName(oldExportNames[reexport.imported]);
}
}
};

const mergeRenderedDeclaration = (
into: ModuleDeclarationDependency,
from: ModuleDeclarationDependency
) => {
if (from.imports) {
if (!into.imports) {
into.imports = from.imports;
} else {
into.imports = into.imports.concat(from.imports);
}
}
if (from.reexports) {
if (!into.reexports) {
into.reexports = from.reexports;
} else {
into.reexports = into.reexports.concat(from.reexports);
}
}
if (!into.exportsNames && from.exportsNames) {
into.exportsNames = true;
}
if (!into.exportsDefault && from.exportsDefault) {
into.exportsDefault = true;
}
into.name = this.variableName;
};

// go through the other chunks and update their dependencies
// also update their import and reexport names in the process
for (const c of chunkList) {
let includedDeclaration: ModuleDeclarationDependency = undefined as any;
const dependencies = Array.from(c.dependencies);
const renderedDependencies = dependencies.map(dep => c.renderedDependencies!.get(dep));
for (let i = 0; i < dependencies.length; i++) {
const dep = dependencies[i];
if ((dep === chunk || dep === this) && includedDeclaration) {
const duplicateDeclaration = renderedDependencies[i]!;
updateRenderedDeclaration(
duplicateDeclaration,
dep === chunk ? chunk.exportNames : thisOldExportNames
);
mergeRenderedDeclaration(includedDeclaration, duplicateDeclaration);
renderedDependencies.splice(i, 1);
dependencies.splice(i--, 1);
} else if (dep === chunk) {
dependencies[i] = this;
includedDeclaration = renderedDependencies[i]!;
updateRenderedDeclaration(includedDeclaration, chunk.exportNames);
} else if (dep === this) {
includedDeclaration = renderedDependencies[i]!;
updateRenderedDeclaration(includedDeclaration, thisOldExportNames);
}
}
c.dependencies = new Set(dependencies);
c.renderedDependencies = new Map();
for (let i = 0; i < dependencies.length; i++) {
c.renderedDependencies.set(dependencies[i], renderedDependencies[i]!);
}
}

// re-render the merged chunk
this.preRender(options, inputBase);
}

// prerender allows chunk hashes and names to be generated before finalizing
preRender(options: OutputOptions, inputBase: string) {
timeStart('render modules', 3);
Expand Down Expand Up @@ -601,7 +482,6 @@ export default class Chunk {
this.renderedSource = magicString.trim();
}

this.renderedSourceLength = undefined as any;
this.renderedHash = undefined as any;

if (this.isEmpty && this.getExportNames().length === 0 && this.dependencies.size === 0) {
Expand Down Expand Up @@ -749,23 +629,6 @@ export default class Chunk {
});
}

visitStaticDependenciesUntilCondition(
isConditionSatisfied: (dep: Chunk | ExternalModule) => any
): boolean {
const seen = new Set<Chunk | ExternalModule>();
function visitDep(dep: Chunk | ExternalModule): boolean {
if (seen.has(dep)) return undefined as any;
seen.add(dep);
if (dep instanceof Chunk) {
for (const subDep of dep.dependencies) {
if (visitDep(subDep)) return true;
}
}
return isConditionSatisfied(dep) === true;
}
return visitDep(this);
}

private addDependenciesToChunk(
moduleDependencies: Set<Module | ExternalModule>,
chunkDependencies: Set<Chunk | ExternalModule>
Expand Down
138 changes: 0 additions & 138 deletions src/chunk-optimization.ts

This file was deleted.

0 comments on commit 4132844

Please sign in to comment.