From c87132b1aa1c8e81102adb128bf6f738b50153f9 Mon Sep 17 00:00:00 2001 From: Lukas Taegert-Atkinson Date: Tue, 11 Dec 2018 07:51:35 +0100 Subject: [PATCH] Refactor chunking algorithm (#2575) * Split up misc tests * Create basic bundle information test * * Make sure "isEntry" is only true for entry facades * Give precedence to entry facades when deconflicting ids * Add entryModuleId to entry facades * * Mark dynamic entry points as such and separate this from actual entry points * Use internal names for dynamic entry points * Do not generate dynamic entry points that are not used * Add entryModuleIds to both static and dynamic entry points * Add name to output * Separate execution order from chunk colouring * Prefer named export and do not mix for better IDE support * Move chunk colouring behind tree-shaking and add more tests * Use dynamic import tree-shaking information to optimize chunks * Create proper facades for dynamic imports if necessary that are actually used in place of the facaded module. Also no longer inline dynamic imports that are part of the static graph for now as this logic would fail if those are then dynamically imported by another chunk. * As with normal imports, also use single quotes for dynamic imports * Test we provide the right chunk information for dynamic facades * Move facadeChunk property to modules * Refactor entry export generation to prepare for multiple entry modules * Make entryModuleIds a Set on each module * Support manual chunks with multiple facades * Handle name conflicts between dynamic entries in manual chunks * Simplify tracing * A chunk may only ever be facade for a single module to simplify the logic Also delete tests that have been skipped for years. Let's rather make a fresh start should the problem still persists and someone care to address it. * Add information about dynamically imported chunks to bundle * Make "optimizeImports" an experimental option to reflect that the logic is complicated and may not have been properly tested in all situations. * Make sure tree-shaken dynamic imports do not lead to the creation of namespace objects when inlined --- src/Chunk.ts | 274 ++++---- src/ExternalModule.ts | 6 +- src/Graph.ts | 176 +++--- src/Module.ts | 126 ++-- src/ast/nodes/Import.ts | 13 +- src/ast/nodes/Program.ts | 3 +- src/chunk-optimization.ts | 4 +- src/finalisers/iife.ts | 2 +- src/finalisers/umd.ts | 2 +- src/rollup/index.ts | 85 ++- src/rollup/types.d.ts | 10 +- src/utils/addons.ts | 2 +- src/utils/assetHooks.ts | 2 +- src/utils/assignChunkIds.ts | 50 ++ src/utils/chunkColouring.ts | 83 +++ src/utils/collapseSourcemaps.ts | 2 +- .../{default-plugin.ts => defaultPlugin.ts} | 2 +- src/utils/error.ts | 2 +- src/utils/execution-order.ts | 147 ----- src/utils/executionOrder.ts | 89 +++ src/utils/getExportMode.ts | 9 +- src/utils/mergeOptions.ts | 2 +- src/utils/pluginDriver.ts | 4 +- src/utils/renderChunk.ts | 2 +- src/utils/renderNamePattern.ts | 2 +- src/utils/transform.ts | 2 +- src/utils/traverseStaticDependencies.ts | 19 + .../samples/aliasing-extensions/_config.js | 5 +- .../{main4.dynamic.js => generated-chunk.js} | 0 .../amd/{main5.js => generated-chunk2.js} | 0 .../_expected/amd/main1.js | 4 +- .../{main4.dynamic.js => generated-chunk.js} | 0 .../cjs/{main5.js => generated-chunk2.js} | 0 .../_expected/cjs/main1.js | 4 +- .../{main4.dynamic.js => generated-chunk.js} | 0 .../es/{main5.js => generated-chunk2.js} | 0 .../aliasing-extensions/_expected/es/main1.js | 4 +- .../{main4.dynamic.js => generated-chunk.js} | 0 .../system/{main5.js => generated-chunk2.js} | 0 .../_expected/system/main1.js | 4 +- .../samples/dynamic-import-chained/_config.js | 9 + .../_expected/amd/generated-chunk.js} | 2 +- .../_expected/amd/generated-chunk2.js | 6 + .../_expected/amd/main.js | 6 + .../_expected/cjs/generated-chunk.js | 3 + .../_expected/cjs/generated-chunk2.js | 4 + .../_expected/cjs/main.js | 4 + .../_expected/es/generated-chunk.js | 1 + .../_expected/es/generated-chunk2.js | 2 + .../_expected/es/main.js | 2 + .../_expected/system/generated-chunk.js} | 2 +- .../_expected/system/generated-chunk2.js | 11 + .../_expected/system/main.js | 11 + .../samples/dynamic-import-chained/dep1.js | 2 + .../samples/dynamic-import-chained/dep2.js | 1 + .../samples/dynamic-import-chained/main.js | 5 + .../_expected/amd/chunk-8ea4f89e.js} | 2 - .../_expected/amd/dep2.js | 11 - .../_expected/amd/main.js | 2 +- .../_expected/cjs/chunk-38762abc.js} | 2 - .../_expected/cjs/dep2.js | 11 - .../_expected/cjs/main.js | 2 +- .../es/{dep2.js => chunk-a97cfc63.js} | 0 .../_expected/es/main.js | 2 +- .../system/{dep2.js => chunk-b7f9caf2.js} | 0 .../_expected/system/main.js | 2 +- .../samples/dynamic-import-facade/_config.js | 6 + .../_expected/amd/chunk-822f1303.js | 7 + .../_expected/amd/chunk-d42319c1.js | 13 + .../_expected/amd/main1.js | 5 + .../_expected/amd/main2.js | 5 + .../_expected/cjs/chunk-0ad7c258.js | 7 + .../_expected/cjs/chunk-57ff6d6d.js | 11 + .../_expected/cjs/main1.js | 3 + .../_expected/cjs/main2.js | 5 + .../_expected/es/chunk-9fd0b968.js | 1 + .../_expected/es/chunk-fa3f0c72.js | 8 + .../_expected/es/main1.js | 1 + .../_expected/es/main2.js | 3 + .../_expected/system/chunk-55e635b3.js | 15 + .../_expected/system/chunk-d225f367.js | 13 + .../_expected/system/main1.js | 10 + .../_expected/system/main2.js | 15 + .../samples/dynamic-import-facade/dep.js | 3 + .../samples/dynamic-import-facade/dynamic.js | 4 + .../samples/dynamic-import-facade/main1.js | 1 + .../samples/dynamic-import-facade/main2.js | 4 + .../_config.js | 4 +- .../_expected/amd/chunk-a2558f00.js | 9 + .../_expected/amd/chunk-d309b27d.js | 9 + .../_expected/amd/main.js | 13 - .../_expected/amd/main1.js | 11 + .../_expected/amd/main2.js | 9 + .../_expected/cjs/chunk-bc97caee.js | 7 + .../_expected/cjs/chunk-e4f8b8db.js | 7 + .../_expected/cjs/main.js | 11 - .../_expected/cjs/main1.js | 12 + .../_expected/cjs/main2.js | 7 + .../_expected/es/chunk-61f7224d.js | 5 + .../_expected/es/chunk-6d572aec.js | 5 + .../_expected/es/main.js | 9 - .../_expected/es/main1.js | 7 + .../_expected/es/main2.js | 3 + .../_expected/system/chunk-9df34bdb.js | 11 + .../_expected/system/chunk-cdaf79ed.js | 11 + .../_expected/system/main.js | 16 - .../_expected/system/main1.js | 12 + .../_expected/system/main2.js | 10 + .../dynamic-import-inline-colouring/foo.js | 1 - .../inlined.js | 2 + .../dynamic-import-inline-colouring/main.js | 3 - .../dynamic-import-inline-colouring/main1.js | 5 + .../dynamic-import-inline-colouring/main2.js | 1 + .../separate.js | 2 + .../dynamic-import-tree-shaking-1/_config.js | 12 + .../_expected/amd/entryA.js | 9 + .../_expected/amd/entryB.js | 5 + .../_expected/cjs/entryA.js | 7 + .../_expected/cjs/entryB.js | 3 + .../_expected/es/entryA.js | 5 + .../_expected/es/entryB.js | 1 + .../_expected/system/entryA.js | 14 + .../_expected/system/entryB.js} | 2 +- .../dynamic-import-tree-shaking-1/dep.js | 3 + .../dynamic-import-tree-shaking-1/dep2.js | 3 + .../dynamic-import-tree-shaking-1/main1.js | 3 + .../dynamic-import-tree-shaking-1/main2.js | 5 + .../dynamic-import-tree-shaking-2/_config.js | 6 + .../_expected/amd/main1.js | 5 + .../_expected/amd/main2.js | 10 + .../_expected/cjs/main1.js | 3 + .../_expected/cjs/main2.js | 8 + .../_expected/es/main1.js | 1 + .../_expected/es/main2.js | 6 + .../_expected/system/main1.js | 10 + .../_expected/system/main2.js | 15 + .../dynamic-import-tree-shaking-2/dep.js | 2 + .../dynamic-import-tree-shaking-2/dynamic.js | 4 + .../dynamic-import-tree-shaking-2/main1.js | 4 + .../dynamic-import-tree-shaking-2/main2.js | 4 + .../dynamic-import-treeshaking/_config.js | 6 - .../_expected/amd/main.js | 13 - .../_expected/cjs/chunk-3a53aa58.js | 5 - .../_expected/cjs/main.js | 13 - .../_expected/es/chunk-713732d9.js | 3 - .../_expected/es/dep2.js | 7 - .../_expected/es/main.js | 11 - .../_expected/system/dep2.js | 18 - .../_expected/system/main.js | 22 - .../dynamic-import-treeshaking/dep1.js | 12 - .../dynamic-import-treeshaking/dep2.js | 5 - .../dynamic-import-treeshaking/dep3.js | 5 - .../dynamic-import-treeshaking/dep4.js | 1 - .../dynamic-import-treeshaking/main.js | 3 - .../samples/grouping-multiple/_config.js | 2 +- .../samples/grouping-size/_config.js | 2 +- .../manual-chunks-dynamic-facades/_config.js | 12 + .../_expected/amd/generated-dynamic.js | 16 + .../_expected/amd/generated-dynamic2.js | 7 + .../_expected/amd/generated-dynamic3.js | 7 + .../_expected/amd/main.js | 7 + .../_expected/cjs/generated-dynamic.js | 14 + .../_expected/cjs/generated-dynamic2.js | 7 + .../_expected/cjs/generated-dynamic3.js | 7 + .../_expected/cjs/main.js | 7 + .../_expected/es/generated-dynamic.js | 9 + .../_expected/es/generated-dynamic2.js | 1 + .../_expected/es/generated-dynamic3.js | 1 + .../_expected/es/main.js | 5 + .../_expected/system/generated-dynamic.js | 16 + .../_expected/system/generated-dynamic2.js | 13 + .../_expected/system/generated-dynamic3.js | 13 + .../_expected/system/main.js | 16 + .../manual-chunks-dynamic-facades/dep.js | 1 + .../manual-chunks-dynamic-facades/dynamic1.js | 4 + .../manual-chunks-dynamic-facades/dynamic2.js | 1 + .../manual-chunks-dynamic-facades/dynamic3.js | 1 + .../manual-chunks-dynamic-facades/main.js | 5 + .../_config.js | 12 + .../_expected/amd/generated-dynamic.js | 13 + .../_expected/amd/generated-dynamic2.js | 8 + .../_expected/amd/main.js | 6 + .../_expected/cjs/generated-dynamic.js | 11 + .../_expected/cjs/generated-dynamic2.js | 8 + .../_expected/cjs/main.js | 4 + .../_expected/es/generated-dynamic.js | 8 + .../_expected/es/generated-dynamic2.js | 1 + .../_expected/es/main.js | 2 + .../_expected/system/generated-dynamic.js | 15 + .../_expected/system/generated-dynamic2.js | 16 + .../_expected/system/main.js | 11 + .../dynamic1.js | 3 + .../dynamic2.js | 4 + .../main.js | 2 + .../samples/manual-chunks-dynamic/_config.js | 6 +- .../_expected/amd/generated-dynamic.js | 7 + .../_expected/amd/main.js | 2 +- .../_expected/cjs/dynamic-5ab72169.js | 2 - .../_expected/cjs/generated-dynamic.js | 5 + .../_expected/cjs/main.js | 2 +- .../_expected/es/dynamic-12dc935a.js | 1 - .../_expected/es/generated-dynamic.js | 3 + .../_expected/es/main.js | 2 +- .../_expected/system/generated-dynamic.js | 10 + .../_expected/system/main.js | 2 +- .../samples/manual-chunks-dynamic/main.js | 2 +- ...and3-0c5d98d0.js => deps2and3-609a33db.js} | 4 +- .../manual-chunks/_expected/amd/main.js | 6 +- ...and3-9aeb2d5b.js => deps2and3-c8fe246d.js} | 4 +- .../manual-chunks/_expected/cjs/main.js | 6 +- .../_expected/es/index-6a71658c.js | 3 +- .../namespace-reexports/_expected/es/index.js | 2 +- .../namespace-reexports/_expected/es/main.js | 4 +- .../{index-8b381a8d.js => index-51f0f10d.js} | 3 +- .../_expected/system/index.js | 4 +- .../_expected/system/main.js | 8 +- .../_config.js | 7 + .../_expected/amd/dynamic-included.js} | 4 +- .../_expected/amd/main.js | 5 + .../_expected/cjs/dynamic-included.js | 5 + .../_expected/cjs/main.js | 3 + .../_expected/es/dynamic-included.js | 3 + .../_expected/es/main.js | 1 + .../_expected/system/dynamic-included.js | 10 + .../_expected/system/main.js | 10 + .../dynamic-included.js | 1 + .../dynamic-removed.js | 1 + .../preserve-modules-dynamic-imports/main.js | 6 + .../default-identifier-deshadowing/dep.js | 2 +- .../dynamic-import-inlining/_expected.js | 6 +- .../samples/dynamic-import-inlining/main.js | 5 +- .../_config.js | 6 + .../_expected/amd.js | 5 + .../_expected/cjs.js | 3 + .../_expected/es.js | 1 + .../_expected/iife.js | 6 + .../_expected/system.js | 10 + .../_expected/umd.js | 9 + .../dynamic.js | 2 + .../inlined-treeshaken-dynamic-import/main.js | 2 + .../function/samples/cycles-pathological/A.js | 11 - .../function/samples/cycles-pathological/B.js | 8 - .../function/samples/cycles-pathological/C.js | 8 - .../function/samples/cycles-pathological/D.js | 11 - .../samples/cycles-pathological/_config.js | 17 - .../samples/cycles-pathological/main.js | 12 - .../samples/iife-strong-dependencies/A.js | 15 - .../samples/iife-strong-dependencies/B.js | 11 - .../samples/iife-strong-dependencies/C.js | 11 - .../samples/iife-strong-dependencies/D.js | 15 - .../iife-strong-dependencies/_config.js | 16 - .../samples/iife-strong-dependencies/main.js | 14 - .../inline-imports-with-manual/_config.js | 15 + .../samples/inline-imports-with-manual/lib.js | 1 + .../inline-imports-with-manual/main.js | 1 + .../inline-imports-with-multiple/_config.js | 12 + .../inline-imports-with-multiple/lib.js | 1 + .../inline-imports-with-multiple/main.js | 1 + .../inline-imports-with-optimize/_config.js | 13 + .../inline-imports-with-optimize/lib.js | 1 + .../inline-imports-with-optimize/main.js | 1 + .../preserve-modules-with-inline/_config.js | 13 + .../preserve-modules-with-inline/lib.js | 1 + .../preserve-modules-with-inline/main.js | 1 + .../preserve-modules-with-manual/_config.js | 15 + .../preserve-modules-with-manual/lib.js | 1 + .../preserve-modules-with-manual/main.js | 3 + .../preserve-modules-with-optimize/_config.js | 13 + .../preserve-modules-with-optimize/lib.js | 1 + .../preserve-modules-with-optimize/main.js | 3 + test/hooks/index.js | 12 +- test/misc/acorn-plugins.js | 124 ++++ test/misc/bundle-information.js | 419 +++++++++++++ test/misc/deprecations.js | 93 +++ test/misc/in-memory-sourcemaps.js | 33 + test/misc/index.js | 590 +----------------- test/misc/misc.js | 73 +++ test/misc/optionList.js | 4 +- test/misc/sanity-checks.js | 159 +++++ test/misc/write-bundle.js | 116 ++++ 280 files changed, 2708 insertions(+), 1522 deletions(-) create mode 100644 src/utils/assignChunkIds.ts create mode 100644 src/utils/chunkColouring.ts rename src/utils/{default-plugin.ts => defaultPlugin.ts} (98%) delete mode 100644 src/utils/execution-order.ts create mode 100644 src/utils/executionOrder.ts create mode 100644 src/utils/traverseStaticDependencies.ts rename test/chunking-form/samples/aliasing-extensions/_expected/amd/{main4.dynamic.js => generated-chunk.js} (100%) rename test/chunking-form/samples/aliasing-extensions/_expected/amd/{main5.js => generated-chunk2.js} (100%) rename test/chunking-form/samples/aliasing-extensions/_expected/cjs/{main4.dynamic.js => generated-chunk.js} (100%) rename test/chunking-form/samples/aliasing-extensions/_expected/cjs/{main5.js => generated-chunk2.js} (100%) rename test/chunking-form/samples/aliasing-extensions/_expected/es/{main4.dynamic.js => generated-chunk.js} (100%) rename test/chunking-form/samples/aliasing-extensions/_expected/es/{main5.js => generated-chunk2.js} (100%) rename test/chunking-form/samples/aliasing-extensions/_expected/system/{main4.dynamic.js => generated-chunk.js} (100%) rename test/chunking-form/samples/aliasing-extensions/_expected/system/{main5.js => generated-chunk2.js} (100%) create mode 100644 test/chunking-form/samples/dynamic-import-chained/_config.js rename test/chunking-form/samples/{manual-chunks-dynamic/_expected/amd/dynamic-10698fc3.js => dynamic-import-chained/_expected/amd/generated-chunk.js} (65%) create mode 100644 test/chunking-form/samples/dynamic-import-chained/_expected/amd/generated-chunk2.js create mode 100644 test/chunking-form/samples/dynamic-import-chained/_expected/amd/main.js create mode 100644 test/chunking-form/samples/dynamic-import-chained/_expected/cjs/generated-chunk.js create mode 100644 test/chunking-form/samples/dynamic-import-chained/_expected/cjs/generated-chunk2.js create mode 100644 test/chunking-form/samples/dynamic-import-chained/_expected/cjs/main.js create mode 100644 test/chunking-form/samples/dynamic-import-chained/_expected/es/generated-chunk.js create mode 100644 test/chunking-form/samples/dynamic-import-chained/_expected/es/generated-chunk2.js create mode 100644 test/chunking-form/samples/dynamic-import-chained/_expected/es/main.js rename test/chunking-form/samples/{manual-chunks-dynamic/_expected/system/dynamic-e8bd5876.js => dynamic-import-chained/_expected/system/generated-chunk.js} (82%) create mode 100644 test/chunking-form/samples/dynamic-import-chained/_expected/system/generated-chunk2.js create mode 100644 test/chunking-form/samples/dynamic-import-chained/_expected/system/main.js create mode 100644 test/chunking-form/samples/dynamic-import-chained/dep1.js create mode 100644 test/chunking-form/samples/dynamic-import-chained/dep2.js create mode 100644 test/chunking-form/samples/dynamic-import-chained/main.js rename test/chunking-form/samples/{dynamic-import-treeshaking/_expected/amd/dep2.js => dynamic-import-chunking/_expected/amd/chunk-8ea4f89e.js} (73%) delete mode 100644 test/chunking-form/samples/dynamic-import-chunking/_expected/amd/dep2.js rename test/chunking-form/samples/{dynamic-import-treeshaking/_expected/cjs/dep2.js => dynamic-import-chunking/_expected/cjs/chunk-38762abc.js} (69%) delete mode 100644 test/chunking-form/samples/dynamic-import-chunking/_expected/cjs/dep2.js rename test/chunking-form/samples/dynamic-import-chunking/_expected/es/{dep2.js => chunk-a97cfc63.js} (100%) rename test/chunking-form/samples/dynamic-import-chunking/_expected/system/{dep2.js => chunk-b7f9caf2.js} (100%) create mode 100644 test/chunking-form/samples/dynamic-import-facade/_config.js create mode 100644 test/chunking-form/samples/dynamic-import-facade/_expected/amd/chunk-822f1303.js create mode 100644 test/chunking-form/samples/dynamic-import-facade/_expected/amd/chunk-d42319c1.js create mode 100644 test/chunking-form/samples/dynamic-import-facade/_expected/amd/main1.js create mode 100644 test/chunking-form/samples/dynamic-import-facade/_expected/amd/main2.js create mode 100644 test/chunking-form/samples/dynamic-import-facade/_expected/cjs/chunk-0ad7c258.js create mode 100644 test/chunking-form/samples/dynamic-import-facade/_expected/cjs/chunk-57ff6d6d.js create mode 100644 test/chunking-form/samples/dynamic-import-facade/_expected/cjs/main1.js create mode 100644 test/chunking-form/samples/dynamic-import-facade/_expected/cjs/main2.js create mode 100644 test/chunking-form/samples/dynamic-import-facade/_expected/es/chunk-9fd0b968.js create mode 100644 test/chunking-form/samples/dynamic-import-facade/_expected/es/chunk-fa3f0c72.js create mode 100644 test/chunking-form/samples/dynamic-import-facade/_expected/es/main1.js create mode 100644 test/chunking-form/samples/dynamic-import-facade/_expected/es/main2.js create mode 100644 test/chunking-form/samples/dynamic-import-facade/_expected/system/chunk-55e635b3.js create mode 100644 test/chunking-form/samples/dynamic-import-facade/_expected/system/chunk-d225f367.js create mode 100644 test/chunking-form/samples/dynamic-import-facade/_expected/system/main1.js create mode 100644 test/chunking-form/samples/dynamic-import-facade/_expected/system/main2.js create mode 100644 test/chunking-form/samples/dynamic-import-facade/dep.js create mode 100644 test/chunking-form/samples/dynamic-import-facade/dynamic.js create mode 100644 test/chunking-form/samples/dynamic-import-facade/main1.js create mode 100644 test/chunking-form/samples/dynamic-import-facade/main2.js create mode 100644 test/chunking-form/samples/dynamic-import-inline-colouring/_expected/amd/chunk-a2558f00.js create mode 100644 test/chunking-form/samples/dynamic-import-inline-colouring/_expected/amd/chunk-d309b27d.js delete mode 100644 test/chunking-form/samples/dynamic-import-inline-colouring/_expected/amd/main.js create mode 100644 test/chunking-form/samples/dynamic-import-inline-colouring/_expected/amd/main1.js create mode 100644 test/chunking-form/samples/dynamic-import-inline-colouring/_expected/amd/main2.js create mode 100644 test/chunking-form/samples/dynamic-import-inline-colouring/_expected/cjs/chunk-bc97caee.js create mode 100644 test/chunking-form/samples/dynamic-import-inline-colouring/_expected/cjs/chunk-e4f8b8db.js delete mode 100644 test/chunking-form/samples/dynamic-import-inline-colouring/_expected/cjs/main.js create mode 100644 test/chunking-form/samples/dynamic-import-inline-colouring/_expected/cjs/main1.js create mode 100644 test/chunking-form/samples/dynamic-import-inline-colouring/_expected/cjs/main2.js create mode 100644 test/chunking-form/samples/dynamic-import-inline-colouring/_expected/es/chunk-61f7224d.js create mode 100644 test/chunking-form/samples/dynamic-import-inline-colouring/_expected/es/chunk-6d572aec.js delete mode 100644 test/chunking-form/samples/dynamic-import-inline-colouring/_expected/es/main.js create mode 100644 test/chunking-form/samples/dynamic-import-inline-colouring/_expected/es/main1.js create mode 100644 test/chunking-form/samples/dynamic-import-inline-colouring/_expected/es/main2.js create mode 100644 test/chunking-form/samples/dynamic-import-inline-colouring/_expected/system/chunk-9df34bdb.js create mode 100644 test/chunking-form/samples/dynamic-import-inline-colouring/_expected/system/chunk-cdaf79ed.js delete mode 100644 test/chunking-form/samples/dynamic-import-inline-colouring/_expected/system/main.js create mode 100644 test/chunking-form/samples/dynamic-import-inline-colouring/_expected/system/main1.js create mode 100644 test/chunking-form/samples/dynamic-import-inline-colouring/_expected/system/main2.js delete mode 100644 test/chunking-form/samples/dynamic-import-inline-colouring/foo.js create mode 100644 test/chunking-form/samples/dynamic-import-inline-colouring/inlined.js delete mode 100644 test/chunking-form/samples/dynamic-import-inline-colouring/main.js create mode 100644 test/chunking-form/samples/dynamic-import-inline-colouring/main1.js create mode 100644 test/chunking-form/samples/dynamic-import-inline-colouring/main2.js create mode 100644 test/chunking-form/samples/dynamic-import-inline-colouring/separate.js create mode 100644 test/chunking-form/samples/dynamic-import-tree-shaking-1/_config.js create mode 100644 test/chunking-form/samples/dynamic-import-tree-shaking-1/_expected/amd/entryA.js create mode 100644 test/chunking-form/samples/dynamic-import-tree-shaking-1/_expected/amd/entryB.js create mode 100644 test/chunking-form/samples/dynamic-import-tree-shaking-1/_expected/cjs/entryA.js create mode 100644 test/chunking-form/samples/dynamic-import-tree-shaking-1/_expected/cjs/entryB.js create mode 100644 test/chunking-form/samples/dynamic-import-tree-shaking-1/_expected/es/entryA.js create mode 100644 test/chunking-form/samples/dynamic-import-tree-shaking-1/_expected/es/entryB.js create mode 100644 test/chunking-form/samples/dynamic-import-tree-shaking-1/_expected/system/entryA.js rename test/chunking-form/samples/{dynamic-import-treeshaking/_expected/system/chunk-4d8f4e43.js => dynamic-import-tree-shaking-1/_expected/system/entryB.js} (75%) create mode 100644 test/chunking-form/samples/dynamic-import-tree-shaking-1/dep.js create mode 100644 test/chunking-form/samples/dynamic-import-tree-shaking-1/dep2.js create mode 100644 test/chunking-form/samples/dynamic-import-tree-shaking-1/main1.js create mode 100644 test/chunking-form/samples/dynamic-import-tree-shaking-1/main2.js create mode 100644 test/chunking-form/samples/dynamic-import-tree-shaking-2/_config.js create mode 100644 test/chunking-form/samples/dynamic-import-tree-shaking-2/_expected/amd/main1.js create mode 100644 test/chunking-form/samples/dynamic-import-tree-shaking-2/_expected/amd/main2.js create mode 100644 test/chunking-form/samples/dynamic-import-tree-shaking-2/_expected/cjs/main1.js create mode 100644 test/chunking-form/samples/dynamic-import-tree-shaking-2/_expected/cjs/main2.js create mode 100644 test/chunking-form/samples/dynamic-import-tree-shaking-2/_expected/es/main1.js create mode 100644 test/chunking-form/samples/dynamic-import-tree-shaking-2/_expected/es/main2.js create mode 100644 test/chunking-form/samples/dynamic-import-tree-shaking-2/_expected/system/main1.js create mode 100644 test/chunking-form/samples/dynamic-import-tree-shaking-2/_expected/system/main2.js create mode 100644 test/chunking-form/samples/dynamic-import-tree-shaking-2/dep.js create mode 100644 test/chunking-form/samples/dynamic-import-tree-shaking-2/dynamic.js create mode 100644 test/chunking-form/samples/dynamic-import-tree-shaking-2/main1.js create mode 100644 test/chunking-form/samples/dynamic-import-tree-shaking-2/main2.js delete mode 100644 test/chunking-form/samples/dynamic-import-treeshaking/_config.js delete mode 100644 test/chunking-form/samples/dynamic-import-treeshaking/_expected/amd/main.js delete mode 100644 test/chunking-form/samples/dynamic-import-treeshaking/_expected/cjs/chunk-3a53aa58.js delete mode 100644 test/chunking-form/samples/dynamic-import-treeshaking/_expected/cjs/main.js delete mode 100644 test/chunking-form/samples/dynamic-import-treeshaking/_expected/es/chunk-713732d9.js delete mode 100644 test/chunking-form/samples/dynamic-import-treeshaking/_expected/es/dep2.js delete mode 100644 test/chunking-form/samples/dynamic-import-treeshaking/_expected/es/main.js delete mode 100644 test/chunking-form/samples/dynamic-import-treeshaking/_expected/system/dep2.js delete mode 100644 test/chunking-form/samples/dynamic-import-treeshaking/_expected/system/main.js delete mode 100644 test/chunking-form/samples/dynamic-import-treeshaking/dep1.js delete mode 100644 test/chunking-form/samples/dynamic-import-treeshaking/dep2.js delete mode 100644 test/chunking-form/samples/dynamic-import-treeshaking/dep3.js delete mode 100644 test/chunking-form/samples/dynamic-import-treeshaking/dep4.js delete mode 100644 test/chunking-form/samples/dynamic-import-treeshaking/main.js create mode 100644 test/chunking-form/samples/manual-chunks-dynamic-facades/_config.js create mode 100644 test/chunking-form/samples/manual-chunks-dynamic-facades/_expected/amd/generated-dynamic.js create mode 100644 test/chunking-form/samples/manual-chunks-dynamic-facades/_expected/amd/generated-dynamic2.js create mode 100644 test/chunking-form/samples/manual-chunks-dynamic-facades/_expected/amd/generated-dynamic3.js create mode 100644 test/chunking-form/samples/manual-chunks-dynamic-facades/_expected/amd/main.js create mode 100644 test/chunking-form/samples/manual-chunks-dynamic-facades/_expected/cjs/generated-dynamic.js create mode 100644 test/chunking-form/samples/manual-chunks-dynamic-facades/_expected/cjs/generated-dynamic2.js create mode 100644 test/chunking-form/samples/manual-chunks-dynamic-facades/_expected/cjs/generated-dynamic3.js create mode 100644 test/chunking-form/samples/manual-chunks-dynamic-facades/_expected/cjs/main.js create mode 100644 test/chunking-form/samples/manual-chunks-dynamic-facades/_expected/es/generated-dynamic.js create mode 100644 test/chunking-form/samples/manual-chunks-dynamic-facades/_expected/es/generated-dynamic2.js create mode 100644 test/chunking-form/samples/manual-chunks-dynamic-facades/_expected/es/generated-dynamic3.js create mode 100644 test/chunking-form/samples/manual-chunks-dynamic-facades/_expected/es/main.js create mode 100644 test/chunking-form/samples/manual-chunks-dynamic-facades/_expected/system/generated-dynamic.js create mode 100644 test/chunking-form/samples/manual-chunks-dynamic-facades/_expected/system/generated-dynamic2.js create mode 100644 test/chunking-form/samples/manual-chunks-dynamic-facades/_expected/system/generated-dynamic3.js create mode 100644 test/chunking-form/samples/manual-chunks-dynamic-facades/_expected/system/main.js create mode 100644 test/chunking-form/samples/manual-chunks-dynamic-facades/dep.js create mode 100644 test/chunking-form/samples/manual-chunks-dynamic-facades/dynamic1.js create mode 100644 test/chunking-form/samples/manual-chunks-dynamic-facades/dynamic2.js create mode 100644 test/chunking-form/samples/manual-chunks-dynamic-facades/dynamic3.js create mode 100644 test/chunking-form/samples/manual-chunks-dynamic-facades/main.js create mode 100644 test/chunking-form/samples/manual-chunks-dynamic-name-conflict/_config.js create mode 100644 test/chunking-form/samples/manual-chunks-dynamic-name-conflict/_expected/amd/generated-dynamic.js create mode 100644 test/chunking-form/samples/manual-chunks-dynamic-name-conflict/_expected/amd/generated-dynamic2.js create mode 100644 test/chunking-form/samples/manual-chunks-dynamic-name-conflict/_expected/amd/main.js create mode 100644 test/chunking-form/samples/manual-chunks-dynamic-name-conflict/_expected/cjs/generated-dynamic.js create mode 100644 test/chunking-form/samples/manual-chunks-dynamic-name-conflict/_expected/cjs/generated-dynamic2.js create mode 100644 test/chunking-form/samples/manual-chunks-dynamic-name-conflict/_expected/cjs/main.js create mode 100644 test/chunking-form/samples/manual-chunks-dynamic-name-conflict/_expected/es/generated-dynamic.js create mode 100644 test/chunking-form/samples/manual-chunks-dynamic-name-conflict/_expected/es/generated-dynamic2.js create mode 100644 test/chunking-form/samples/manual-chunks-dynamic-name-conflict/_expected/es/main.js create mode 100644 test/chunking-form/samples/manual-chunks-dynamic-name-conflict/_expected/system/generated-dynamic.js create mode 100644 test/chunking-form/samples/manual-chunks-dynamic-name-conflict/_expected/system/generated-dynamic2.js create mode 100644 test/chunking-form/samples/manual-chunks-dynamic-name-conflict/_expected/system/main.js create mode 100644 test/chunking-form/samples/manual-chunks-dynamic-name-conflict/dynamic1.js create mode 100644 test/chunking-form/samples/manual-chunks-dynamic-name-conflict/dynamic2.js create mode 100644 test/chunking-form/samples/manual-chunks-dynamic-name-conflict/main.js create mode 100644 test/chunking-form/samples/manual-chunks-dynamic/_expected/amd/generated-dynamic.js delete mode 100644 test/chunking-form/samples/manual-chunks-dynamic/_expected/cjs/dynamic-5ab72169.js create mode 100644 test/chunking-form/samples/manual-chunks-dynamic/_expected/cjs/generated-dynamic.js delete mode 100644 test/chunking-form/samples/manual-chunks-dynamic/_expected/es/dynamic-12dc935a.js create mode 100644 test/chunking-form/samples/manual-chunks-dynamic/_expected/es/generated-dynamic.js create mode 100644 test/chunking-form/samples/manual-chunks-dynamic/_expected/system/generated-dynamic.js rename test/chunking-form/samples/manual-chunks/_expected/amd/{deps2and3-0c5d98d0.js => deps2and3-609a33db.js} (86%) rename test/chunking-form/samples/manual-chunks/_expected/cjs/{deps2and3-9aeb2d5b.js => deps2and3-c8fe246d.js} (76%) rename test/chunking-form/samples/namespace-reexports/_expected/system/{index-8b381a8d.js => index-51f0f10d.js} (85%) create mode 100644 test/chunking-form/samples/preserve-modules-dynamic-imports/_config.js rename test/chunking-form/samples/{dynamic-import-treeshaking/_expected/amd/chunk-7b720877.js => preserve-modules-dynamic-imports/_expected/amd/dynamic-included.js} (52%) create mode 100644 test/chunking-form/samples/preserve-modules-dynamic-imports/_expected/amd/main.js create mode 100644 test/chunking-form/samples/preserve-modules-dynamic-imports/_expected/cjs/dynamic-included.js create mode 100644 test/chunking-form/samples/preserve-modules-dynamic-imports/_expected/cjs/main.js create mode 100644 test/chunking-form/samples/preserve-modules-dynamic-imports/_expected/es/dynamic-included.js create mode 100644 test/chunking-form/samples/preserve-modules-dynamic-imports/_expected/es/main.js create mode 100644 test/chunking-form/samples/preserve-modules-dynamic-imports/_expected/system/dynamic-included.js create mode 100644 test/chunking-form/samples/preserve-modules-dynamic-imports/_expected/system/main.js create mode 100644 test/chunking-form/samples/preserve-modules-dynamic-imports/dynamic-included.js create mode 100644 test/chunking-form/samples/preserve-modules-dynamic-imports/dynamic-removed.js create mode 100644 test/chunking-form/samples/preserve-modules-dynamic-imports/main.js create mode 100644 test/form/samples/inlined-treeshaken-dynamic-import/_config.js create mode 100644 test/form/samples/inlined-treeshaken-dynamic-import/_expected/amd.js create mode 100644 test/form/samples/inlined-treeshaken-dynamic-import/_expected/cjs.js create mode 100644 test/form/samples/inlined-treeshaken-dynamic-import/_expected/es.js create mode 100644 test/form/samples/inlined-treeshaken-dynamic-import/_expected/iife.js create mode 100644 test/form/samples/inlined-treeshaken-dynamic-import/_expected/system.js create mode 100644 test/form/samples/inlined-treeshaken-dynamic-import/_expected/umd.js create mode 100644 test/form/samples/inlined-treeshaken-dynamic-import/dynamic.js create mode 100644 test/form/samples/inlined-treeshaken-dynamic-import/main.js delete mode 100644 test/function/samples/cycles-pathological/A.js delete mode 100644 test/function/samples/cycles-pathological/B.js delete mode 100644 test/function/samples/cycles-pathological/C.js delete mode 100644 test/function/samples/cycles-pathological/D.js delete mode 100644 test/function/samples/cycles-pathological/_config.js delete mode 100644 test/function/samples/cycles-pathological/main.js delete mode 100644 test/function/samples/iife-strong-dependencies/A.js delete mode 100644 test/function/samples/iife-strong-dependencies/B.js delete mode 100644 test/function/samples/iife-strong-dependencies/C.js delete mode 100644 test/function/samples/iife-strong-dependencies/D.js delete mode 100644 test/function/samples/iife-strong-dependencies/_config.js delete mode 100644 test/function/samples/iife-strong-dependencies/main.js create mode 100644 test/function/samples/inline-imports-with-manual/_config.js create mode 100644 test/function/samples/inline-imports-with-manual/lib.js create mode 100644 test/function/samples/inline-imports-with-manual/main.js create mode 100644 test/function/samples/inline-imports-with-multiple/_config.js create mode 100644 test/function/samples/inline-imports-with-multiple/lib.js create mode 100644 test/function/samples/inline-imports-with-multiple/main.js create mode 100644 test/function/samples/inline-imports-with-optimize/_config.js create mode 100644 test/function/samples/inline-imports-with-optimize/lib.js create mode 100644 test/function/samples/inline-imports-with-optimize/main.js create mode 100644 test/function/samples/preserve-modules-with-inline/_config.js create mode 100644 test/function/samples/preserve-modules-with-inline/lib.js create mode 100644 test/function/samples/preserve-modules-with-inline/main.js create mode 100644 test/function/samples/preserve-modules-with-manual/_config.js create mode 100644 test/function/samples/preserve-modules-with-manual/lib.js create mode 100644 test/function/samples/preserve-modules-with-manual/main.js create mode 100644 test/function/samples/preserve-modules-with-optimize/_config.js create mode 100644 test/function/samples/preserve-modules-with-optimize/lib.js create mode 100644 test/function/samples/preserve-modules-with-optimize/main.js create mode 100644 test/misc/acorn-plugins.js create mode 100644 test/misc/bundle-information.js create mode 100644 test/misc/deprecations.js create mode 100644 test/misc/in-memory-sourcemaps.js create mode 100644 test/misc/misc.js create mode 100644 test/misc/sanity-checks.js create mode 100644 test/misc/write-bundle.js diff --git a/src/Chunk.ts b/src/Chunk.ts index 2786843cb9e..a1e52a87fa6 100644 --- a/src/Chunk.ts +++ b/src/Chunk.ts @@ -22,8 +22,8 @@ import { import { Addons } from './utils/addons'; import { toBase64 } from './utils/base64'; import collapseSourcemaps from './utils/collapseSourcemaps'; -import error from './utils/error'; -import { sortByExecutionOrder } from './utils/execution-order'; +import { error } from './utils/error'; +import { sortByExecutionOrder } from './utils/executionOrder'; import getIndentString from './utils/getIndentString'; import { makeLegal } from './utils/identifierHelpers'; import { basename, dirname, isAbsolute, normalize, relative, resolve } from './utils/path'; @@ -90,12 +90,12 @@ function getGlobalName( graph.warn({ code: 'MISSING_GLOBAL_NAME', source: module.id, - guess: module.name, + guess: module.variableName, message: `No name was provided for external module '${ module.id - }' in output.globals – guessing '${module.name}'` + }' in output.globals – guessing '${module.variableName}'` }); - return module.name; + return module.variableName; } } @@ -109,7 +109,7 @@ export default class Chunk { exportMode: string = 'named'; usedModules: Module[] = undefined; id: string = undefined; - name: string; + variableName: string; graph: Graph; orderedModules: Module[]; execIndex: number; @@ -127,10 +127,10 @@ export default class Chunk { private exportNames: { [name: string]: Variable } = Object.create(null); private dependencies: (ExternalModule | Chunk)[] = undefined; - // an entry module chunk is a chunk that exactly exports the exports of - // an input entry point module - entryModule: Module = undefined; - isEntryModuleFacade: boolean = false; + private dynamicDependencies: (ExternalModule | Chunk)[] = undefined; + entryModules: Module[] = []; + facadeModule: Module | null = null; + isEmpty: boolean; isManualChunk: boolean = false; private renderedHash: string = undefined; @@ -142,9 +142,9 @@ export default class Chunk { dependencies: ChunkDependencies; exports: ChunkExports; } = undefined; - isEmpty: boolean; + private chunkName: string | void; - constructor(graph: Graph, orderedModules: Module[]) { + constructor(graph: Graph, orderedModules: Module[], inlineDynamicImports: boolean) { this.graph = graph; this.orderedModules = orderedModules; this.execIndex = orderedModules.length > 0 ? orderedModules[0].execIndex : Infinity; @@ -158,23 +158,27 @@ export default class Chunk { this.isManualChunk = true; } module.chunk = this; - if (module.isEntryPoint && !this.entryModule) { - this.entryModule = module; - this.isEntryModuleFacade = true; + if (module.isEntryPoint || (module.isDynamicEntryPoint && !inlineDynamicImports)) { + this.entryModules.push(module); } } - if (this.entryModule) - this.name = makeLegal( + if (this.entryModules.length > 0) { + this.variableName = makeLegal( basename( - this.entryModule.chunkAlias || this.orderedModules[0].chunkAlias || this.entryModule.id + this.entryModules.map(module => module.chunkAlias).find(Boolean) || + this.entryModules[0].id ) ); - else this.name = '__chunk_' + ++graph.curChunkIndex; + } else this.variableName = '__chunk_' + ++graph.curChunkIndex; } getImportIds(): string[] { - return this.dependencies.map(module => module.id); + return this.dependencies.map(chunk => chunk.id); + } + + getDynamicImportIds(): string[] { + return this.dynamicDependencies.map(chunk => chunk.id); } getExportNames(): string[] { @@ -193,30 +197,36 @@ export default class Chunk { } } - // note we assume the facade module chunk is itself linked - // with generateEntryExports called - linkFacade(entryFacade: Module) { - this.dependencies = [entryFacade.chunk]; - this.entryModule = entryFacade; - this.isEntryModuleFacade = true; - for (const exportName of entryFacade.getAllExports()) { - const tracedVariable = entryFacade.traceExport(exportName); - this.exports.set(tracedVariable, entryFacade); + turnIntoFacade(facadedModule: Module) { + this.dependencies = [facadedModule.chunk]; + this.dynamicDependencies = []; + this.facadeModule = facadedModule; + facadedModule.facadeChunk = this; + for (const exportName of facadedModule.getAllExports()) { + const tracedVariable = facadedModule.traceExport(exportName); + this.exports.set(tracedVariable, facadedModule); this.exportNames[exportName] = tracedVariable; } } link() { - this.dependencies = []; + const dependencies: Set = new Set(); + const dynamicDependencies: Set = new Set(); for (const module of this.orderedModules) { - this.addModuleDependenciesToChunk(module); + this.addChunksFromDependencies(module.dependencies, dependencies); + this.addChunksFromDependencies(module.dynamicDependencies, dynamicDependencies); this.setUpModuleImports(module); } + this.dependencies = Array.from(dependencies); + this.dynamicDependencies = Array.from(dynamicDependencies); sortByExecutionOrder(this.dependencies); } - private addModuleDependenciesToChunk(module: Module) { - for (const depModule of module.dependencies) { + private addChunksFromDependencies( + moduleDependencies: (Module | ExternalModule)[], + chunkDependencies: Set + ) { + for (const depModule of moduleDependencies) { if (depModule.chunk === this) { continue; } @@ -224,15 +234,12 @@ export default class Chunk { if (depModule instanceof Module) { dependency = depModule.chunk; } else { - // unused pure external modules can be skipped if (!depModule.used && this.graph.isPureExternalModule(depModule.id)) { continue; } dependency = depModule; } - if (this.dependencies.indexOf(dependency) === -1) { - this.dependencies.push(dependency); - } + chunkDependencies.add(dependency); } } @@ -241,63 +248,69 @@ export default class Chunk { const declaration = module.imports[importName]; this.traceAndInitializeImport(declaration.name, declaration.module); } - for (const { resolution } of module.dynamicImportResolutions) { - this.hasDynamicImport = true; - if (resolution instanceof Module && resolution.chunk === this) - resolution.getOrCreateNamespace().include(); + for (const { node, resolution } of module.dynamicImports) { + if (node.included) { + this.hasDynamicImport = true; + if (resolution instanceof Module && resolution.chunk === this) + resolution.getOrCreateNamespace().include(); + } } } - // Note preserveModules implementation is not a comprehensive technique - // this will likely need to be reworked at some stage for edge cases - populateEntryExports(preserveModules: boolean) { - const entryExportEntries = Array.from(this.entryModule.getAllExports().entries()); - const tracedExports: { variable: Variable; module: Module | ExternalModule }[] = []; - for (const [index, exportName] of entryExportEntries) { - const traced = this.traceExport(exportName, this.entryModule); - if ( - !traced || - (traced.variable && !traced.variable.included && !traced.variable.isExternal) - ) { - continue; - } - tracedExports[index] = traced; - if (!traced.variable) { - continue; - } - if (traced.module.chunk) { - traced.module.chunk.exports.set(traced.variable, traced.module); - } - const existingExport = this.exportNames[exportName]; - // tainted entryModule boundary - if (existingExport && existingExport !== traced.variable) { - this.isEntryModuleFacade = false; + generateEntryExportsOrMarkAsTainted() { + const exportVariableMaps = this.entryModules.map(module => ({ + module, + map: this.getExportVariableMapForModule(module) + })); + for (const { map } of exportVariableMaps) { + for (const exposedVariable of Array.from(map.keys())) { + this.exports.set(exposedVariable, map.get(exposedVariable).module); } } - // tainted if we've already exposed something not corresponding to entry exports - for (const exposedVariable of Array.from(this.exports.keys())) { - if (tracedExports.every(({ variable }) => variable !== exposedVariable)) { - this.isEntryModuleFacade = false; - return; + checkNextEntryModule: for (const { map, module } of exportVariableMaps) { + for (const exposedVariable of Array.from(this.exports.keys())) { + if (!map.has(exposedVariable)) { + continue checkNextEntryModule; + } } + this.facadeModule = module; + for (const [variable, { exportNames }] of Array.from(map)) { + for (const exportName of exportNames) { + this.exportNames[exportName] = variable; + } + } + return; } + } - if (preserveModules || this.isEntryModuleFacade) { - for (const [index, exportName] of entryExportEntries) { - const traced = tracedExports[index]; - if (!traced) { - continue; - } - if (traced.variable) { - if (!traced.variable.included && !traced.variable.isExternal) { - continue; - } - this.exports.set(traced.variable, traced.module); - } - // can be undefined for star external exports (exportName[0] === '*') - this.exportNames[exportName] = traced.variable; + private getExportVariableMapForModule(module: Module) { + const tracedEntryExports: Map< + Variable, + { exportNames: string[]; module: Module | ExternalModule } + > = new Map(); + for (const exportName of module.getAllExports()) { + const tracedExport = this.traceExport(exportName, module); + if ( + !tracedExport || + !tracedExport.variable || + !(tracedExport.variable.included || tracedExport.variable.isExternal) + ) { + continue; + } + const existingExport = tracedEntryExports.get(tracedExport.variable); + if (existingExport) { + existingExport.exportNames.push(exportName); + } else { + tracedEntryExports.set(tracedExport.variable, { + exportNames: [exportName], + module: tracedExport.module + }); + } + if (tracedExport.module.chunk && tracedExport.module.chunk !== this) { + tracedExport.module.chunk.exports.set(tracedExport.variable, tracedExport.module); } } + return tracedEntryExports; } private traceAndInitializeImport(exportName: string, module: Module | ExternalModule) { @@ -320,7 +333,9 @@ export default class Chunk { this.traceAndInitializeImport(importName, traced.variable.module); } else { const externalVariable = traced.variable.module.traceExport(importName); - if (externalVariable.included) this.imports.set(original, traced.variable.module); + if (externalVariable.included) { + this.imports.set(original, traced.variable.module); + } } } } @@ -349,11 +364,6 @@ export default class Chunk { } if (module.chunk !== this) { - // we follow reexports if they are not entry points in the hope - // that we can get an entry point reexport to reduce the chance of - // tainting an entryModule chunk by exposing other unnecessary exports - if (module.isEntryPoint && !module.chunk.isEmpty) - return { variable: module.traceExport(name), module }; return module.chunk.traceExport(name, module); } @@ -393,7 +403,7 @@ export default class Chunk { } generateInternalExports(options: OutputOptions) { - if (this.isEntryModuleFacade) return; + if (this.facadeModule !== null) return; const mangle = options.format === 'system' || options.format === 'es' || options.compact; let i = 0, safeExportName: string; @@ -423,26 +433,17 @@ export default class Chunk { private prepareDynamicImports() { for (const module of this.orderedModules) { - for (let i = 0; i < module.dynamicImportResolutions.length; i++) { - const node = module.dynamicImports[i]; - const resolution = module.dynamicImportResolutions[i].resolution; - + for (const { node, resolution } of module.dynamicImports) { if (!resolution) continue; - if (resolution instanceof Module) { - // if we have the module in the chunk, inline as Promise.resolve(namespace) - // ensuring that we create a namespace import of it as well if (resolution.chunk === this) { const namespace = resolution.getOrCreateNamespace(); node.setResolution(false, namespace.getName()); - // for the module in another chunk, import that other chunk directly } else { node.setResolution(false); } - // external dynamic import resolution } else if (resolution instanceof ExternalModule) { node.setResolution(true); - // AST Node -> source replacement } else { node.setResolution(false); } @@ -454,20 +455,17 @@ export default class Chunk { for (let i = 0; i < this.orderedModules.length; i++) { const module = this.orderedModules[i]; const code = this.renderedModuleSources[i]; - for (let j = 0; j < module.dynamicImportResolutions.length; j++) { - const node = module.dynamicImports[j]; - const resolution = module.dynamicImportResolutions[j].resolution; - + for (const { node, resolution } of module.dynamicImports) { if (!resolution) continue; if (resolution instanceof Module) { - if (resolution.chunk !== this) { - let relPath = normalize(relative(dirname(this.id), resolution.chunk.id)); + const resolutionChunk = resolution.facadeChunk || resolution.chunk; + if (resolutionChunk && resolutionChunk !== this && resolutionChunk.id) { + let relPath = normalize(relative(dirname(this.id), resolutionChunk.id)); if (!relPath.startsWith('../')) relPath = './' + relPath; - node.renderFinalResolution(code, `"${relPath}"`); + node.renderFinalResolution(code, `'${relPath}'`); } } else if (resolution instanceof ExternalModule) { - node.renderFinalResolution(code, `"${resolution.id}"`); - // AST Node -> source replacement + node.renderFinalResolution(code, `'${resolution.id}'`); } else { node.renderFinalResolution(code, resolution); } @@ -514,9 +512,9 @@ export default class Chunk { if (!esm) { this.dependencies.forEach(module => { - const safeName = getSafeName(module.name); + const safeName = getSafeName(module.variableName); toDeshadow.add(safeName); - module.name = safeName; + module.variableName = safeName; }); } @@ -532,18 +530,18 @@ export default class Chunk { if (module instanceof ExternalModule) { if (variable.name === '*') { - safeName = module.name; + safeName = module.variableName; } else if (variable.name === 'default') { if ( options.interop !== false && (module.exportsNamespace || (!esm && module.exportsNames)) ) { - safeName = `${module.name}__default`; + safeName = `${module.variableName}__default`; } else { - safeName = module.name; + safeName = module.variableName; } } else { - safeName = esm ? variable.name : `${module.name}.${variable.name}`; + safeName = esm ? variable.name : `${module.variableName}.${variable.name}`; } if (esm) { safeName = getSafeName(safeName); @@ -554,8 +552,8 @@ export default class Chunk { toDeshadow.add(safeName); } else { const chunk = module.chunk; - if (chunk.exportMode === 'default') safeName = chunk.name; - else safeName = `${chunk.name}.${module.chunk.getVariableExportName(variable)}`; + if (chunk.exportMode === 'default') safeName = chunk.variableName; + else safeName = `${chunk.variableName}.${module.chunk.getVariableExportName(variable)}`; } if (safeName) variable.setSafeName(safeName); }); @@ -684,7 +682,7 @@ export default class Chunk { id, // chunk id updated on render namedExportsMode, globalName, - name: dep.name, + name: dep.variableName, isChunk: !(dep).isExternal, exportsNames, exportsDefault, @@ -764,7 +762,7 @@ export default class Chunk { return visitDep(this); } - private computeFullHash(addons: Addons, options: OutputOptions): string { + private computeContentHashWithDependencies(addons: Addons, options: OutputOptions): string { const hash = sha256(); // own rendered source, except for finalizer wrapping @@ -808,8 +806,8 @@ export default class Chunk { format: options.format }; - // if an entry point facade, inline the execution list to avoid loading latency - if (this.isEntryModuleFacade) { + // if an entry point facade or dynamic entry point, inline the execution list to avoid loading latency + if (this.facadeModule !== null) { for (const dep of this.dependencies) { if (dep instanceof Chunk) this.inlineChunkDependencies(dep, true); } @@ -910,7 +908,7 @@ export default class 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.isEntryModuleFacade || chunk.isEntryModuleFacade) + 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) { @@ -977,7 +975,7 @@ export default class Chunk { if (!into.exportsDefault && from.exportsDefault) { into.exportsDefault = true; } - into.name = this.name; + into.name = this.variableName; }; // go through the other chunks and update their dependencies @@ -1014,10 +1012,10 @@ export default class Chunk { preserveModulesRelativeDir: string, existingNames: Record ) { - const sanitizedId = this.entryModule.id.replace('\0', '_'); + const sanitizedId = this.orderedModules[0].id.replace('\0', '_'); this.id = makeUnique( normalize( - isAbsolute(this.entryModule.id) + isAbsolute(this.orderedModules[0].id) ? relative(preserveModulesRelativeDir, sanitizedId) : '_virtual/' + basename(sanitizedId) ), @@ -1038,19 +1036,29 @@ export default class Chunk { case 'format': return options.format === 'es' ? 'esm' : options.format; case 'hash': - return this.computeFullHash(addons, options); + return this.computeContentHashWithDependencies(addons, options); case 'name': - if (this.entryModule && this.entryModule.chunkAlias) return this.entryModule.chunkAlias; - for (const module of this.orderedModules) { - if (module.chunkAlias) return module.chunkAlias; - } - return 'chunk'; + return this.getChunkName(); } }), existingNames ); } + getChunkName(): string { + return this.chunkName || (this.chunkName = this.computeChunkName()); + } + + private computeChunkName(): string { + if (this.facadeModule !== null && this.facadeModule.chunkAlias) { + return this.facadeModule.chunkAlias; + } + for (const module of this.orderedModules) { + if (module.chunkAlias) return module.chunkAlias; + } + return 'chunk'; + } + render(options: OutputOptions, addons: Addons, outputChunk: RenderedChunk) { timeStart('render format', 3); @@ -1115,7 +1123,7 @@ export default class Chunk { dependencies: this.renderedDeclarations.dependencies, exports: this.renderedDeclarations.exports, graph: this.graph, - isEntryModuleFacade: this.isEntryModuleFacade, + isEntryModuleFacade: this.facadeModule !== null && this.facadeModule.isEntryPoint, usesTopLevelAwait }, options diff --git a/src/ExternalModule.ts b/src/ExternalModule.ts index 3be5b02fccb..3d488a82bb5 100644 --- a/src/ExternalModule.ts +++ b/src/ExternalModule.ts @@ -17,7 +17,7 @@ export default class ExternalModule { renormalizeRenderPath = false; isExternal = true; isEntryPoint = false; - name: string; + variableName: string; mostCommonSuggestion: number = 0; nameSuggestions: { [name: string]: number }; reexported: boolean = false; @@ -30,7 +30,7 @@ export default class ExternalModule { this.execIndex = Infinity; const parts = id.split(/[\\/]/); - this.name = makeLegal(parts.pop()); + this.variableName = makeLegal(parts.pop()); this.nameSuggestions = Object.create(null); this.declarations = Object.create(null); @@ -58,7 +58,7 @@ export default class ExternalModule { if (this.nameSuggestions[name] > this.mostCommonSuggestion) { this.mostCommonSuggestion = this.nameSuggestions[name]; - this.name = name; + this.variableName = name; } } diff --git a/src/Graph.ts b/src/Graph.ts index 6e3f28b18b7..7a3d89e5b28 100644 --- a/src/Graph.ts +++ b/src/Graph.ts @@ -23,9 +23,10 @@ import { Watcher } from './rollup/types'; import { finaliseAsset } from './utils/assetHooks'; +import { assignChunkColouringHashes } from './utils/chunkColouring'; import { Uint8ArrayToHexString } from './utils/entryHashing'; -import error from './utils/error'; -import { analyzeModuleExecution, sortByExecutionOrder } from './utils/execution-order'; +import { error } from './utils/error'; +import { analyseModuleExecution, sortByExecutionOrder } from './utils/executionOrder'; import { isRelative, resolve } from './utils/path'; import { createPluginDriver, PluginDriver } from './utils/pluginDriver'; import relativeId, { getAliasName } from './utils/relativeId'; @@ -51,11 +52,11 @@ export default class Graph { context: string; externalModules: ExternalModule[] = []; getModuleContext: (id: string) => string; - hasLoaders: boolean; isPureExternalModule: (id: string) => boolean; moduleById = new Map(); assetsById = new Map(); modules: Module[] = []; + needsTreeshakingPass: boolean = false; onwarn: WarningHandler; deoptimizationTracker: EntityPathTracker; scope: GlobalScope; @@ -154,7 +155,7 @@ export default class Graph { this.shimMissingExports = options.shimMissingExports; this.scope = new GlobalScope(); - // TODO strictly speaking, this only applies with non-ES6, non-default-only bundles + // Strictly speaking, this only applies with non-ES6, non-default-only bundles for (const name of ['module', 'exports', '_interopDefault']) { this.scope.findVariable(name); // creates global variable as side-effect } @@ -262,18 +263,15 @@ export default class Graph { includeMarked(modules: Module[]) { if (this.treeshake) { - let needsTreeshakingPass, - treeshakingPass = 1; + let treeshakingPass = 1; do { timeStart(`treeshaking pass ${treeshakingPass}`, 3); - needsTreeshakingPass = false; + this.needsTreeshakingPass = false; for (const module of modules) { - if (module.include()) { - needsTreeshakingPass = true; - } + if (module.isExecuted) module.include(); } timeEnd(`treeshaking pass ${treeshakingPass++}`, 3); - } while (needsTreeshakingPass); + } while (this.needsTreeshakingPass); } else { // Necessary to properly replace namespace imports for (const module of modules) module.includeAllInBundle(); @@ -371,17 +369,7 @@ export default class Graph { this.link(); - const { - orderedModules, - dynamicImports, - dynamicImportAliases, - cyclePaths - } = analyzeModuleExecution( - entryModules, - !preserveModules && !inlineDynamicImports, - inlineDynamicImports, - manualChunkModules - ); + const { orderedModules, cyclePaths } = analyseModuleExecution(entryModules); for (const cyclePath of cyclePaths) { this.warn({ code: 'CIRCULAR_DEPENDENCY', @@ -390,41 +378,18 @@ export default class Graph { }); } - if (entryModuleAliases) { - for (let i = entryModules.length - 1; i >= 0; i--) { - entryModules[i].chunkAlias = entryModuleAliases[i]; - } - } + timeEnd('analyse dependency graph', 2); + + // Phase 3 – marking. We include all statements that should be included + timeStart('mark included statements', 2); if (inlineDynamicImports) { - const entryModule = entryModules[0]; if (entryModules.length > 1) throw new Error( 'Internal Error: can only inline dynamic imports for single-file builds.' ); - for (const dynamicImportModule of dynamicImports) { - if (entryModule !== dynamicImportModule) dynamicImportModule.markPublicExports(); - dynamicImportModule.getOrCreateNamespace().include(); - } - } else { - for (let i = 0; i < dynamicImports.length; i++) { - const dynamicImportModule = dynamicImports[i]; - if (entryModules.indexOf(dynamicImportModule) === -1) { - entryModules.push(dynamicImportModule); - if (!dynamicImportModule.chunkAlias) - dynamicImportModule.chunkAlias = dynamicImportAliases[i]; - } - } } - - timeEnd('analyse dependency graph', 2); - - // Phase 3 – marking. We include all statements that should be included - timeStart('mark included statements', 2); - - for (const entryModule of entryModules) entryModule.markPublicExports(); - - // only include statements that should appear in the bundle + for (const entryModule of entryModules) entryModule.includeAllExports(); this.includeMarked(orderedModules); // check for unused external imports @@ -436,6 +401,16 @@ export default class Graph { // entry point graph colouring, before generating the import and export facades timeStart('generate chunks', 2); + if (!preserveModules && !inlineDynamicImports) { + assignChunkColouringHashes(entryModules, manualChunkModules); + } + + if (entryModuleAliases) { + for (let i = entryModules.length - 1; i >= 0; i--) { + entryModules[i].chunkAlias = entryModuleAliases[i]; + } + } + // TODO: there is one special edge case unhandled here and that is that any module // exposed as an unresolvable export * (to a graph external export *, // either as a namespace import reexported or top-level export *) @@ -443,8 +418,10 @@ export default class Graph { let chunks: Chunk[] = []; if (preserveModules) { for (const module of orderedModules) { - const chunk = new Chunk(this, [module]); - if (module.isEntryPoint || !chunk.isEmpty) chunk.entryModule = module; + const chunk = new Chunk(this, [module], inlineDynamicImports); + if (module.isEntryPoint || !chunk.isEmpty) { + chunk.entryModules = [module]; + } chunks.push(chunk); } } else { @@ -462,7 +439,7 @@ export default class Graph { for (const entryHashSum in chunkModules) { const chunkModulesOrdered = chunkModules[entryHashSum]; sortByExecutionOrder(chunkModulesOrdered); - const chunk = new Chunk(this, chunkModulesOrdered); + const chunk = new Chunk(this, chunkModulesOrdered, inlineDynamicImports); chunks.push(chunk); } } @@ -474,22 +451,27 @@ export default class Graph { } // filter out empty dependencies - chunks = chunks.filter(chunk => !chunk.isEmpty || chunk.entryModule || chunk.isManualChunk); + chunks = chunks.filter( + chunk => !chunk.isEmpty || chunk.entryModules.length > 0 || chunk.isManualChunk + ); // then go over and ensure all entry chunks export their variables for (const chunk of chunks) { - if (preserveModules || chunk.entryModule) { - chunk.populateEntryExports(preserveModules); + if (preserveModules || chunk.entryModules.length > 0) { + chunk.generateEntryExportsOrMarkAsTainted(); } } // create entry point facades for entry module chunks that have tainted exports + const facades = []; if (!preserveModules) { - for (const entryModule of entryModules) { - if (!entryModule.chunk.isEntryModuleFacade) { - const entryPointFacade = new Chunk(this, []); - entryPointFacade.linkFacade(entryModule); - chunks.push(entryPointFacade); + for (const chunk of chunks) { + for (const entryModule of chunk.entryModules) { + if (chunk.facadeModule !== entryModule) { + const entryPointFacade = new Chunk(this, [], inlineDynamicImports); + entryPointFacade.turnIntoFacade(entryModule); + facades.push(entryPointFacade); + } } } } @@ -497,7 +479,7 @@ export default class Graph { timeEnd('generate chunks', 2); this.finished = true; - return chunks; + return chunks.concat(facades); } ); } @@ -605,47 +587,41 @@ export default class Graph { } private fetchAllDependencies(module: Module) { - // resolve and fetch dynamic imports where possible const fetchDynamicImportsPromise = Promise.all( - module.getDynamicImportExpressions().map((dynamicImportExpression, index) => { - return Promise.resolve( - this.pluginDriver.hookFirst('resolveDynamicImport', [dynamicImportExpression, module.id]) - ).then(replacement => { - if (!replacement) { - module.dynamicImportResolutions[index] = { - alias: undefined, - resolution: undefined - }; - return; - } - const alias = getAliasName( - replacement, - typeof dynamicImportExpression === 'string' ? dynamicImportExpression : undefined - ); - if (typeof dynamicImportExpression !== 'string') { - module.dynamicImportResolutions[index] = { alias, resolution: replacement }; - } else if (this.isExternal(replacement, module.id, true)) { - let externalModule; - if (!this.moduleById.has(replacement)) { - externalModule = new ExternalModule({ - graph: this, - id: replacement - }); - this.externalModules.push(externalModule); - this.moduleById.set(replacement, module); + module.getDynamicImportExpressions().map((dynamicImportExpression, index) => + this.pluginDriver + .hookFirst('resolveDynamicImport', [dynamicImportExpression, module.id]) + .then(replacement => { + if (!replacement) return; + const dynamicImport = module.dynamicImports[index]; + dynamicImport.alias = getAliasName( + replacement, + typeof dynamicImportExpression === 'string' ? dynamicImportExpression : undefined + ); + if (typeof dynamicImportExpression !== 'string') { + dynamicImport.resolution = replacement; + } else if (this.isExternal(replacement, module.id, true)) { + let externalModule; + if (!this.moduleById.has(replacement)) { + externalModule = new ExternalModule({ + graph: this, + id: replacement + }); + this.externalModules.push(externalModule); + this.moduleById.set(replacement, module); + } else { + externalModule = this.moduleById.get(replacement); + } + dynamicImport.resolution = externalModule; + externalModule.exportsNamespace = true; } else { - externalModule = this.moduleById.get(replacement); + return this.fetchModule(replacement, module.id).then(depModule => { + dynamicImport.resolution = depModule; + }); } - module.dynamicImportResolutions[index] = { alias, resolution: externalModule }; - externalModule.exportsNamespace = true; - } else { - return this.fetchModule(replacement, module.id).then(depModule => { - module.dynamicImportResolutions[index] = { alias, resolution: depModule }; - }); - } - }); - }) - ).then(() => {}); + }) + ) + ); fetchDynamicImportsPromise.catch(() => {}); return Promise.all( diff --git a/src/Module.ts b/src/Module.ts index a7de14f23f9..3d1d5624099 100644 --- a/src/Module.ts +++ b/src/Module.ts @@ -28,7 +28,7 @@ import Chunk from './Chunk'; import ExternalModule from './ExternalModule'; import Graph from './Graph'; import { Asset, IdMap, ModuleJSON, RawSourceMap, RollupError, RollupWarning } from './rollup/types'; -import error from './utils/error'; +import { error } from './utils/error'; import getCodeFrame from './utils/getCodeFrame'; import { getOriginalLocation } from './utils/getOriginalLocation'; import { makeLegal } from './utils/identifierHelpers'; @@ -37,6 +37,7 @@ import relativeId from './utils/relativeId'; import { RenderOptions } from './utils/renderHelpers'; import { SOURCEMAPPING_URL_RE } from './utils/sourceMappingURL'; import { timeEnd, timeStart } from './utils/timers'; +import { visitStaticDependencies } from './utils/traverseStaticDependencies'; export interface CommentDescription { block: boolean; @@ -83,6 +84,7 @@ export interface AstContext { imports: { [name: string]: ImportDescription }; isCrossChunkImport: (importDescription: ImportDescription) => boolean; includeNamespace: () => void; + includeDynamicImport: (node: Import) => void; magicString: MagicString; moduleContext: string; nodeConstructors: { [name: string]: typeof NodeBase }; @@ -147,78 +149,57 @@ function handleMissingExport( export default class Module { type: 'Module'; - private graph: Graph; + chunk: Chunk; + chunkAlias: string = undefined; code: string; - comments: CommentDescription[]; - dependencies: (Module | ExternalModule)[]; + comments: CommentDescription[] = []; + customTransformCache: boolean; + dependencies: (Module | ExternalModule)[] = []; + dynamicDependencies: (Module | ExternalModule)[] = []; + dynamicImports: { + node: Import; + alias: string | null; + resolution: Module | ExternalModule | string | void; + }[] = []; + entryPointsHash: Uint8Array = new Uint8Array(10); + exportAllModules: (Module | ExternalModule)[] = null; excludeFromSourcemap: boolean; - exports: { [name: string]: ExportDescription }; - exportsAll: { [name: string]: string }; - exportAllSources: string[]; + execIndex: number = Infinity; + exports: { [name: string]: ExportDescription } = Object.create(null); + exportsAll: { [name: string]: string } = Object.create(null); + exportAllSources: string[] = []; + facadeChunk: Chunk | null = null; id: string; - imports: { [name: string]: ImportDescription }; + importMetas: MetaProperty[] = []; + imports: { [name: string]: ImportDescription } = Object.create(null); + isDynamicEntryPoint: boolean = false; + isEntryPoint: boolean = false; + isExecuted: boolean = false; isExternal: false; originalCode: string; originalSourcemap: RawSourceMap | void; - reexports: { [name: string]: ReexportDescription }; + reexports: { [name: string]: ReexportDescription } = Object.create(null); resolvedIds: IdMap; scope: ModuleScope; sourcemapChain: RawSourceMap[]; - sources: string[]; - dynamicImports: Import[]; - importMetas: MetaProperty[]; - dynamicImportResolutions: { - alias: string; - resolution: Module | ExternalModule | string | void; - }[]; + sources: string[] = []; transformAssets: Asset[]; - customTransformCache: boolean; - - execIndex: number; - isEntryPoint: boolean; - chunkAlias: string; - entryPointsHash: Uint8Array; - chunk: Chunk; - exportAllModules: (Module | ExternalModule)[]; usesTopLevelAwait: boolean = false; private ast: Program; private astContext: AstContext; private context: string; - private namespaceVariable: NamespaceVariable = undefined; private esTreeAst: ESTree.Program; + private graph: Graph; private magicString: MagicString; - private needsTreeshakingPass: boolean = false; + private namespaceVariable: NamespaceVariable = undefined; private transformDependencies: string[]; constructor(graph: Graph, id: string) { this.id = id; - this.chunkAlias = undefined; this.graph = graph; - this.comments = []; - - this.dynamicImports = []; - this.importMetas = []; - this.dynamicImportResolutions = []; - this.isEntryPoint = false; - this.execIndex = Infinity; - this.entryPointsHash = new Uint8Array(10); - this.excludeFromSourcemap = /\0/.test(id); this.context = graph.getModuleContext(id); - - // all dependencies - this.sources = []; - this.dependencies = []; - - // imports and exports, indexed by local name - this.imports = Object.create(null); - this.exports = Object.create(null); - this.exportsAll = Object.create(null); - this.reexports = Object.create(null); - - this.exportAllSources = []; - this.exportAllModules = null; } setSource({ @@ -272,6 +253,7 @@ export default class Module { getModuleExecIndex: () => this.execIndex, getModuleName: this.basename.bind(this), imports: this.imports, + includeDynamicImport: this.includeDynamicImport.bind(this), includeNamespace: this.includeNamespace.bind(this), isCrossChunkImport: importDescription => importDescription.module.chunk !== this.chunk, magicString: this.magicString, @@ -280,7 +262,7 @@ export default class Module { propertyReadSideEffects: !this.graph.treeshake || this.graph.treeshakingOptions.propertyReadSideEffects, deoptimizationTracker: this.graph.deoptimizationTracker, - requestTreeshakingPass: () => (this.needsTreeshakingPass = true), + requestTreeshakingPass: () => (this.graph.needsTreeshakingPass = true), traceExport: this.traceExport.bind(this), traceVariable: this.traceVariable.bind(this), treeshake: this.graph.treeshake, @@ -431,7 +413,7 @@ export default class Module { } private addDynamicImport(node: Import) { - this.dynamicImports.push(node); + this.dynamicImports.push({ node, alias: undefined, resolution: undefined }); } private addImportMeta(node: MetaProperty) { @@ -445,13 +427,24 @@ export default class Module { return makeLegal(ext ? base.slice(0, -ext.length) : base); } - markPublicExports() { + includeAllExports() { + if (!this.isExecuted) { + this.graph.needsTreeshakingPass = true; + visitStaticDependencies(this, module => { + if (module instanceof ExternalModule || module.isExecuted) return true; + module.isExecuted = true; + return false; + }); + } + for (const exportName of this.getExports()) { const variable = this.traceExport(exportName); - variable.exportName = exportName; variable.deoptimizePath(UNKNOWN_PATH); - variable.include(); + if (!variable.included) { + variable.include(); + this.graph.needsTreeshakingPass = true; + } if (variable.isNamespace) { (variable).needsNamespaceBlock = true; @@ -461,13 +454,12 @@ export default class Module { for (const name of this.getReexports()) { const variable = this.traceExport(name); - variable.exportName = name; - if (variable.isExternal) { variable.reexported = (variable).module.reexported = true; - } else { + } else if (!variable.included) { variable.include(); variable.deoptimizePath(UNKNOWN_PATH); + this.graph.needsTreeshakingPass = true; } } } @@ -481,6 +473,11 @@ export default class Module { this.dependencies.push(module); } } + for (const { resolution } of this.dynamicImports) { + if (resolution instanceof Module || resolution instanceof ExternalModule) { + this.dynamicDependencies.push(resolution); + } + } const resolveSpecifiers = (specifiers: { [name: string]: ImportDescription | ReexportDescription; @@ -507,7 +504,7 @@ export default class Module { } getDynamicImportExpressions(): (string | Node)[] { - return this.dynamicImports.map(node => { + return this.dynamicImports.map(({ node }) => { const importArgument = node.parent.arguments[0]; if (isTemplateLiteral(importArgument)) { if (importArgument.expressions.length === 0 && importArgument.quasis.length === 1) { @@ -607,10 +604,8 @@ export default class Module { return this.ast.included; } - include(): boolean { - this.needsTreeshakingPass = false; + include(): void { if (this.ast.shouldBeIncluded()) this.ast.include(false); - return this.needsTreeshakingPass; } getOrCreateNamespace(): NamespaceVariable { @@ -619,6 +614,15 @@ export default class Module { return (this.namespaceVariable = new NamespaceVariable(this.astContext, this)); } + private includeDynamicImport(node: Import) { + const resolution = this.dynamicImports.find(dynamicImport => dynamicImport.node === node) + .resolution; + if (resolution instanceof Module) { + resolution.isDynamicEntryPoint = true; + resolution.includeAllExports(); + } + } + private includeNamespace() { const namespace = this.getOrCreateNamespace(); if (namespace.needsNamespaceBlock) return; diff --git a/src/ast/nodes/Import.ts b/src/ast/nodes/Import.ts index 1ce8b00630c..37164af3578 100644 --- a/src/ast/nodes/Import.ts +++ b/src/ast/nodes/Import.ts @@ -47,24 +47,26 @@ export default class Import extends NodeBase { private resolutionNamespace: string; private resolutionInterop: boolean; - private rendered: boolean; + + include() { + this.included = true; + this.context.includeDynamicImport(this); + } initialise() { this.included = false; this.resolutionNamespace = undefined; this.resolutionInterop = false; - this.rendered = false; this.context.addDynamicImport(this); } renderFinalResolution(code: MagicString, resolution: string) { - // avoid unnecessary writes when tree-shaken - if (this.rendered) + if (this.included) { code.overwrite(this.parent.arguments[0].start, this.parent.arguments[0].end, resolution); + } } render(code: MagicString, options: RenderOptions) { - this.rendered = true; if (this.resolutionNamespace) { const _ = options.compact ? '' : ' '; const s = options.compact ? '' : ';'; @@ -89,7 +91,6 @@ export default class Import extends NodeBase { } setResolution(interop: boolean, namespace: string = undefined): void { - this.rendered = false; this.resolutionInterop = interop; this.resolutionNamespace = namespace; } diff --git a/src/ast/nodes/Program.ts b/src/ast/nodes/Program.ts index 06952c8912b..102d4c02f1e 100644 --- a/src/ast/nodes/Program.ts +++ b/src/ast/nodes/Program.ts @@ -18,8 +18,9 @@ export default class Program extends NodeBase { include(includeAllChildrenRecursively: boolean) { this.included = true; for (const node of this.body) { - if (includeAllChildrenRecursively || node.shouldBeIncluded()) + if (includeAllChildrenRecursively || node.shouldBeIncluded()) { node.include(includeAllChildrenRecursively); + } } } diff --git a/src/chunk-optimization.ts b/src/chunk-optimization.ts index 90274a3ffda..5c706f60fc7 100644 --- a/src/chunk-optimization.ts +++ b/src/chunk-optimization.ts @@ -36,10 +36,10 @@ export function optimizeChunks( nextChunk = execGroup[1]; const isMergeCandidate = (chunk: Chunk) => { - if (chunk.isEntryModuleFacade || chunk.isManualChunk) { + if (chunk.facadeModule !== null || chunk.isManualChunk) { return false; } - if (!nextChunk || nextChunk.isEntryModuleFacade) { + if (!nextChunk || nextChunk.facadeModule !== null) { return false; } if (chunk.getRenderedSourceLength() > CHUNK_GROUPING_SIZE) { diff --git a/src/finalisers/iife.ts b/src/finalisers/iife.ts index 7fe45c4e7d3..60d477e24d5 100644 --- a/src/finalisers/iife.ts +++ b/src/finalisers/iife.ts @@ -1,6 +1,6 @@ import { Bundle as MagicStringBundle } from 'magic-string'; import { OutputOptions } from '../rollup/types'; -import error from '../utils/error'; +import { error } from '../utils/error'; import { isLegal } from '../utils/identifierHelpers'; import { FinaliserOptions } from './index'; import getExportBlock from './shared/getExportBlock'; diff --git a/src/finalisers/umd.ts b/src/finalisers/umd.ts index 8127ff12b2e..92b1834ce29 100644 --- a/src/finalisers/umd.ts +++ b/src/finalisers/umd.ts @@ -1,6 +1,6 @@ import { Bundle as MagicStringBundle } from 'magic-string'; import { OutputOptions } from '../rollup/types'; -import error from '../utils/error'; +import { error } from '../utils/error'; import { FinaliserOptions } from './index'; import { compactEsModuleExport, esModuleExport } from './shared/esModuleExport'; import getExportBlock from './shared/getExportBlock'; diff --git a/src/rollup/index.ts b/src/rollup/index.ts index afe8cfe4bc3..ca40b8cae7c 100644 --- a/src/rollup/index.ts +++ b/src/rollup/index.ts @@ -3,9 +3,10 @@ import { optimizeChunks } from '../chunk-optimization'; import Graph from '../Graph'; import { createAddons } from '../utils/addons'; import { createAssetPluginHooks, finaliseAsset } from '../utils/assetHooks'; +import { assignChunkIds } from '../utils/assignChunkIds'; import commondir from '../utils/commondir'; import { Deprecation } from '../utils/deprecateOptions'; -import error from '../utils/error'; +import { error } from '../utils/error'; import { writeFile } from '../utils/fs'; import getExportMode from '../utils/getExportMode'; import mergeOptions, { GenericConfigObject } from '../utils/mergeOptions'; @@ -64,6 +65,18 @@ function checkOutputOptions(options: OutputOptions) { } } +function getAbsoluteEntryModulePaths(chunks: Chunk[]): string[] { + const absoluteEntryModulePaths: string[] = []; + for (const chunk of chunks) { + for (const entryModule of chunk.entryModules) { + if (isAbsolute(entryModule.id)) { + absoluteEntryModulePaths.push(entryModule.id); + } + } + } + return absoluteEntryModulePaths; +} + const throwAsyncGenerateError = { get() { throw new Error(`bundle.generate(...) now returns a Promise instead of a { code, map } object`); @@ -104,10 +117,11 @@ function getInputOptions(rawInputOptions: GenericConfigObject): any { code: 'INVALID_OPTION', message: '"manualChunks" option is only supported for experimentalCodeSplitting.' }); - if (inputOptions.optimizeChunks) + if (inputOptions.experimentalOptimizeChunks) error({ code: 'INVALID_OPTION', - message: '"optimizeChunks" option is only supported for experimentalCodeSplitting.' + message: + '"experimentalOptimizeChunks" option is only supported for experimentalCodeSplitting.' }); if (inputOptions.input instanceof Array || typeof inputOptions.input === 'object') error({ @@ -128,10 +142,10 @@ function getInputOptions(rawInputOptions: GenericConfigObject): any { message: '"manualChunks" option is not supported for inlineDynamicImports.' }); - if (inputOptions.optimizeChunks) + if (inputOptions.experimentalOptimizeChunks) error({ code: 'INVALID_OPTION', - message: '"optimizeChunks" option is not supported for inlineDynamicImports.' + message: '"experimentalOptimizeChunks" option is not supported for inlineDynamicImports.' }); if (inputOptions.input instanceof Array || typeof inputOptions.input === 'object') error({ @@ -144,10 +158,11 @@ function getInputOptions(rawInputOptions: GenericConfigObject): any { code: 'INVALID_OPTION', message: 'experimentalPreserveModules does not support the manualChunks option.' }); - if (inputOptions.optimizeChunks) + if (inputOptions.experimentalOptimizeChunks) error({ code: 'INVALID_OPTION', - message: 'experimentalPreserveModules does not support the optimizeChunks option.' + message: + 'experimentalPreserveModules does not support the experimentalOptimizeChunks option.' }); } @@ -204,11 +219,9 @@ export default function rollup( const singleInput = typeof inputOptions.input === 'string' || (inputOptions.input instanceof Array && inputOptions.input.length === 1); - //let imports: string[], exports: string[]; if (!inputOptions.experimentalPreserveModules) { if (singleInput) { for (const chunk of chunks) { - if (chunk.entryModule === undefined) continue; if (singleChunk) { singleChunk = undefined; break; @@ -259,14 +272,9 @@ export default function rollup( timeStart('GENERATE', 1); - // populate asset files into output const assetFileNames = outputOptions.assetFileNames || 'assets/[name]-[hash][extname]'; const outputBundle: OutputBundle = graph.finaliseAssets(assetFileNames); - const inputBase = commondir( - chunks - .filter(chunk => chunk.entryModule && isAbsolute(chunk.entryModule.id)) - .map(chunk => chunk.entryModule.id) - ); + const inputBase = commondir(getAbsoluteEntryModulePaths(chunks)); return graph.pluginDriver .hookParallel('renderStart') @@ -276,57 +284,38 @@ export default function rollup( for (const chunk of chunks) { if (!inputOptions.experimentalPreserveModules) chunk.generateInternalExports(outputOptions); - if (chunk.isEntryModuleFacade) + if (chunk.facadeModule && chunk.facadeModule.isEntryPoint) chunk.exportMode = getExportMode(chunk, outputOptions); } for (const chunk of chunks) { chunk.preRender(outputOptions, inputBase); } - if (!optimized && inputOptions.optimizeChunks) { + if (!optimized && inputOptions.experimentalOptimizeChunks) { optimizeChunks(chunks, outputOptions, inputOptions.chunkGroupingSize, inputBase); optimized = true; } - // name all chunks - const usedIds: Record = {}; - for (let i = 0; i < chunks.length; i++) { - const chunk = chunks[i]; - - if (chunk === singleChunk) { - singleChunk.id = basename( - outputOptions.file || - (inputOptions.input instanceof Array - ? inputOptions.input[0] - : inputOptions.input) - ); - } else if (inputOptions.experimentalPreserveModules) { - chunk.generateIdPreserveModules(inputBase, usedIds); - } else { - let pattern, patternName; - if (chunk.isEntryModuleFacade) { - pattern = outputOptions.entryFileNames || '[name].js'; - patternName = 'output.entryFileNames'; - } else { - pattern = outputOptions.chunkFileNames || '[name]-[hash].js'; - patternName = 'output.chunkFileNames'; - } - chunk.generateId(pattern, patternName, addons, outputOptions, usedIds); - } - usedIds[chunk.id] = true; - } + assignChunkIds(chunks, singleChunk, inputOptions, outputOptions, inputBase, addons); // assign to outputBundle for (let i = 0; i < chunks.length; i++) { const chunk = chunks[i]; + const facadeModule = chunk.facadeModule; outputBundle[chunk.id] = { + code: undefined, + dynamicImports: chunk.getDynamicImportIds(), + exports: chunk.getExportNames(), + facadeModuleId: facadeModule && facadeModule.id, fileName: chunk.id, - isEntry: chunk.entryModule !== undefined, imports: chunk.getImportIds(), - exports: chunk.getExportNames(), + isDynamicEntry: facadeModule !== null && facadeModule.isDynamicEntryPoint, + isEntry: facadeModule !== null && facadeModule.isEntryPoint, + map: undefined, modules: chunk.renderedModules, - code: undefined, - map: undefined + get name() { + return chunk.getChunkName(); + } }; } diff --git a/src/rollup/types.d.ts b/src/rollup/types.d.ts index bf0d0be823a..354dd8e631a 100644 --- a/src/rollup/types.d.ts +++ b/src/rollup/types.d.ts @@ -242,7 +242,7 @@ export interface InputOptions { inlineDynamicImports?: boolean; preserveSymlinks?: boolean; experimentalPreserveModules?: boolean; - optimizeChunks?: boolean; + experimentalOptimizeChunks?: boolean; chunkGroupingSize?: number; shimMissingExports?: boolean; @@ -363,13 +363,17 @@ export interface RenderedModule { } export interface RenderedChunk { + dynamicImports: string[]; + exports: string[]; + facadeModuleId: string | null; fileName: string; - isEntry: boolean; imports: string[]; - exports: string[]; + isDynamicEntry: boolean; + isEntry: boolean; modules: { [id: string]: RenderedModule; }; + name: string; } export interface OutputChunk extends RenderedChunk { diff --git a/src/utils/addons.ts b/src/utils/addons.ts index f55a0bf394d..d4705048ffc 100644 --- a/src/utils/addons.ts +++ b/src/utils/addons.ts @@ -1,6 +1,6 @@ import Graph from '../Graph'; import { OutputOptions } from '../rollup/types'; -import error from './error'; +import { error } from './error'; export interface Addons { intro?: string; diff --git a/src/utils/assetHooks.ts b/src/utils/assetHooks.ts index dc062c15311..a800f1845d0 100644 --- a/src/utils/assetHooks.ts +++ b/src/utils/assetHooks.ts @@ -1,6 +1,6 @@ import sha256 from 'hash.js/lib/hash/sha/256'; import { Asset, OutputBundle } from '../rollup/types'; -import error from './error'; +import { error } from './error'; import { extname } from './path'; import { isPlainName } from './relativeId'; import { makeUnique, renderNamePattern } from './renderNamePattern'; diff --git a/src/utils/assignChunkIds.ts b/src/utils/assignChunkIds.ts new file mode 100644 index 00000000000..bd5fbcb667a --- /dev/null +++ b/src/utils/assignChunkIds.ts @@ -0,0 +1,50 @@ +import Chunk from '../Chunk'; +import { InputOptions, OutputOptions } from '../rollup/types'; +import { Addons } from './addons'; +import { basename } from './path'; + +export function assignChunkIds( + chunks: Chunk[], + singleChunk: Chunk | void, + inputOptions: InputOptions, + outputOptions: OutputOptions, + inputBase: string, + addons: Addons +) { + const usedIds: Record = {}; + const [entryChunks, otherChunks] = chunks.reduce( + ([entryChunks, otherChunks], chunk) => { + (chunk.facadeModule && chunk.facadeModule.isEntryPoint ? entryChunks : otherChunks).push( + chunk + ); + return [entryChunks, otherChunks]; + }, + [[], []] + ); + + // make sure entry chunk names take precedence with regard to deconflicting + const chunksForNaming: Chunk[] = entryChunks.concat(otherChunks); + for (let i = 0; i < chunksForNaming.length; i++) { + const chunk = chunksForNaming[i]; + + if (chunk === singleChunk) { + singleChunk.id = basename( + outputOptions.file || + (inputOptions.input instanceof Array ? inputOptions.input[0] : inputOptions.input) + ); + } else if (inputOptions.experimentalPreserveModules) { + chunk.generateIdPreserveModules(inputBase, usedIds); + } else { + let pattern, patternName; + if (chunk.facadeModule && chunk.facadeModule.isEntryPoint) { + pattern = outputOptions.entryFileNames || '[name].js'; + patternName = 'output.entryFileNames'; + } else { + pattern = outputOptions.chunkFileNames || '[name]-[hash].js'; + patternName = 'output.chunkFileNames'; + } + chunk.generateId(pattern, patternName, addons, outputOptions, usedIds); + } + usedIds[chunk.id] = true; + } +} diff --git a/src/utils/chunkColouring.ts b/src/utils/chunkColouring.ts new file mode 100644 index 00000000000..973f26ee708 --- /dev/null +++ b/src/utils/chunkColouring.ts @@ -0,0 +1,83 @@ +import ExternalModule from '../ExternalModule'; +import Module from '../Module'; +import { randomUint8Array, Uint8ArrayXor } from './entryHashing'; +import { error } from './error'; +import { relative } from './path'; + +export function assignChunkColouringHashes( + entryModules: Module[], + manualChunkModules: Record +) { + let currentEntry: Module, currentEntryHash: Uint8Array; + let modulesVisitedForCurrentEntry: { [id: string]: boolean }; + const handledEntryPoints: { [id: string]: boolean } = {}; + const dynamicImports: Set = new Set(); + + const addCurrentEntryColourToModule = (module: Module) => { + if (currentEntry.chunkAlias) { + module.chunkAlias = currentEntry.chunkAlias; + module.entryPointsHash = currentEntryHash; + } else { + Uint8ArrayXor(module.entryPointsHash, currentEntryHash); + } + + for (const dependency of module.dependencies) { + if (dependency instanceof ExternalModule || dependency.id in modulesVisitedForCurrentEntry) { + continue; + } + modulesVisitedForCurrentEntry[dependency.id] = true; + if (!handledEntryPoints[dependency.id] && !dependency.chunkAlias) + addCurrentEntryColourToModule(dependency); + } + + for (const { resolution } of module.dynamicImports) { + if ( + resolution instanceof Module && + resolution.isDynamicEntryPoint && + !resolution.chunkAlias + ) { + dynamicImports.add(resolution); + } + } + }; + + if (manualChunkModules) { + for (const chunkName of Object.keys(manualChunkModules)) { + currentEntryHash = randomUint8Array(10); + + for (currentEntry of manualChunkModules[chunkName]) { + if (currentEntry.chunkAlias) { + error({ + code: 'INVALID_CHUNK', + message: `Cannot assign ${relative( + process.cwd(), + currentEntry.id + )} to the "${chunkName}" chunk as it is already in the "${ + currentEntry.chunkAlias + }" chunk. +Try defining "${chunkName}" first in the manualChunks definitions of the Rollup configuration.` + }); + } + currentEntry.chunkAlias = chunkName; + modulesVisitedForCurrentEntry = { [currentEntry.id]: true }; + addCurrentEntryColourToModule(currentEntry); + } + } + } + + for (currentEntry of entryModules) { + handledEntryPoints[currentEntry.id] = true; + currentEntryHash = randomUint8Array(10); + modulesVisitedForCurrentEntry = { [currentEntry.id]: null }; + addCurrentEntryColourToModule(currentEntry); + } + + for (currentEntry of Array.from(dynamicImports)) { + if (handledEntryPoints[currentEntry.id]) { + continue; + } + currentEntryHash = randomUint8Array(10); + modulesVisitedForCurrentEntry = { [currentEntry.id]: null }; + addCurrentEntryColourToModule(currentEntry); + } +} diff --git a/src/utils/collapseSourcemaps.ts b/src/utils/collapseSourcemaps.ts index 1f624c0eba0..8c2da89822b 100644 --- a/src/utils/collapseSourcemaps.ts +++ b/src/utils/collapseSourcemaps.ts @@ -2,7 +2,7 @@ import { DecodedSourceMap, SourceMap } from 'magic-string'; import Chunk from '../Chunk'; import Module from '../Module'; import { ExistingRawSourceMap, RawSourceMap } from '../rollup/types'; -import error from './error'; +import { error } from './error'; import { basename, dirname, relative, resolve } from './path'; class Source { diff --git a/src/utils/default-plugin.ts b/src/utils/defaultPlugin.ts similarity index 98% rename from src/utils/default-plugin.ts rename to src/utils/defaultPlugin.ts index 6997e175d79..6478e6a3410 100644 --- a/src/utils/default-plugin.ts +++ b/src/utils/defaultPlugin.ts @@ -1,5 +1,5 @@ import { InputOptions, Plugin } from '../rollup/types'; -import error from './error'; +import { error } from './error'; import { lstatSync, readdirSync, readFileSync, realpathSync } from './fs'; // eslint-disable-line import { basename, dirname, isAbsolute, resolve } from './path'; diff --git a/src/utils/error.ts b/src/utils/error.ts index b9e94049bb1..b7a20fc3f55 100644 --- a/src/utils/error.ts +++ b/src/utils/error.ts @@ -2,7 +2,7 @@ import { locate } from 'locate-character'; import { RollupError, RollupWarning } from '../rollup/types'; import getCodeFrame from './getCodeFrame'; -export default function error(base: Error | RollupError, props?: RollupError) { +export function error(base: Error | RollupError, props?: RollupError) { if (base instanceof Error === false) base = Object.assign(new Error(base.message), base); if (props) Object.assign(base, props); throw base; diff --git a/src/utils/execution-order.ts b/src/utils/execution-order.ts deleted file mode 100644 index 2e483593d19..00000000000 --- a/src/utils/execution-order.ts +++ /dev/null @@ -1,147 +0,0 @@ -import ExternalModule from '../ExternalModule'; -import Module from '../Module'; -import { randomUint8Array, Uint8ArrayEqual, Uint8ArrayXor } from './entryHashing'; -import error from './error'; -import { relative } from './path'; -import relativeId from './relativeId'; - -interface OrderedExecutionUnit { - execIndex: number; -} - -const compareExecIndex = (unitA: T, unitB: T) => - unitA.execIndex > unitB.execIndex ? 1 : -1; - -export function sortByExecutionOrder(units: OrderedExecutionUnit[]) { - units.sort(compareExecIndex); -} - -export function analyzeModuleExecution( - entryModules: Module[], - generateChunkColouringHashes: boolean, - inlineDynamicImports: boolean, - manualChunkModules: Record -) { - let curEntry: Module, curEntryHash: Uint8Array; - const cyclePaths: string[][] = []; - const allSeen: { [id: string]: boolean } = {}; - - const orderedModules: Module[] = []; - let analyzedModuleCount = 0; - - const dynamicImports: Module[] = []; - const dynamicImportAliases: string[] = []; - - let parents: { [id: string]: string }; - - const visit = (module: Module) => { - // Track entry point graph colouring by tracing all modules loaded by a given - // entry point and colouring those modules by the hash of its id. Colours are mixed as - // hash xors, providing the unique colouring of the graph into unique hash chunks. - // This is really all there is to automated chunking, the rest is chunk wiring. - if (generateChunkColouringHashes) { - if (!curEntry.chunkAlias) { - Uint8ArrayXor(module.entryPointsHash, curEntryHash); - } else { - // manual chunks are indicated in this phase by having a chunk alias - // they are treated as a single colour in the colouring - // and aren't divisable by future colourings - module.chunkAlias = curEntry.chunkAlias; - module.entryPointsHash = curEntryHash; - } - } - - for (const depModule of module.dependencies) { - if (depModule instanceof ExternalModule) { - depModule.execIndex = analyzedModuleCount++; - continue; - } - - if (depModule.id in parents) { - if (!allSeen[depModule.id]) { - cyclePaths.push(getCyclePath(depModule.id, module.id, parents)); - } - continue; - } - - parents[depModule.id] = module.id; - if (!depModule.isEntryPoint && !depModule.chunkAlias) visit(depModule); - } - - for (const dynamicModule of module.dynamicImportResolutions) { - if (!(dynamicModule.resolution instanceof Module)) continue; - // If the parent module of a dynamic import is to a child module whose graph - // colouring is the same as the parent module, then that dynamic import does - // not need to be treated as a new entry point as it is in the static graph - if ( - !generateChunkColouringHashes || - (!dynamicModule.resolution.chunkAlias && - !Uint8ArrayEqual(dynamicModule.resolution.entryPointsHash, curEntry.entryPointsHash)) - ) { - if (dynamicImports.indexOf(dynamicModule.resolution) === -1) { - dynamicImports.push(dynamicModule.resolution); - dynamicImportAliases.push(dynamicModule.alias); - } - } - } - - if (allSeen[module.id]) return; - allSeen[module.id] = true; - - module.execIndex = analyzedModuleCount++; - orderedModules.push(module); - }; - - if (generateChunkColouringHashes && manualChunkModules) { - for (const chunkName of Object.keys(manualChunkModules)) { - curEntryHash = randomUint8Array(10); - - for (curEntry of manualChunkModules[chunkName]) { - if (curEntry.chunkAlias) { - error({ - code: 'INVALID_CHUNK', - message: `Cannot assign ${relative( - process.cwd(), - curEntry.id - )} to the "${chunkName}" chunk as it is already in the "${curEntry.chunkAlias}" chunk. -Try defining "${chunkName}" first in the manualChunks definitions of the Rollup configuration.` - }); - } - curEntry.chunkAlias = chunkName; - parents = { [curEntry.id]: null }; - visit(curEntry); - } - } - } - - for (curEntry of entryModules) { - curEntry.isEntryPoint = true; - curEntryHash = randomUint8Array(10); - parents = { [curEntry.id]: null }; - visit(curEntry); - } - - // new items can be added during this loop - for (curEntry of dynamicImports) { - if (curEntry.isEntryPoint) continue; - if (!inlineDynamicImports) curEntry.isEntryPoint = true; - curEntryHash = randomUint8Array(10); - parents = { [curEntry.id]: null }; - visit(curEntry); - } - - return { orderedModules, dynamicImports, dynamicImportAliases, cyclePaths }; -} - -function getCyclePath(id: string, parentId: string, parents: { [id: string]: string | null }) { - const path = [relativeId(id)]; - let curId = parentId; - while (curId !== id) { - path.push(relativeId(curId)); - curId = parents[curId]; - if (!curId) break; - } - path.push(path[0]); - path.reverse(); - return path; -} diff --git a/src/utils/executionOrder.ts b/src/utils/executionOrder.ts new file mode 100644 index 00000000000..29f685abb78 --- /dev/null +++ b/src/utils/executionOrder.ts @@ -0,0 +1,89 @@ +import ExternalModule from '../ExternalModule'; +import Module from '../Module'; +import relativeId from './relativeId'; + +interface OrderedExecutionUnit { + execIndex: number; +} + +const compareExecIndex = (unitA: T, unitB: T) => + unitA.execIndex > unitB.execIndex ? 1 : -1; + +export function sortByExecutionOrder(units: OrderedExecutionUnit[]) { + units.sort(compareExecIndex); +} + +export function analyseModuleExecution(entryModules: Module[]) { + let nextExecIndex = 0; + let inStaticGraph = true; + const cyclePaths: string[][] = []; + const analysedModules: { [id: string]: boolean } = {}; + const orderedModules: Module[] = []; + const dynamicImports: Module[] = []; + const parents: { [id: string]: string | null } = {}; + + const analyseModule = (module: Module | ExternalModule) => { + if (analysedModules[module.id]) return; + + if (module instanceof ExternalModule) { + module.execIndex = nextExecIndex++; + analysedModules[module.id] = true; + return; + } + + if (inStaticGraph) { + module.isExecuted = true; + } + for (const dependency of module.dependencies) { + if (dependency.id in parents) { + if (!analysedModules[dependency.id]) { + cyclePaths.push(getCyclePath(dependency.id, module.id, parents)); + } + continue; + } + parents[dependency.id] = module.id; + analyseModule(dependency); + } + + for (const { resolution } of module.dynamicImports) { + if (resolution instanceof Module && dynamicImports.indexOf(resolution) === -1) { + dynamicImports.push(resolution); + } + } + + module.execIndex = nextExecIndex++; + analysedModules[module.id] = true; + orderedModules.push(module); + }; + + for (const curEntry of entryModules) { + curEntry.isEntryPoint = true; + if (!parents[curEntry.id]) { + parents[curEntry.id] = null; + analyseModule(curEntry); + } + } + + inStaticGraph = false; + for (const curEntry of dynamicImports) { + if (!parents[curEntry.id]) { + parents[curEntry.id] = null; + analyseModule(curEntry); + } + } + + return { orderedModules, cyclePaths }; +} + +function getCyclePath(id: string, parentId: string, parents: { [id: string]: string | null }) { + const path = [relativeId(id)]; + let curId = parentId; + while (curId !== id) { + path.push(relativeId(curId)); + curId = parents[curId]; + if (!curId) break; + } + path.push(path[0]); + path.reverse(); + return path; +} diff --git a/src/utils/getExportMode.ts b/src/utils/getExportMode.ts index 8a20416a61d..174719b7a27 100644 --- a/src/utils/getExportMode.ts +++ b/src/utils/getExportMode.ts @@ -1,6 +1,6 @@ import Chunk from '../Chunk'; import { OutputOptions } from '../rollup/types'; -import error from './error'; +import { error } from './error'; function badExports(option: string, keys: string[]) { error({ @@ -31,7 +31,12 @@ export default function getExportMode( } else if (exportKeys.length === 1 && exportKeys[0] === 'default') { exportMode = 'default'; } else { - if (chunk.isEntryModuleFacade && format !== 'es' && exportKeys.indexOf('default') !== -1) { + if ( + chunk.facadeModule !== null && + chunk.facadeModule.isEntryPoint && + format !== 'es' && + exportKeys.indexOf('default') !== -1 + ) { chunk.graph.warn({ code: 'MIXED_EXPORTS', message: `Using named and default exports together. Consumers of your bundle will have to use ${name || diff --git a/src/utils/mergeOptions.ts b/src/utils/mergeOptions.ts index dba8c27d8eb..37e96b45fae 100644 --- a/src/utils/mergeOptions.ts +++ b/src/utils/mergeOptions.ts @@ -212,7 +212,7 @@ function getInputOptions( input: getOption('input'), manualChunks: getOption('manualChunks'), chunkGroupingSize: getOption('chunkGroupingSize', 5000), - optimizeChunks: getOption('optimizeChunks'), + experimentalOptimizeChunks: getOption('experimentalOptimizeChunks'), moduleContext: config.moduleContext, onwarn: getOnWarn(config, command, defaultOnWarnHandler), perf: getOption('perf', false), diff --git a/src/utils/pluginDriver.ts b/src/utils/pluginDriver.ts index bc2992e3497..959872ca9e9 100644 --- a/src/utils/pluginDriver.ts +++ b/src/utils/pluginDriver.ts @@ -11,8 +11,8 @@ import { Watcher } from '../rollup/types'; import { createAssetPluginHooks, EmitAsset } from './assetHooks'; -import { getRollupDefaultPlugin } from './default-plugin'; -import error from './error'; +import { getRollupDefaultPlugin } from './defaultPlugin'; +import { error } from './error'; export interface PluginDriver { emitAsset: EmitAsset; diff --git a/src/utils/renderChunk.ts b/src/utils/renderChunk.ts index 0fb3aff5a62..2056538ccb1 100644 --- a/src/utils/renderChunk.ts +++ b/src/utils/renderChunk.ts @@ -2,7 +2,7 @@ import { decode } from 'sourcemap-codec'; import Chunk from '../Chunk'; import Graph from '../Graph'; import { OutputOptions, Plugin, RawSourceMap, RenderedChunk } from '../rollup/types'; -import error from './error'; +import { error } from './error'; export default function renderChunk({ graph, diff --git a/src/utils/renderNamePattern.ts b/src/utils/renderNamePattern.ts index 765cbf336dd..12e14666b83 100644 --- a/src/utils/renderNamePattern.ts +++ b/src/utils/renderNamePattern.ts @@ -1,4 +1,4 @@ -import error from './error'; +import { error } from './error'; import { extname } from './path'; import { isPlainName } from './relativeId'; diff --git a/src/utils/transform.ts b/src/utils/transform.ts index 29c2b901554..45c20c8f6c1 100644 --- a/src/utils/transform.ts +++ b/src/utils/transform.ts @@ -13,7 +13,7 @@ import { TransformSourceDescription } from '../rollup/types'; import { createTransformEmitAsset, EmitAsset } from './assetHooks'; -import error, { augmentCodeLocation } from './error'; +import { augmentCodeLocation, error } from './error'; import { dirname, resolve } from './path'; import { trackPluginCache } from './pluginDriver'; diff --git a/src/utils/traverseStaticDependencies.ts b/src/utils/traverseStaticDependencies.ts new file mode 100644 index 00000000000..c56fba4ad81 --- /dev/null +++ b/src/utils/traverseStaticDependencies.ts @@ -0,0 +1,19 @@ +import ExternalModule from '../ExternalModule'; +import Module from '../Module'; + +export function visitStaticDependencies( + entryModule: Module | ExternalModule, + areDependenciesSkipped: (module: Module | ExternalModule) => boolean +) { + const modules = [entryModule]; + const visitedModules: { [id: string]: true } = {}; + for (const module of modules) { + if (areDependenciesSkipped(module) || module instanceof ExternalModule) continue; + for (const dependency of module.dependencies) { + if (!visitedModules[dependency.id]) { + visitedModules[dependency.id] = true; + modules.push(dependency); + } + } + } +} diff --git a/test/chunking-form/samples/aliasing-extensions/_config.js b/test/chunking-form/samples/aliasing-extensions/_config.js index aa5a872d5b7..238c925f8e4 100644 --- a/test/chunking-form/samples/aliasing-extensions/_config.js +++ b/test/chunking-form/samples/aliasing-extensions/_config.js @@ -1,6 +1,9 @@ module.exports = { description: 'chunk aliasing with extensions', options: { - input: ['main1', 'main2', 'main3.ts'] + input: ['main1', 'main2', 'main3.ts'], + output: { + chunkFileNames: 'generated-[name].js' + } } }; diff --git a/test/chunking-form/samples/aliasing-extensions/_expected/amd/main4.dynamic.js b/test/chunking-form/samples/aliasing-extensions/_expected/amd/generated-chunk.js similarity index 100% rename from test/chunking-form/samples/aliasing-extensions/_expected/amd/main4.dynamic.js rename to test/chunking-form/samples/aliasing-extensions/_expected/amd/generated-chunk.js diff --git a/test/chunking-form/samples/aliasing-extensions/_expected/amd/main5.js b/test/chunking-form/samples/aliasing-extensions/_expected/amd/generated-chunk2.js similarity index 100% rename from test/chunking-form/samples/aliasing-extensions/_expected/amd/main5.js rename to test/chunking-form/samples/aliasing-extensions/_expected/amd/generated-chunk2.js diff --git a/test/chunking-form/samples/aliasing-extensions/_expected/amd/main1.js b/test/chunking-form/samples/aliasing-extensions/_expected/amd/main1.js index 3913745da6c..97a0f22a858 100644 --- a/test/chunking-form/samples/aliasing-extensions/_expected/amd/main1.js +++ b/test/chunking-form/samples/aliasing-extensions/_expected/amd/main1.js @@ -1,7 +1,7 @@ define(['require'], function (require) { 'use strict'; console.log('main1'); - new Promise(function (resolve, reject) { require(["./main4.dynamic.js"], resolve, reject) }); - new Promise(function (resolve, reject) { require(["./main5.js"], resolve, reject) }); + new Promise(function (resolve, reject) { require(['./generated-chunk.js'], resolve, reject) }); + new Promise(function (resolve, reject) { require(['./generated-chunk2.js'], resolve, reject) }); }); diff --git a/test/chunking-form/samples/aliasing-extensions/_expected/cjs/main4.dynamic.js b/test/chunking-form/samples/aliasing-extensions/_expected/cjs/generated-chunk.js similarity index 100% rename from test/chunking-form/samples/aliasing-extensions/_expected/cjs/main4.dynamic.js rename to test/chunking-form/samples/aliasing-extensions/_expected/cjs/generated-chunk.js diff --git a/test/chunking-form/samples/aliasing-extensions/_expected/cjs/main5.js b/test/chunking-form/samples/aliasing-extensions/_expected/cjs/generated-chunk2.js similarity index 100% rename from test/chunking-form/samples/aliasing-extensions/_expected/cjs/main5.js rename to test/chunking-form/samples/aliasing-extensions/_expected/cjs/generated-chunk2.js diff --git a/test/chunking-form/samples/aliasing-extensions/_expected/cjs/main1.js b/test/chunking-form/samples/aliasing-extensions/_expected/cjs/main1.js index c2db120ae65..ffb10b14b6d 100644 --- a/test/chunking-form/samples/aliasing-extensions/_expected/cjs/main1.js +++ b/test/chunking-form/samples/aliasing-extensions/_expected/cjs/main1.js @@ -1,5 +1,5 @@ 'use strict'; console.log('main1'); -Promise.resolve(require("./main4.dynamic.js")); -Promise.resolve(require("./main5.js")); +Promise.resolve(require('./generated-chunk.js')); +Promise.resolve(require('./generated-chunk2.js')); diff --git a/test/chunking-form/samples/aliasing-extensions/_expected/es/main4.dynamic.js b/test/chunking-form/samples/aliasing-extensions/_expected/es/generated-chunk.js similarity index 100% rename from test/chunking-form/samples/aliasing-extensions/_expected/es/main4.dynamic.js rename to test/chunking-form/samples/aliasing-extensions/_expected/es/generated-chunk.js diff --git a/test/chunking-form/samples/aliasing-extensions/_expected/es/main5.js b/test/chunking-form/samples/aliasing-extensions/_expected/es/generated-chunk2.js similarity index 100% rename from test/chunking-form/samples/aliasing-extensions/_expected/es/main5.js rename to test/chunking-form/samples/aliasing-extensions/_expected/es/generated-chunk2.js diff --git a/test/chunking-form/samples/aliasing-extensions/_expected/es/main1.js b/test/chunking-form/samples/aliasing-extensions/_expected/es/main1.js index 1d07e379985..de1c78214cd 100644 --- a/test/chunking-form/samples/aliasing-extensions/_expected/es/main1.js +++ b/test/chunking-form/samples/aliasing-extensions/_expected/es/main1.js @@ -1,3 +1,3 @@ console.log('main1'); -import("./main4.dynamic.js"); -import("./main5.js"); +import('./generated-chunk.js'); +import('./generated-chunk2.js'); diff --git a/test/chunking-form/samples/aliasing-extensions/_expected/system/main4.dynamic.js b/test/chunking-form/samples/aliasing-extensions/_expected/system/generated-chunk.js similarity index 100% rename from test/chunking-form/samples/aliasing-extensions/_expected/system/main4.dynamic.js rename to test/chunking-form/samples/aliasing-extensions/_expected/system/generated-chunk.js diff --git a/test/chunking-form/samples/aliasing-extensions/_expected/system/main5.js b/test/chunking-form/samples/aliasing-extensions/_expected/system/generated-chunk2.js similarity index 100% rename from test/chunking-form/samples/aliasing-extensions/_expected/system/main5.js rename to test/chunking-form/samples/aliasing-extensions/_expected/system/generated-chunk2.js diff --git a/test/chunking-form/samples/aliasing-extensions/_expected/system/main1.js b/test/chunking-form/samples/aliasing-extensions/_expected/system/main1.js index 55da5619feb..fe72dd01fb6 100644 --- a/test/chunking-form/samples/aliasing-extensions/_expected/system/main1.js +++ b/test/chunking-form/samples/aliasing-extensions/_expected/system/main1.js @@ -4,8 +4,8 @@ System.register([], function (exports, module) { execute: function () { console.log('main1'); - module.import("./main4.dynamic.js"); - module.import("./main5.js"); + module.import('./generated-chunk.js'); + module.import('./generated-chunk2.js'); } }; diff --git a/test/chunking-form/samples/dynamic-import-chained/_config.js b/test/chunking-form/samples/dynamic-import-chained/_config.js new file mode 100644 index 00000000000..b510f0c0616 --- /dev/null +++ b/test/chunking-form/samples/dynamic-import-chained/_config.js @@ -0,0 +1,9 @@ +module.exports = { + description: 'includes chained dynamic imports', + options: { + input: 'main.js', + output: { + chunkFileNames: 'generated-chunk.js' + } + } +}; diff --git a/test/chunking-form/samples/manual-chunks-dynamic/_expected/amd/dynamic-10698fc3.js b/test/chunking-form/samples/dynamic-import-chained/_expected/amd/generated-chunk.js similarity index 65% rename from test/chunking-form/samples/manual-chunks-dynamic/_expected/amd/dynamic-10698fc3.js rename to test/chunking-form/samples/dynamic-import-chained/_expected/amd/generated-chunk.js index f9f8229aa40..af27f254599 100644 --- a/test/chunking-form/samples/manual-chunks-dynamic/_expected/amd/dynamic-10698fc3.js +++ b/test/chunking-form/samples/dynamic-import-chained/_expected/amd/generated-chunk.js @@ -1,5 +1,5 @@ define(function () { 'use strict'; - + console.log('dep2'); }); diff --git a/test/chunking-form/samples/dynamic-import-chained/_expected/amd/generated-chunk2.js b/test/chunking-form/samples/dynamic-import-chained/_expected/amd/generated-chunk2.js new file mode 100644 index 00000000000..dd1c3279a6c --- /dev/null +++ b/test/chunking-form/samples/dynamic-import-chained/_expected/amd/generated-chunk2.js @@ -0,0 +1,6 @@ +define(['require'], function (require) { 'use strict'; + + console.log('dep1'); + new Promise(function (resolve, reject) { require(['./generated-chunk.js'], resolve, reject) }); + +}); diff --git a/test/chunking-form/samples/dynamic-import-chained/_expected/amd/main.js b/test/chunking-form/samples/dynamic-import-chained/_expected/amd/main.js new file mode 100644 index 00000000000..5ccfb90eecb --- /dev/null +++ b/test/chunking-form/samples/dynamic-import-chained/_expected/amd/main.js @@ -0,0 +1,6 @@ +define(['require'], function (require) { 'use strict'; + + console.log('main'); + new Promise(function (resolve, reject) { require(['./generated-chunk2.js'], resolve, reject) }); + +}); diff --git a/test/chunking-form/samples/dynamic-import-chained/_expected/cjs/generated-chunk.js b/test/chunking-form/samples/dynamic-import-chained/_expected/cjs/generated-chunk.js new file mode 100644 index 00000000000..132fb447b0c --- /dev/null +++ b/test/chunking-form/samples/dynamic-import-chained/_expected/cjs/generated-chunk.js @@ -0,0 +1,3 @@ +'use strict'; + +console.log('dep2'); diff --git a/test/chunking-form/samples/dynamic-import-chained/_expected/cjs/generated-chunk2.js b/test/chunking-form/samples/dynamic-import-chained/_expected/cjs/generated-chunk2.js new file mode 100644 index 00000000000..264ed3db946 --- /dev/null +++ b/test/chunking-form/samples/dynamic-import-chained/_expected/cjs/generated-chunk2.js @@ -0,0 +1,4 @@ +'use strict'; + +console.log('dep1'); +Promise.resolve(require('./generated-chunk.js')); diff --git a/test/chunking-form/samples/dynamic-import-chained/_expected/cjs/main.js b/test/chunking-form/samples/dynamic-import-chained/_expected/cjs/main.js new file mode 100644 index 00000000000..f94f250a8bb --- /dev/null +++ b/test/chunking-form/samples/dynamic-import-chained/_expected/cjs/main.js @@ -0,0 +1,4 @@ +'use strict'; + +console.log('main'); +Promise.resolve(require('./generated-chunk2.js')); diff --git a/test/chunking-form/samples/dynamic-import-chained/_expected/es/generated-chunk.js b/test/chunking-form/samples/dynamic-import-chained/_expected/es/generated-chunk.js new file mode 100644 index 00000000000..f5325d80e8a --- /dev/null +++ b/test/chunking-form/samples/dynamic-import-chained/_expected/es/generated-chunk.js @@ -0,0 +1 @@ +console.log('dep2'); diff --git a/test/chunking-form/samples/dynamic-import-chained/_expected/es/generated-chunk2.js b/test/chunking-form/samples/dynamic-import-chained/_expected/es/generated-chunk2.js new file mode 100644 index 00000000000..829d0490ba6 --- /dev/null +++ b/test/chunking-form/samples/dynamic-import-chained/_expected/es/generated-chunk2.js @@ -0,0 +1,2 @@ +console.log('dep1'); +import('./generated-chunk.js'); diff --git a/test/chunking-form/samples/dynamic-import-chained/_expected/es/main.js b/test/chunking-form/samples/dynamic-import-chained/_expected/es/main.js new file mode 100644 index 00000000000..8e124b5d186 --- /dev/null +++ b/test/chunking-form/samples/dynamic-import-chained/_expected/es/main.js @@ -0,0 +1,2 @@ +console.log('main'); +import('./generated-chunk2.js'); diff --git a/test/chunking-form/samples/manual-chunks-dynamic/_expected/system/dynamic-e8bd5876.js b/test/chunking-form/samples/dynamic-import-chained/_expected/system/generated-chunk.js similarity index 82% rename from test/chunking-form/samples/manual-chunks-dynamic/_expected/system/dynamic-e8bd5876.js rename to test/chunking-form/samples/dynamic-import-chained/_expected/system/generated-chunk.js index 3b9098cda90..135361ec64d 100644 --- a/test/chunking-form/samples/manual-chunks-dynamic/_expected/system/dynamic-e8bd5876.js +++ b/test/chunking-form/samples/dynamic-import-chained/_expected/system/generated-chunk.js @@ -3,7 +3,7 @@ System.register([], function (exports, module) { return { execute: function () { - + console.log('dep2'); } }; diff --git a/test/chunking-form/samples/dynamic-import-chained/_expected/system/generated-chunk2.js b/test/chunking-form/samples/dynamic-import-chained/_expected/system/generated-chunk2.js new file mode 100644 index 00000000000..83e8602aefd --- /dev/null +++ b/test/chunking-form/samples/dynamic-import-chained/_expected/system/generated-chunk2.js @@ -0,0 +1,11 @@ +System.register([], function (exports, module) { + 'use strict'; + return { + execute: function () { + + console.log('dep1'); + module.import('./generated-chunk.js'); + + } + }; +}); diff --git a/test/chunking-form/samples/dynamic-import-chained/_expected/system/main.js b/test/chunking-form/samples/dynamic-import-chained/_expected/system/main.js new file mode 100644 index 00000000000..7dfd4a28cae --- /dev/null +++ b/test/chunking-form/samples/dynamic-import-chained/_expected/system/main.js @@ -0,0 +1,11 @@ +System.register([], function (exports, module) { + 'use strict'; + return { + execute: function () { + + console.log('main'); + module.import('./generated-chunk2.js'); + + } + }; +}); diff --git a/test/chunking-form/samples/dynamic-import-chained/dep1.js b/test/chunking-form/samples/dynamic-import-chained/dep1.js new file mode 100644 index 00000000000..78b71aab977 --- /dev/null +++ b/test/chunking-form/samples/dynamic-import-chained/dep1.js @@ -0,0 +1,2 @@ +console.log('dep1'); +import('./dep2.js'); diff --git a/test/chunking-form/samples/dynamic-import-chained/dep2.js b/test/chunking-form/samples/dynamic-import-chained/dep2.js new file mode 100644 index 00000000000..f5325d80e8a --- /dev/null +++ b/test/chunking-form/samples/dynamic-import-chained/dep2.js @@ -0,0 +1 @@ +console.log('dep2'); diff --git a/test/chunking-form/samples/dynamic-import-chained/main.js b/test/chunking-form/samples/dynamic-import-chained/main.js new file mode 100644 index 00000000000..6626641d177 --- /dev/null +++ b/test/chunking-form/samples/dynamic-import-chained/main.js @@ -0,0 +1,5 @@ +console.log('main'); + +// to mess up the internal execution order +if (false) import('./dep2.js') +import('./dep1.js'); diff --git a/test/chunking-form/samples/dynamic-import-treeshaking/_expected/amd/dep2.js b/test/chunking-form/samples/dynamic-import-chunking/_expected/amd/chunk-8ea4f89e.js similarity index 73% rename from test/chunking-form/samples/dynamic-import-treeshaking/_expected/amd/dep2.js rename to test/chunking-form/samples/dynamic-import-chunking/_expected/amd/chunk-8ea4f89e.js index 0d4b271bf1a..60eba601593 100644 --- a/test/chunking-form/samples/dynamic-import-treeshaking/_expected/amd/dep2.js +++ b/test/chunking-form/samples/dynamic-import-chunking/_expected/amd/chunk-8ea4f89e.js @@ -6,6 +6,4 @@ define(['exports', './chunk-7b720877.js'], function (exports, __chunk_1) { 'use exports.mult = mult; - Object.defineProperty(exports, '__esModule', { value: true }); - }); diff --git a/test/chunking-form/samples/dynamic-import-chunking/_expected/amd/dep2.js b/test/chunking-form/samples/dynamic-import-chunking/_expected/amd/dep2.js deleted file mode 100644 index 0d4b271bf1a..00000000000 --- a/test/chunking-form/samples/dynamic-import-chunking/_expected/amd/dep2.js +++ /dev/null @@ -1,11 +0,0 @@ -define(['exports', './chunk-7b720877.js'], function (exports, __chunk_1) { 'use strict'; - - function mult (num) { - return num + __chunk_1.multiplier; - } - - exports.mult = mult; - - Object.defineProperty(exports, '__esModule', { value: true }); - -}); diff --git a/test/chunking-form/samples/dynamic-import-chunking/_expected/amd/main.js b/test/chunking-form/samples/dynamic-import-chunking/_expected/amd/main.js index 9bbdca63f2e..30e89b9397c 100644 --- a/test/chunking-form/samples/dynamic-import-chunking/_expected/amd/main.js +++ b/test/chunking-form/samples/dynamic-import-chunking/_expected/amd/main.js @@ -9,7 +9,7 @@ define(['require', './chunk-7b720877.js'], function (require, __chunk_1) { 'use } function dynamic (num) { - return new Promise(function (resolve, reject) { require(["./dep2.js"], resolve, reject) }) + return new Promise(function (resolve, reject) { require(['./chunk-8ea4f89e.js'], resolve, reject) }) .then(dep2 => { return dep2.mult(num); }); diff --git a/test/chunking-form/samples/dynamic-import-treeshaking/_expected/cjs/dep2.js b/test/chunking-form/samples/dynamic-import-chunking/_expected/cjs/chunk-38762abc.js similarity index 69% rename from test/chunking-form/samples/dynamic-import-treeshaking/_expected/cjs/dep2.js rename to test/chunking-form/samples/dynamic-import-chunking/_expected/cjs/chunk-38762abc.js index 5c0ba52bcf6..e156f0e2be6 100644 --- a/test/chunking-form/samples/dynamic-import-treeshaking/_expected/cjs/dep2.js +++ b/test/chunking-form/samples/dynamic-import-chunking/_expected/cjs/chunk-38762abc.js @@ -1,7 +1,5 @@ 'use strict'; -Object.defineProperty(exports, '__esModule', { value: true }); - var __chunk_1 = require('./chunk-3a53aa58.js'); function mult (num) { diff --git a/test/chunking-form/samples/dynamic-import-chunking/_expected/cjs/dep2.js b/test/chunking-form/samples/dynamic-import-chunking/_expected/cjs/dep2.js deleted file mode 100644 index 5c0ba52bcf6..00000000000 --- a/test/chunking-form/samples/dynamic-import-chunking/_expected/cjs/dep2.js +++ /dev/null @@ -1,11 +0,0 @@ -'use strict'; - -Object.defineProperty(exports, '__esModule', { value: true }); - -var __chunk_1 = require('./chunk-3a53aa58.js'); - -function mult (num) { - return num + __chunk_1.multiplier; -} - -exports.mult = mult; diff --git a/test/chunking-form/samples/dynamic-import-chunking/_expected/cjs/main.js b/test/chunking-form/samples/dynamic-import-chunking/_expected/cjs/main.js index 1c4e4a31e0b..1aa12cb7927 100644 --- a/test/chunking-form/samples/dynamic-import-chunking/_expected/cjs/main.js +++ b/test/chunking-form/samples/dynamic-import-chunking/_expected/cjs/main.js @@ -11,7 +11,7 @@ function fn (num) { } function dynamic (num) { - return Promise.resolve(require("./dep2.js")) + return Promise.resolve(require('./chunk-38762abc.js')) .then(dep2 => { return dep2.mult(num); }); diff --git a/test/chunking-form/samples/dynamic-import-chunking/_expected/es/dep2.js b/test/chunking-form/samples/dynamic-import-chunking/_expected/es/chunk-a97cfc63.js similarity index 100% rename from test/chunking-form/samples/dynamic-import-chunking/_expected/es/dep2.js rename to test/chunking-form/samples/dynamic-import-chunking/_expected/es/chunk-a97cfc63.js diff --git a/test/chunking-form/samples/dynamic-import-chunking/_expected/es/main.js b/test/chunking-form/samples/dynamic-import-chunking/_expected/es/main.js index ef18c5069dc..c4b407daf5c 100644 --- a/test/chunking-form/samples/dynamic-import-chunking/_expected/es/main.js +++ b/test/chunking-form/samples/dynamic-import-chunking/_expected/es/main.js @@ -9,7 +9,7 @@ function fn (num) { } function dynamic (num) { - return import("./dep2.js") + return import('./chunk-a97cfc63.js') .then(dep2 => { return dep2.mult(num); }); diff --git a/test/chunking-form/samples/dynamic-import-chunking/_expected/system/dep2.js b/test/chunking-form/samples/dynamic-import-chunking/_expected/system/chunk-b7f9caf2.js similarity index 100% rename from test/chunking-form/samples/dynamic-import-chunking/_expected/system/dep2.js rename to test/chunking-form/samples/dynamic-import-chunking/_expected/system/chunk-b7f9caf2.js diff --git a/test/chunking-form/samples/dynamic-import-chunking/_expected/system/main.js b/test/chunking-form/samples/dynamic-import-chunking/_expected/system/main.js index 4478b7d425f..d9cfae39e95 100644 --- a/test/chunking-form/samples/dynamic-import-chunking/_expected/system/main.js +++ b/test/chunking-form/samples/dynamic-import-chunking/_expected/system/main.js @@ -16,7 +16,7 @@ System.register(['./chunk-4d8f4e43.js'], function (exports, module) { } function dynamic (num) { - return module.import("./dep2.js") + return module.import('./chunk-b7f9caf2.js') .then(dep2 => { return dep2.mult(num); }); diff --git a/test/chunking-form/samples/dynamic-import-facade/_config.js b/test/chunking-form/samples/dynamic-import-facade/_config.js new file mode 100644 index 00000000000..62db88c24ef --- /dev/null +++ b/test/chunking-form/samples/dynamic-import-facade/_config.js @@ -0,0 +1,6 @@ +module.exports = { + description: 'makes sure dynamic chunks are not tainted', + options: { + input: ['main1.js', 'main2.js'] + } +}; diff --git a/test/chunking-form/samples/dynamic-import-facade/_expected/amd/chunk-822f1303.js b/test/chunking-form/samples/dynamic-import-facade/_expected/amd/chunk-822f1303.js new file mode 100644 index 00000000000..74adaf7720f --- /dev/null +++ b/test/chunking-form/samples/dynamic-import-facade/_expected/amd/chunk-822f1303.js @@ -0,0 +1,7 @@ +define(['exports', './chunk-d42319c1.js'], function (exports, dynamic_js) { 'use strict'; + + + + exports.dynamic = dynamic_js.dynamic; + +}); diff --git a/test/chunking-form/samples/dynamic-import-facade/_expected/amd/chunk-d42319c1.js b/test/chunking-form/samples/dynamic-import-facade/_expected/amd/chunk-d42319c1.js new file mode 100644 index 00000000000..7c2370c19a3 --- /dev/null +++ b/test/chunking-form/samples/dynamic-import-facade/_expected/amd/chunk-d42319c1.js @@ -0,0 +1,13 @@ +define(['exports'], function (exports) { 'use strict'; + + console.log('dep'); + + const dep = 'dep'; + + console.log('dynamic', dep); + const dynamic = 'dynamic'; + + exports.dep = dep; + exports.dynamic = dynamic; + +}); diff --git a/test/chunking-form/samples/dynamic-import-facade/_expected/amd/main1.js b/test/chunking-form/samples/dynamic-import-facade/_expected/amd/main1.js new file mode 100644 index 00000000000..f86b485fbd0 --- /dev/null +++ b/test/chunking-form/samples/dynamic-import-facade/_expected/amd/main1.js @@ -0,0 +1,5 @@ +define(['require'], function (require) { 'use strict'; + + new Promise(function (resolve, reject) { require(['./chunk-822f1303.js'], resolve, reject) }).then(({dynamic}) => console.log('main1', dynamic)); + +}); diff --git a/test/chunking-form/samples/dynamic-import-facade/_expected/amd/main2.js b/test/chunking-form/samples/dynamic-import-facade/_expected/amd/main2.js new file mode 100644 index 00000000000..7897d3f5089 --- /dev/null +++ b/test/chunking-form/samples/dynamic-import-facade/_expected/amd/main2.js @@ -0,0 +1,5 @@ +define(['./chunk-d42319c1.js'], function (dynamic_js) { 'use strict'; + + console.log('main2', dynamic_js.dynamic, dynamic_js.dep); + +}); diff --git a/test/chunking-form/samples/dynamic-import-facade/_expected/cjs/chunk-0ad7c258.js b/test/chunking-form/samples/dynamic-import-facade/_expected/cjs/chunk-0ad7c258.js new file mode 100644 index 00000000000..2ec3ea65c66 --- /dev/null +++ b/test/chunking-form/samples/dynamic-import-facade/_expected/cjs/chunk-0ad7c258.js @@ -0,0 +1,7 @@ +'use strict'; + +var dynamic_js = require('./chunk-57ff6d6d.js'); + + + +exports.dynamic = dynamic_js.dynamic; diff --git a/test/chunking-form/samples/dynamic-import-facade/_expected/cjs/chunk-57ff6d6d.js b/test/chunking-form/samples/dynamic-import-facade/_expected/cjs/chunk-57ff6d6d.js new file mode 100644 index 00000000000..210a1e1c5bc --- /dev/null +++ b/test/chunking-form/samples/dynamic-import-facade/_expected/cjs/chunk-57ff6d6d.js @@ -0,0 +1,11 @@ +'use strict'; + +console.log('dep'); + +const dep = 'dep'; + +console.log('dynamic', dep); +const dynamic = 'dynamic'; + +exports.dep = dep; +exports.dynamic = dynamic; diff --git a/test/chunking-form/samples/dynamic-import-facade/_expected/cjs/main1.js b/test/chunking-form/samples/dynamic-import-facade/_expected/cjs/main1.js new file mode 100644 index 00000000000..935d3463248 --- /dev/null +++ b/test/chunking-form/samples/dynamic-import-facade/_expected/cjs/main1.js @@ -0,0 +1,3 @@ +'use strict'; + +Promise.resolve(require('./chunk-0ad7c258.js')).then(({dynamic}) => console.log('main1', dynamic)); diff --git a/test/chunking-form/samples/dynamic-import-facade/_expected/cjs/main2.js b/test/chunking-form/samples/dynamic-import-facade/_expected/cjs/main2.js new file mode 100644 index 00000000000..db275b5f6e4 --- /dev/null +++ b/test/chunking-form/samples/dynamic-import-facade/_expected/cjs/main2.js @@ -0,0 +1,5 @@ +'use strict'; + +var dynamic_js = require('./chunk-57ff6d6d.js'); + +console.log('main2', dynamic_js.dynamic, dynamic_js.dep); diff --git a/test/chunking-form/samples/dynamic-import-facade/_expected/es/chunk-9fd0b968.js b/test/chunking-form/samples/dynamic-import-facade/_expected/es/chunk-9fd0b968.js new file mode 100644 index 00000000000..14faa75894f --- /dev/null +++ b/test/chunking-form/samples/dynamic-import-facade/_expected/es/chunk-9fd0b968.js @@ -0,0 +1 @@ +export { b as dynamic } from './chunk-fa3f0c72.js'; diff --git a/test/chunking-form/samples/dynamic-import-facade/_expected/es/chunk-fa3f0c72.js b/test/chunking-form/samples/dynamic-import-facade/_expected/es/chunk-fa3f0c72.js new file mode 100644 index 00000000000..37053a9255c --- /dev/null +++ b/test/chunking-form/samples/dynamic-import-facade/_expected/es/chunk-fa3f0c72.js @@ -0,0 +1,8 @@ +console.log('dep'); + +const dep = 'dep'; + +console.log('dynamic', dep); +const dynamic = 'dynamic'; + +export { dep as a, dynamic as b }; diff --git a/test/chunking-form/samples/dynamic-import-facade/_expected/es/main1.js b/test/chunking-form/samples/dynamic-import-facade/_expected/es/main1.js new file mode 100644 index 00000000000..64d20ffd0d1 --- /dev/null +++ b/test/chunking-form/samples/dynamic-import-facade/_expected/es/main1.js @@ -0,0 +1 @@ +import('./chunk-9fd0b968.js').then(({dynamic}) => console.log('main1', dynamic)); diff --git a/test/chunking-form/samples/dynamic-import-facade/_expected/es/main2.js b/test/chunking-form/samples/dynamic-import-facade/_expected/es/main2.js new file mode 100644 index 00000000000..288ebafb02c --- /dev/null +++ b/test/chunking-form/samples/dynamic-import-facade/_expected/es/main2.js @@ -0,0 +1,3 @@ +import { a as dep, b as dynamic } from './chunk-fa3f0c72.js'; + +console.log('main2', dynamic, dep); diff --git a/test/chunking-form/samples/dynamic-import-facade/_expected/system/chunk-55e635b3.js b/test/chunking-form/samples/dynamic-import-facade/_expected/system/chunk-55e635b3.js new file mode 100644 index 00000000000..0092d9f8101 --- /dev/null +++ b/test/chunking-form/samples/dynamic-import-facade/_expected/system/chunk-55e635b3.js @@ -0,0 +1,15 @@ +System.register([], function (exports, module) { + 'use strict'; + return { + execute: function () { + + console.log('dep'); + + const dep = exports('a', 'dep'); + + console.log('dynamic', dep); + const dynamic = exports('b', 'dynamic'); + + } + }; +}); diff --git a/test/chunking-form/samples/dynamic-import-facade/_expected/system/chunk-d225f367.js b/test/chunking-form/samples/dynamic-import-facade/_expected/system/chunk-d225f367.js new file mode 100644 index 00000000000..db29f31bc42 --- /dev/null +++ b/test/chunking-form/samples/dynamic-import-facade/_expected/system/chunk-d225f367.js @@ -0,0 +1,13 @@ +System.register(['./chunk-55e635b3.js'], function (exports, module) { + 'use strict'; + return { + setters: [function (module) { + exports('dynamic', module.b); + }], + execute: function () { + + + + } + }; +}); diff --git a/test/chunking-form/samples/dynamic-import-facade/_expected/system/main1.js b/test/chunking-form/samples/dynamic-import-facade/_expected/system/main1.js new file mode 100644 index 00000000000..35f39e567cb --- /dev/null +++ b/test/chunking-form/samples/dynamic-import-facade/_expected/system/main1.js @@ -0,0 +1,10 @@ +System.register([], function (exports, module) { + 'use strict'; + return { + execute: function () { + + module.import('./chunk-d225f367.js').then(({dynamic}) => console.log('main1', dynamic)); + + } + }; +}); diff --git a/test/chunking-form/samples/dynamic-import-facade/_expected/system/main2.js b/test/chunking-form/samples/dynamic-import-facade/_expected/system/main2.js new file mode 100644 index 00000000000..96e037f1b38 --- /dev/null +++ b/test/chunking-form/samples/dynamic-import-facade/_expected/system/main2.js @@ -0,0 +1,15 @@ +System.register(['./chunk-55e635b3.js'], function (exports, module) { + 'use strict'; + var dep, dynamic; + return { + setters: [function (module) { + dep = module.a; + dynamic = module.b; + }], + execute: function () { + + console.log('main2', dynamic, dep); + + } + }; +}); diff --git a/test/chunking-form/samples/dynamic-import-facade/dep.js b/test/chunking-form/samples/dynamic-import-facade/dep.js new file mode 100644 index 00000000000..4a9a55b5887 --- /dev/null +++ b/test/chunking-form/samples/dynamic-import-facade/dep.js @@ -0,0 +1,3 @@ +console.log('dep'); + +export const dep = 'dep'; diff --git a/test/chunking-form/samples/dynamic-import-facade/dynamic.js b/test/chunking-form/samples/dynamic-import-facade/dynamic.js new file mode 100644 index 00000000000..89989daed6f --- /dev/null +++ b/test/chunking-form/samples/dynamic-import-facade/dynamic.js @@ -0,0 +1,4 @@ +import {dep} from './dep'; + +console.log('dynamic', dep); +export const dynamic = 'dynamic'; diff --git a/test/chunking-form/samples/dynamic-import-facade/main1.js b/test/chunking-form/samples/dynamic-import-facade/main1.js new file mode 100644 index 00000000000..69910b8e505 --- /dev/null +++ b/test/chunking-form/samples/dynamic-import-facade/main1.js @@ -0,0 +1 @@ +import('./dynamic.js').then(({dynamic}) => console.log('main1', dynamic)); diff --git a/test/chunking-form/samples/dynamic-import-facade/main2.js b/test/chunking-form/samples/dynamic-import-facade/main2.js new file mode 100644 index 00000000000..9833454d148 --- /dev/null +++ b/test/chunking-form/samples/dynamic-import-facade/main2.js @@ -0,0 +1,4 @@ +import { dep } from './dep.js'; +import { dynamic } from './dynamic.js'; + +console.log('main2', dynamic, dep); diff --git a/test/chunking-form/samples/dynamic-import-inline-colouring/_config.js b/test/chunking-form/samples/dynamic-import-inline-colouring/_config.js index 703fbca1c5c..b5769882caf 100644 --- a/test/chunking-form/samples/dynamic-import-inline-colouring/_config.js +++ b/test/chunking-form/samples/dynamic-import-inline-colouring/_config.js @@ -1,6 +1,6 @@ module.exports = { - description: 'Dynamic import inlining for static colouring', + description: 'Handle dynamic imports that are part of a static graph', options: { - input: ['main.js'] + input: ['main1.js', 'main2.js'] } }; diff --git a/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/amd/chunk-a2558f00.js b/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/amd/chunk-a2558f00.js new file mode 100644 index 00000000000..c06b72922c5 --- /dev/null +++ b/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/amd/chunk-a2558f00.js @@ -0,0 +1,9 @@ +define(['exports'], function (exports) { 'use strict'; + + var separate = 'separate'; + const x = 2; + + exports.default = separate; + exports.x = x; + +}); diff --git a/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/amd/chunk-d309b27d.js b/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/amd/chunk-d309b27d.js new file mode 100644 index 00000000000..eeab6552e64 --- /dev/null +++ b/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/amd/chunk-d309b27d.js @@ -0,0 +1,9 @@ +define(['exports'], function (exports) { 'use strict'; + + var inlined = 'inlined'; + const x = 1; + + exports.default = inlined; + exports.x = x; + +}); diff --git a/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/amd/main.js b/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/amd/main.js deleted file mode 100644 index ad52189480a..00000000000 --- a/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/amd/main.js +++ /dev/null @@ -1,13 +0,0 @@ -define(['require'], function (require) { 'use strict'; - - var foo = "FOO"; - - var foo$1 = /*#__PURE__*/Object.freeze({ - default: foo - }); - - var main = Promise.resolve().then(function () { return foo$1; }); - - return main; - -}); diff --git a/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/amd/main1.js b/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/amd/main1.js new file mode 100644 index 00000000000..4a6cf7a204a --- /dev/null +++ b/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/amd/main1.js @@ -0,0 +1,11 @@ +define(['require', 'exports', './chunk-d309b27d.js', './chunk-a2558f00.js'], function (require, exports, inlined_js, separate_js) { 'use strict'; + + const inlined = new Promise(function (resolve, reject) { require(['./chunk-d309b27d.js'], resolve, reject) }); + const separate = new Promise(function (resolve, reject) { require(['./chunk-a2558f00.js'], resolve, reject) }); + + exports.inlined = inlined; + exports.separate = separate; + + Object.defineProperty(exports, '__esModule', { value: true }); + +}); diff --git a/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/amd/main2.js b/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/amd/main2.js new file mode 100644 index 00000000000..efd0fdd1e70 --- /dev/null +++ b/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/amd/main2.js @@ -0,0 +1,9 @@ +define(['require', 'exports'], function (require, exports) { 'use strict'; + + const separate = new Promise(function (resolve, reject) { require(['./chunk-a2558f00.js'], resolve, reject) }); + + exports.separate = separate; + + Object.defineProperty(exports, '__esModule', { value: true }); + +}); diff --git a/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/cjs/chunk-bc97caee.js b/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/cjs/chunk-bc97caee.js new file mode 100644 index 00000000000..6eb315e5cac --- /dev/null +++ b/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/cjs/chunk-bc97caee.js @@ -0,0 +1,7 @@ +'use strict'; + +var separate = 'separate'; +const x = 2; + +exports.default = separate; +exports.x = x; diff --git a/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/cjs/chunk-e4f8b8db.js b/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/cjs/chunk-e4f8b8db.js new file mode 100644 index 00000000000..42f7789b8cf --- /dev/null +++ b/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/cjs/chunk-e4f8b8db.js @@ -0,0 +1,7 @@ +'use strict'; + +var inlined = 'inlined'; +const x = 1; + +exports.default = inlined; +exports.x = x; diff --git a/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/cjs/main.js b/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/cjs/main.js deleted file mode 100644 index 1a883d8e104..00000000000 --- a/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/cjs/main.js +++ /dev/null @@ -1,11 +0,0 @@ -'use strict'; - -var foo = "FOO"; - -var foo$1 = /*#__PURE__*/Object.freeze({ - default: foo -}); - -var main = Promise.resolve().then(function () { return foo$1; }); - -module.exports = main; diff --git a/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/cjs/main1.js b/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/cjs/main1.js new file mode 100644 index 00000000000..0ea38c8b561 --- /dev/null +++ b/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/cjs/main1.js @@ -0,0 +1,12 @@ +'use strict'; + +Object.defineProperty(exports, '__esModule', { value: true }); + +require('./chunk-e4f8b8db.js'); +require('./chunk-bc97caee.js'); + +const inlined = Promise.resolve(require('./chunk-e4f8b8db.js')); +const separate = Promise.resolve(require('./chunk-bc97caee.js')); + +exports.inlined = inlined; +exports.separate = separate; diff --git a/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/cjs/main2.js b/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/cjs/main2.js new file mode 100644 index 00000000000..602133f2047 --- /dev/null +++ b/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/cjs/main2.js @@ -0,0 +1,7 @@ +'use strict'; + +Object.defineProperty(exports, '__esModule', { value: true }); + +const separate = Promise.resolve(require('./chunk-bc97caee.js')); + +exports.separate = separate; diff --git a/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/es/chunk-61f7224d.js b/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/es/chunk-61f7224d.js new file mode 100644 index 00000000000..e7122e67004 --- /dev/null +++ b/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/es/chunk-61f7224d.js @@ -0,0 +1,5 @@ +var separate = 'separate'; +const x = 2; + +export default separate; +export { x }; diff --git a/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/es/chunk-6d572aec.js b/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/es/chunk-6d572aec.js new file mode 100644 index 00000000000..d13cbecbfa4 --- /dev/null +++ b/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/es/chunk-6d572aec.js @@ -0,0 +1,5 @@ +var inlined = 'inlined'; +const x = 1; + +export default inlined; +export { x }; diff --git a/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/es/main.js b/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/es/main.js deleted file mode 100644 index c2c2c98a3ca..00000000000 --- a/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/es/main.js +++ /dev/null @@ -1,9 +0,0 @@ -var foo = "FOO"; - -var foo$1 = /*#__PURE__*/Object.freeze({ - default: foo -}); - -var main = Promise.resolve().then(function () { return foo$1; }); - -export default main; diff --git a/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/es/main1.js b/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/es/main1.js new file mode 100644 index 00000000000..84ceaf1e669 --- /dev/null +++ b/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/es/main1.js @@ -0,0 +1,7 @@ +import './chunk-6d572aec.js'; +import './chunk-61f7224d.js'; + +const inlined = import('./chunk-6d572aec.js'); +const separate = import('./chunk-61f7224d.js'); + +export { inlined, separate }; diff --git a/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/es/main2.js b/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/es/main2.js new file mode 100644 index 00000000000..ef6e5c38ceb --- /dev/null +++ b/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/es/main2.js @@ -0,0 +1,3 @@ +const separate = import('./chunk-61f7224d.js'); + +export { separate }; diff --git a/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/system/chunk-9df34bdb.js b/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/system/chunk-9df34bdb.js new file mode 100644 index 00000000000..a6804f10504 --- /dev/null +++ b/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/system/chunk-9df34bdb.js @@ -0,0 +1,11 @@ +System.register([], function (exports, module) { + 'use strict'; + return { + execute: function () { + + var separate = exports('default', 'separate'); + const x = exports('x', 2); + + } + }; +}); diff --git a/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/system/chunk-cdaf79ed.js b/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/system/chunk-cdaf79ed.js new file mode 100644 index 00000000000..d0c94460fe2 --- /dev/null +++ b/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/system/chunk-cdaf79ed.js @@ -0,0 +1,11 @@ +System.register([], function (exports, module) { + 'use strict'; + return { + execute: function () { + + var inlined = exports('default', 'inlined'); + const x = exports('x', 1); + + } + }; +}); diff --git a/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/system/main.js b/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/system/main.js deleted file mode 100644 index fa520cb9470..00000000000 --- a/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/system/main.js +++ /dev/null @@ -1,16 +0,0 @@ -System.register([], function (exports, module) { - 'use strict'; - return { - execute: function () { - - var foo = "FOO"; - - var foo$1 = /*#__PURE__*/Object.freeze({ - default: foo - }); - - var main = exports('default', Promise.resolve().then(function () { return foo$1; })); - - } - }; -}); diff --git a/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/system/main1.js b/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/system/main1.js new file mode 100644 index 00000000000..0f36bf48128 --- /dev/null +++ b/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/system/main1.js @@ -0,0 +1,12 @@ +System.register(['./chunk-cdaf79ed.js', './chunk-9df34bdb.js'], function (exports, module) { + 'use strict'; + return { + setters: [function () {}, function () {}], + execute: function () { + + const inlined = exports('inlined', module.import('./chunk-cdaf79ed.js')); + const separate = exports('separate', module.import('./chunk-9df34bdb.js')); + + } + }; +}); diff --git a/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/system/main2.js b/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/system/main2.js new file mode 100644 index 00000000000..c0e58609b00 --- /dev/null +++ b/test/chunking-form/samples/dynamic-import-inline-colouring/_expected/system/main2.js @@ -0,0 +1,10 @@ +System.register([], function (exports, module) { + 'use strict'; + return { + execute: function () { + + const separate = exports('separate', module.import('./chunk-9df34bdb.js')); + + } + }; +}); diff --git a/test/chunking-form/samples/dynamic-import-inline-colouring/foo.js b/test/chunking-form/samples/dynamic-import-inline-colouring/foo.js deleted file mode 100644 index 5337929ccbc..00000000000 --- a/test/chunking-form/samples/dynamic-import-inline-colouring/foo.js +++ /dev/null @@ -1 +0,0 @@ -export default "FOO"; \ No newline at end of file diff --git a/test/chunking-form/samples/dynamic-import-inline-colouring/inlined.js b/test/chunking-form/samples/dynamic-import-inline-colouring/inlined.js new file mode 100644 index 00000000000..179d1f36e2d --- /dev/null +++ b/test/chunking-form/samples/dynamic-import-inline-colouring/inlined.js @@ -0,0 +1,2 @@ +export default 'inlined'; +export const x = 1; diff --git a/test/chunking-form/samples/dynamic-import-inline-colouring/main.js b/test/chunking-form/samples/dynamic-import-inline-colouring/main.js deleted file mode 100644 index 09ad58d8300..00000000000 --- a/test/chunking-form/samples/dynamic-import-inline-colouring/main.js +++ /dev/null @@ -1,3 +0,0 @@ -import foo from "./foo.js"; - -export default import("./foo.js"); \ No newline at end of file diff --git a/test/chunking-form/samples/dynamic-import-inline-colouring/main1.js b/test/chunking-form/samples/dynamic-import-inline-colouring/main1.js new file mode 100644 index 00000000000..0d4b2856ca3 --- /dev/null +++ b/test/chunking-form/samples/dynamic-import-inline-colouring/main1.js @@ -0,0 +1,5 @@ +import './inlined.js'; +import './separate.js'; + +export const inlined = import('./inlined.js'); +export const separate = import('./separate.js'); diff --git a/test/chunking-form/samples/dynamic-import-inline-colouring/main2.js b/test/chunking-form/samples/dynamic-import-inline-colouring/main2.js new file mode 100644 index 00000000000..81d5531d23c --- /dev/null +++ b/test/chunking-form/samples/dynamic-import-inline-colouring/main2.js @@ -0,0 +1 @@ +export const separate = import('./separate.js'); diff --git a/test/chunking-form/samples/dynamic-import-inline-colouring/separate.js b/test/chunking-form/samples/dynamic-import-inline-colouring/separate.js new file mode 100644 index 00000000000..8b13495bb7a --- /dev/null +++ b/test/chunking-form/samples/dynamic-import-inline-colouring/separate.js @@ -0,0 +1,2 @@ +export default 'separate'; +export const x = 2; diff --git a/test/chunking-form/samples/dynamic-import-tree-shaking-1/_config.js b/test/chunking-form/samples/dynamic-import-tree-shaking-1/_config.js new file mode 100644 index 00000000000..467c722b112 --- /dev/null +++ b/test/chunking-form/samples/dynamic-import-tree-shaking-1/_config.js @@ -0,0 +1,12 @@ +module.exports = { + description: 'uses tree-shaking information to improve chunking', + options: { + input: { + entryA: 'main1.js', + entryB: 'main2.js' + }, + output: { + chunkFileNames: 'generated-chunk.js' + } + } +}; diff --git a/test/chunking-form/samples/dynamic-import-tree-shaking-1/_expected/amd/entryA.js b/test/chunking-form/samples/dynamic-import-tree-shaking-1/_expected/amd/entryA.js new file mode 100644 index 00000000000..0f3a098cf76 --- /dev/null +++ b/test/chunking-form/samples/dynamic-import-tree-shaking-1/_expected/amd/entryA.js @@ -0,0 +1,9 @@ +define(function () { 'use strict'; + + console.log('dep'); + + var value = 1; + + console.log('main1', value); + +}); diff --git a/test/chunking-form/samples/dynamic-import-tree-shaking-1/_expected/amd/entryB.js b/test/chunking-form/samples/dynamic-import-tree-shaking-1/_expected/amd/entryB.js new file mode 100644 index 00000000000..b58286ca58e --- /dev/null +++ b/test/chunking-form/samples/dynamic-import-tree-shaking-1/_expected/amd/entryB.js @@ -0,0 +1,5 @@ +define(function () { 'use strict'; + + console.log('main2'); + +}); diff --git a/test/chunking-form/samples/dynamic-import-tree-shaking-1/_expected/cjs/entryA.js b/test/chunking-form/samples/dynamic-import-tree-shaking-1/_expected/cjs/entryA.js new file mode 100644 index 00000000000..cb112f038c4 --- /dev/null +++ b/test/chunking-form/samples/dynamic-import-tree-shaking-1/_expected/cjs/entryA.js @@ -0,0 +1,7 @@ +'use strict'; + +console.log('dep'); + +var value = 1; + +console.log('main1', value); diff --git a/test/chunking-form/samples/dynamic-import-tree-shaking-1/_expected/cjs/entryB.js b/test/chunking-form/samples/dynamic-import-tree-shaking-1/_expected/cjs/entryB.js new file mode 100644 index 00000000000..33fe6f320c2 --- /dev/null +++ b/test/chunking-form/samples/dynamic-import-tree-shaking-1/_expected/cjs/entryB.js @@ -0,0 +1,3 @@ +'use strict'; + +console.log('main2'); diff --git a/test/chunking-form/samples/dynamic-import-tree-shaking-1/_expected/es/entryA.js b/test/chunking-form/samples/dynamic-import-tree-shaking-1/_expected/es/entryA.js new file mode 100644 index 00000000000..a4fe2a7630b --- /dev/null +++ b/test/chunking-form/samples/dynamic-import-tree-shaking-1/_expected/es/entryA.js @@ -0,0 +1,5 @@ +console.log('dep'); + +var value = 1; + +console.log('main1', value); diff --git a/test/chunking-form/samples/dynamic-import-tree-shaking-1/_expected/es/entryB.js b/test/chunking-form/samples/dynamic-import-tree-shaking-1/_expected/es/entryB.js new file mode 100644 index 00000000000..ac653633351 --- /dev/null +++ b/test/chunking-form/samples/dynamic-import-tree-shaking-1/_expected/es/entryB.js @@ -0,0 +1 @@ +console.log('main2'); diff --git a/test/chunking-form/samples/dynamic-import-tree-shaking-1/_expected/system/entryA.js b/test/chunking-form/samples/dynamic-import-tree-shaking-1/_expected/system/entryA.js new file mode 100644 index 00000000000..08e561ffa22 --- /dev/null +++ b/test/chunking-form/samples/dynamic-import-tree-shaking-1/_expected/system/entryA.js @@ -0,0 +1,14 @@ +System.register([], function (exports, module) { + 'use strict'; + return { + execute: function () { + + console.log('dep'); + + var value = 1; + + console.log('main1', value); + + } + }; +}); diff --git a/test/chunking-form/samples/dynamic-import-treeshaking/_expected/system/chunk-4d8f4e43.js b/test/chunking-form/samples/dynamic-import-tree-shaking-1/_expected/system/entryB.js similarity index 75% rename from test/chunking-form/samples/dynamic-import-treeshaking/_expected/system/chunk-4d8f4e43.js rename to test/chunking-form/samples/dynamic-import-tree-shaking-1/_expected/system/entryB.js index 134a5203f20..80e8224ee07 100644 --- a/test/chunking-form/samples/dynamic-import-treeshaking/_expected/system/chunk-4d8f4e43.js +++ b/test/chunking-form/samples/dynamic-import-tree-shaking-1/_expected/system/entryB.js @@ -3,7 +3,7 @@ System.register([], function (exports, module) { return { execute: function () { - var multiplier = exports('a', 7); + console.log('main2'); } }; diff --git a/test/chunking-form/samples/dynamic-import-tree-shaking-1/dep.js b/test/chunking-form/samples/dynamic-import-tree-shaking-1/dep.js new file mode 100644 index 00000000000..6687babb629 --- /dev/null +++ b/test/chunking-form/samples/dynamic-import-tree-shaking-1/dep.js @@ -0,0 +1,3 @@ +console.log('dep'); + +export var value = 1; diff --git a/test/chunking-form/samples/dynamic-import-tree-shaking-1/dep2.js b/test/chunking-form/samples/dynamic-import-tree-shaking-1/dep2.js new file mode 100644 index 00000000000..8a3785fdfce --- /dev/null +++ b/test/chunking-form/samples/dynamic-import-tree-shaking-1/dep2.js @@ -0,0 +1,3 @@ +console.log('dep2'); + +export { value } from './dep'; diff --git a/test/chunking-form/samples/dynamic-import-tree-shaking-1/main1.js b/test/chunking-form/samples/dynamic-import-tree-shaking-1/main1.js new file mode 100644 index 00000000000..dae9519a864 --- /dev/null +++ b/test/chunking-form/samples/dynamic-import-tree-shaking-1/main1.js @@ -0,0 +1,3 @@ +import { value } from './dep'; + +console.log('main1', value); diff --git a/test/chunking-form/samples/dynamic-import-tree-shaking-1/main2.js b/test/chunking-form/samples/dynamic-import-tree-shaking-1/main2.js new file mode 100644 index 00000000000..b4d6090cce9 --- /dev/null +++ b/test/chunking-form/samples/dynamic-import-tree-shaking-1/main2.js @@ -0,0 +1,5 @@ +if (false) { + import('./dep2').then(({ value }) => console.log('main2', value)); +} + +console.log('main2'); diff --git a/test/chunking-form/samples/dynamic-import-tree-shaking-2/_config.js b/test/chunking-form/samples/dynamic-import-tree-shaking-2/_config.js new file mode 100644 index 00000000000..6d2783787e6 --- /dev/null +++ b/test/chunking-form/samples/dynamic-import-tree-shaking-2/_config.js @@ -0,0 +1,6 @@ +module.exports = { + description: 'does not expose exports of chunks which were used by tree-shaken dynamic imports', + options: { + input: ['main1.js', 'main2.js'] + } +}; diff --git a/test/chunking-form/samples/dynamic-import-tree-shaking-2/_expected/amd/main1.js b/test/chunking-form/samples/dynamic-import-tree-shaking-2/_expected/amd/main1.js new file mode 100644 index 00000000000..34f4f818070 --- /dev/null +++ b/test/chunking-form/samples/dynamic-import-tree-shaking-2/_expected/amd/main1.js @@ -0,0 +1,5 @@ +define(function () { 'use strict'; + + console.log('main1'); + +}); diff --git a/test/chunking-form/samples/dynamic-import-tree-shaking-2/_expected/amd/main2.js b/test/chunking-form/samples/dynamic-import-tree-shaking-2/_expected/amd/main2.js new file mode 100644 index 00000000000..25c0aadce80 --- /dev/null +++ b/test/chunking-form/samples/dynamic-import-tree-shaking-2/_expected/amd/main2.js @@ -0,0 +1,10 @@ +define(function () { 'use strict'; + + console.log('dep'); + const dep = 'dep'; + + console.log('dynamic', dep); + + console.log('main2', dep); + +}); diff --git a/test/chunking-form/samples/dynamic-import-tree-shaking-2/_expected/cjs/main1.js b/test/chunking-form/samples/dynamic-import-tree-shaking-2/_expected/cjs/main1.js new file mode 100644 index 00000000000..34e0c8c26cd --- /dev/null +++ b/test/chunking-form/samples/dynamic-import-tree-shaking-2/_expected/cjs/main1.js @@ -0,0 +1,3 @@ +'use strict'; + +console.log('main1'); diff --git a/test/chunking-form/samples/dynamic-import-tree-shaking-2/_expected/cjs/main2.js b/test/chunking-form/samples/dynamic-import-tree-shaking-2/_expected/cjs/main2.js new file mode 100644 index 00000000000..bdbac3ae29b --- /dev/null +++ b/test/chunking-form/samples/dynamic-import-tree-shaking-2/_expected/cjs/main2.js @@ -0,0 +1,8 @@ +'use strict'; + +console.log('dep'); +const dep = 'dep'; + +console.log('dynamic', dep); + +console.log('main2', dep); diff --git a/test/chunking-form/samples/dynamic-import-tree-shaking-2/_expected/es/main1.js b/test/chunking-form/samples/dynamic-import-tree-shaking-2/_expected/es/main1.js new file mode 100644 index 00000000000..fda34828717 --- /dev/null +++ b/test/chunking-form/samples/dynamic-import-tree-shaking-2/_expected/es/main1.js @@ -0,0 +1 @@ +console.log('main1'); diff --git a/test/chunking-form/samples/dynamic-import-tree-shaking-2/_expected/es/main2.js b/test/chunking-form/samples/dynamic-import-tree-shaking-2/_expected/es/main2.js new file mode 100644 index 00000000000..f65207f3ed1 --- /dev/null +++ b/test/chunking-form/samples/dynamic-import-tree-shaking-2/_expected/es/main2.js @@ -0,0 +1,6 @@ +console.log('dep'); +const dep = 'dep'; + +console.log('dynamic', dep); + +console.log('main2', dep); diff --git a/test/chunking-form/samples/dynamic-import-tree-shaking-2/_expected/system/main1.js b/test/chunking-form/samples/dynamic-import-tree-shaking-2/_expected/system/main1.js new file mode 100644 index 00000000000..d426b473433 --- /dev/null +++ b/test/chunking-form/samples/dynamic-import-tree-shaking-2/_expected/system/main1.js @@ -0,0 +1,10 @@ +System.register([], function (exports, module) { + 'use strict'; + return { + execute: function () { + + console.log('main1'); + + } + }; +}); diff --git a/test/chunking-form/samples/dynamic-import-tree-shaking-2/_expected/system/main2.js b/test/chunking-form/samples/dynamic-import-tree-shaking-2/_expected/system/main2.js new file mode 100644 index 00000000000..74d18f428b8 --- /dev/null +++ b/test/chunking-form/samples/dynamic-import-tree-shaking-2/_expected/system/main2.js @@ -0,0 +1,15 @@ +System.register([], function (exports, module) { + 'use strict'; + return { + execute: function () { + + console.log('dep'); + const dep = 'dep'; + + console.log('dynamic', dep); + + console.log('main2', dep); + + } + }; +}); diff --git a/test/chunking-form/samples/dynamic-import-tree-shaking-2/dep.js b/test/chunking-form/samples/dynamic-import-tree-shaking-2/dep.js new file mode 100644 index 00000000000..ba2dab33f2d --- /dev/null +++ b/test/chunking-form/samples/dynamic-import-tree-shaking-2/dep.js @@ -0,0 +1,2 @@ +console.log('dep'); +export const dep = 'dep'; diff --git a/test/chunking-form/samples/dynamic-import-tree-shaking-2/dynamic.js b/test/chunking-form/samples/dynamic-import-tree-shaking-2/dynamic.js new file mode 100644 index 00000000000..630fbf0a902 --- /dev/null +++ b/test/chunking-form/samples/dynamic-import-tree-shaking-2/dynamic.js @@ -0,0 +1,4 @@ +import { dep } from './dep'; + +console.log('dynamic', dep); +export const dynamic = 'dynamic'; diff --git a/test/chunking-form/samples/dynamic-import-tree-shaking-2/main1.js b/test/chunking-form/samples/dynamic-import-tree-shaking-2/main1.js new file mode 100644 index 00000000000..3911a49e217 --- /dev/null +++ b/test/chunking-form/samples/dynamic-import-tree-shaking-2/main1.js @@ -0,0 +1,4 @@ +if (false) { + import('./dynamic.js'); +} +console.log('main1'); diff --git a/test/chunking-form/samples/dynamic-import-tree-shaking-2/main2.js b/test/chunking-form/samples/dynamic-import-tree-shaking-2/main2.js new file mode 100644 index 00000000000..c54398cb4db --- /dev/null +++ b/test/chunking-form/samples/dynamic-import-tree-shaking-2/main2.js @@ -0,0 +1,4 @@ +import { dep } from './dep.js'; +import './dynamic.js'; + +console.log('main2', dep); diff --git a/test/chunking-form/samples/dynamic-import-treeshaking/_config.js b/test/chunking-form/samples/dynamic-import-treeshaking/_config.js deleted file mode 100644 index f74eb51af17..00000000000 --- a/test/chunking-form/samples/dynamic-import-treeshaking/_config.js +++ /dev/null @@ -1,6 +0,0 @@ -module.exports = { - description: 'Treeshaking with dynamic import', - options: { - input: ['main.js'] - } -}; diff --git a/test/chunking-form/samples/dynamic-import-treeshaking/_expected/amd/main.js b/test/chunking-form/samples/dynamic-import-treeshaking/_expected/amd/main.js deleted file mode 100644 index b492836791b..00000000000 --- a/test/chunking-form/samples/dynamic-import-treeshaking/_expected/amd/main.js +++ /dev/null @@ -1,13 +0,0 @@ -define(['require', './chunk-7b720877.js'], function (require, __chunk_1) { 'use strict'; - - function calc (num) { - return num * __chunk_1.multiplier; - } - - function fn (num) { - return num * calc(num); - } - - console.log(fn(5)); - -}); diff --git a/test/chunking-form/samples/dynamic-import-treeshaking/_expected/cjs/chunk-3a53aa58.js b/test/chunking-form/samples/dynamic-import-treeshaking/_expected/cjs/chunk-3a53aa58.js deleted file mode 100644 index 6c19ba5bed9..00000000000 --- a/test/chunking-form/samples/dynamic-import-treeshaking/_expected/cjs/chunk-3a53aa58.js +++ /dev/null @@ -1,5 +0,0 @@ -'use strict'; - -var multiplier = 7; - -exports.multiplier = multiplier; diff --git a/test/chunking-form/samples/dynamic-import-treeshaking/_expected/cjs/main.js b/test/chunking-form/samples/dynamic-import-treeshaking/_expected/cjs/main.js deleted file mode 100644 index c005f8502dd..00000000000 --- a/test/chunking-form/samples/dynamic-import-treeshaking/_expected/cjs/main.js +++ /dev/null @@ -1,13 +0,0 @@ -'use strict'; - -var __chunk_1 = require('./chunk-3a53aa58.js'); - -function calc (num) { - return num * __chunk_1.multiplier; -} - -function fn (num) { - return num * calc(num); -} - -console.log(fn(5)); diff --git a/test/chunking-form/samples/dynamic-import-treeshaking/_expected/es/chunk-713732d9.js b/test/chunking-form/samples/dynamic-import-treeshaking/_expected/es/chunk-713732d9.js deleted file mode 100644 index f112a633446..00000000000 --- a/test/chunking-form/samples/dynamic-import-treeshaking/_expected/es/chunk-713732d9.js +++ /dev/null @@ -1,3 +0,0 @@ -var multiplier = 7; - -export { multiplier as a }; diff --git a/test/chunking-form/samples/dynamic-import-treeshaking/_expected/es/dep2.js b/test/chunking-form/samples/dynamic-import-treeshaking/_expected/es/dep2.js deleted file mode 100644 index c0ed67ae72e..00000000000 --- a/test/chunking-form/samples/dynamic-import-treeshaking/_expected/es/dep2.js +++ /dev/null @@ -1,7 +0,0 @@ -import { a as multiplier } from './chunk-713732d9.js'; - -function mult (num) { - return num + multiplier; -} - -export { mult }; diff --git a/test/chunking-form/samples/dynamic-import-treeshaking/_expected/es/main.js b/test/chunking-form/samples/dynamic-import-treeshaking/_expected/es/main.js deleted file mode 100644 index c25970cb9bf..00000000000 --- a/test/chunking-form/samples/dynamic-import-treeshaking/_expected/es/main.js +++ /dev/null @@ -1,11 +0,0 @@ -import { a as multiplier } from './chunk-713732d9.js'; - -function calc (num) { - return num * multiplier; -} - -function fn (num) { - return num * calc(num); -} - -console.log(fn(5)); diff --git a/test/chunking-form/samples/dynamic-import-treeshaking/_expected/system/dep2.js b/test/chunking-form/samples/dynamic-import-treeshaking/_expected/system/dep2.js deleted file mode 100644 index 39e64c9d4e0..00000000000 --- a/test/chunking-form/samples/dynamic-import-treeshaking/_expected/system/dep2.js +++ /dev/null @@ -1,18 +0,0 @@ -System.register(['./chunk-4d8f4e43.js'], function (exports, module) { - 'use strict'; - var multiplier; - return { - setters: [function (module) { - multiplier = module.a; - }], - execute: function () { - - exports('mult', mult); - - function mult (num) { - return num + multiplier; - } - - } - }; -}); diff --git a/test/chunking-form/samples/dynamic-import-treeshaking/_expected/system/main.js b/test/chunking-form/samples/dynamic-import-treeshaking/_expected/system/main.js deleted file mode 100644 index 2d6a3c22efb..00000000000 --- a/test/chunking-form/samples/dynamic-import-treeshaking/_expected/system/main.js +++ /dev/null @@ -1,22 +0,0 @@ -System.register(['./chunk-4d8f4e43.js'], function (exports, module) { - 'use strict'; - var multiplier; - return { - setters: [function (module) { - multiplier = module.a; - }], - execute: function () { - - function calc (num) { - return num * multiplier; - } - - function fn (num) { - return num * calc(num); - } - - console.log(fn(5)); - - } - }; -}); diff --git a/test/chunking-form/samples/dynamic-import-treeshaking/dep1.js b/test/chunking-form/samples/dynamic-import-treeshaking/dep1.js deleted file mode 100644 index 8c2268595b7..00000000000 --- a/test/chunking-form/samples/dynamic-import-treeshaking/dep1.js +++ /dev/null @@ -1,12 +0,0 @@ -import { calc } from './dep3.js'; - -export function fn (num) { - return num * calc(num); -} - -export function dynamic (num) { - return import('./dep2.js') - .then(dep2 => { - return dep2.mult(num); - }); -} \ No newline at end of file diff --git a/test/chunking-form/samples/dynamic-import-treeshaking/dep2.js b/test/chunking-form/samples/dynamic-import-treeshaking/dep2.js deleted file mode 100644 index b9eaabe5d6d..00000000000 --- a/test/chunking-form/samples/dynamic-import-treeshaking/dep2.js +++ /dev/null @@ -1,5 +0,0 @@ -import { multiplier } from './dep4.js'; - -export function mult (num) { - return num + multiplier; -} \ No newline at end of file diff --git a/test/chunking-form/samples/dynamic-import-treeshaking/dep3.js b/test/chunking-form/samples/dynamic-import-treeshaking/dep3.js deleted file mode 100644 index 2e319b70744..00000000000 --- a/test/chunking-form/samples/dynamic-import-treeshaking/dep3.js +++ /dev/null @@ -1,5 +0,0 @@ -import { multiplier } from './dep4.js'; - -export function calc (num) { - return num * multiplier; -} \ No newline at end of file diff --git a/test/chunking-form/samples/dynamic-import-treeshaking/dep4.js b/test/chunking-form/samples/dynamic-import-treeshaking/dep4.js deleted file mode 100644 index 7468ccc2b3f..00000000000 --- a/test/chunking-form/samples/dynamic-import-treeshaking/dep4.js +++ /dev/null @@ -1 +0,0 @@ -export var multiplier = 7; \ No newline at end of file diff --git a/test/chunking-form/samples/dynamic-import-treeshaking/main.js b/test/chunking-form/samples/dynamic-import-treeshaking/main.js deleted file mode 100644 index baaa2998adf..00000000000 --- a/test/chunking-form/samples/dynamic-import-treeshaking/main.js +++ /dev/null @@ -1,3 +0,0 @@ -import { fn } from './dep1.js'; - -console.log(fn(5)); \ No newline at end of file diff --git a/test/chunking-form/samples/grouping-multiple/_config.js b/test/chunking-form/samples/grouping-multiple/_config.js index 8fba5c3a4e4..e3084e471c8 100644 --- a/test/chunking-form/samples/grouping-multiple/_config.js +++ b/test/chunking-form/samples/grouping-multiple/_config.js @@ -1,7 +1,7 @@ module.exports = { description: 'chunk grouping multiple chunks', options: { - optimizeChunks: true, + experimentalOptimizeChunks: true, chunkGroupingSize: 5000, input: ['main1.js', 'main2.js', 'main3.js'] } diff --git a/test/chunking-form/samples/grouping-size/_config.js b/test/chunking-form/samples/grouping-size/_config.js index 514d29cab28..3a662b0a187 100644 --- a/test/chunking-form/samples/grouping-size/_config.js +++ b/test/chunking-form/samples/grouping-size/_config.js @@ -1,7 +1,7 @@ module.exports = { description: 'chunk grouping size threshold', options: { - optimizeChunks: true, + experimentalOptimizeChunks: true, chunkGroupingSize: 42, input: ['main1.js', 'main2.js', 'main3.js'] } diff --git a/test/chunking-form/samples/manual-chunks-dynamic-facades/_config.js b/test/chunking-form/samples/manual-chunks-dynamic-facades/_config.js new file mode 100644 index 00000000000..3605f593949 --- /dev/null +++ b/test/chunking-form/samples/manual-chunks-dynamic-facades/_config.js @@ -0,0 +1,12 @@ +module.exports = { + description: 'creates facades for dynamic manual chunks if necessary', + options: { + input: ['main.js'], + manualChunks: { + dynamic: ['dynamic1.js'] + }, + output: { + chunkFileNames: 'generated-[name].js' + } + } +}; diff --git a/test/chunking-form/samples/manual-chunks-dynamic-facades/_expected/amd/generated-dynamic.js b/test/chunking-form/samples/manual-chunks-dynamic-facades/_expected/amd/generated-dynamic.js new file mode 100644 index 00000000000..467e384286b --- /dev/null +++ b/test/chunking-form/samples/manual-chunks-dynamic-facades/_expected/amd/generated-dynamic.js @@ -0,0 +1,16 @@ +define(['exports'], function (exports) { 'use strict'; + + const DEP = 'DEP'; + + const DYNAMIC_2 = 'DYNAMIC_2'; + + const DYNAMIC_3 = 'DYNAMIC_3'; + + const DYNAMIC_1 = 'DYNAMIC_1'; + + exports.DYNAMIC_1 = DYNAMIC_1; + exports.DEP = DEP; + exports.DYNAMIC_2 = DYNAMIC_2; + exports.DYNAMIC_3 = DYNAMIC_3; + +}); diff --git a/test/chunking-form/samples/manual-chunks-dynamic-facades/_expected/amd/generated-dynamic2.js b/test/chunking-form/samples/manual-chunks-dynamic-facades/_expected/amd/generated-dynamic2.js new file mode 100644 index 00000000000..d61d9fe71fc --- /dev/null +++ b/test/chunking-form/samples/manual-chunks-dynamic-facades/_expected/amd/generated-dynamic2.js @@ -0,0 +1,7 @@ +define(['exports', './generated-dynamic.js'], function (exports, dynamic) { 'use strict'; + + + + exports.DYNAMIC_2 = dynamic.DYNAMIC_2; + +}); diff --git a/test/chunking-form/samples/manual-chunks-dynamic-facades/_expected/amd/generated-dynamic3.js b/test/chunking-form/samples/manual-chunks-dynamic-facades/_expected/amd/generated-dynamic3.js new file mode 100644 index 00000000000..d8b85da29fc --- /dev/null +++ b/test/chunking-form/samples/manual-chunks-dynamic-facades/_expected/amd/generated-dynamic3.js @@ -0,0 +1,7 @@ +define(['exports', './generated-dynamic.js'], function (exports, dynamic) { 'use strict'; + + + + exports.DYNAMIC_3 = dynamic.DYNAMIC_3; + +}); diff --git a/test/chunking-form/samples/manual-chunks-dynamic-facades/_expected/amd/main.js b/test/chunking-form/samples/manual-chunks-dynamic-facades/_expected/amd/main.js new file mode 100644 index 00000000000..3c9d3dbf487 --- /dev/null +++ b/test/chunking-form/samples/manual-chunks-dynamic-facades/_expected/amd/main.js @@ -0,0 +1,7 @@ +define(['require', './generated-dynamic.js'], function (require, dynamic) { 'use strict'; + + Promise.all([new Promise(function (resolve, reject) { require(['./generated-dynamic.js'], resolve, reject) }), new Promise(function (resolve, reject) { require(['./generated-dynamic2.js'], resolve, reject) }), new Promise(function (resolve, reject) { require(['./generated-dynamic3.js'], resolve, reject) })]).then( + results => console.log(results, dynamic.DEP) + ); + +}); diff --git a/test/chunking-form/samples/manual-chunks-dynamic-facades/_expected/cjs/generated-dynamic.js b/test/chunking-form/samples/manual-chunks-dynamic-facades/_expected/cjs/generated-dynamic.js new file mode 100644 index 00000000000..fe62d18446f --- /dev/null +++ b/test/chunking-form/samples/manual-chunks-dynamic-facades/_expected/cjs/generated-dynamic.js @@ -0,0 +1,14 @@ +'use strict'; + +const DEP = 'DEP'; + +const DYNAMIC_2 = 'DYNAMIC_2'; + +const DYNAMIC_3 = 'DYNAMIC_3'; + +const DYNAMIC_1 = 'DYNAMIC_1'; + +exports.DYNAMIC_1 = DYNAMIC_1; +exports.DEP = DEP; +exports.DYNAMIC_2 = DYNAMIC_2; +exports.DYNAMIC_3 = DYNAMIC_3; diff --git a/test/chunking-form/samples/manual-chunks-dynamic-facades/_expected/cjs/generated-dynamic2.js b/test/chunking-form/samples/manual-chunks-dynamic-facades/_expected/cjs/generated-dynamic2.js new file mode 100644 index 00000000000..cf43f7fbe57 --- /dev/null +++ b/test/chunking-form/samples/manual-chunks-dynamic-facades/_expected/cjs/generated-dynamic2.js @@ -0,0 +1,7 @@ +'use strict'; + +var dynamic = require('./generated-dynamic.js'); + + + +exports.DYNAMIC_2 = dynamic.DYNAMIC_2; diff --git a/test/chunking-form/samples/manual-chunks-dynamic-facades/_expected/cjs/generated-dynamic3.js b/test/chunking-form/samples/manual-chunks-dynamic-facades/_expected/cjs/generated-dynamic3.js new file mode 100644 index 00000000000..4ed30dd39c3 --- /dev/null +++ b/test/chunking-form/samples/manual-chunks-dynamic-facades/_expected/cjs/generated-dynamic3.js @@ -0,0 +1,7 @@ +'use strict'; + +var dynamic = require('./generated-dynamic.js'); + + + +exports.DYNAMIC_3 = dynamic.DYNAMIC_3; diff --git a/test/chunking-form/samples/manual-chunks-dynamic-facades/_expected/cjs/main.js b/test/chunking-form/samples/manual-chunks-dynamic-facades/_expected/cjs/main.js new file mode 100644 index 00000000000..529ca20e209 --- /dev/null +++ b/test/chunking-form/samples/manual-chunks-dynamic-facades/_expected/cjs/main.js @@ -0,0 +1,7 @@ +'use strict'; + +var dynamic = require('./generated-dynamic.js'); + +Promise.all([Promise.resolve(require('./generated-dynamic.js')), Promise.resolve(require('./generated-dynamic2.js')), Promise.resolve(require('./generated-dynamic3.js'))]).then( + results => console.log(results, dynamic.DEP) +); diff --git a/test/chunking-form/samples/manual-chunks-dynamic-facades/_expected/es/generated-dynamic.js b/test/chunking-form/samples/manual-chunks-dynamic-facades/_expected/es/generated-dynamic.js new file mode 100644 index 00000000000..36b7ea16ba7 --- /dev/null +++ b/test/chunking-form/samples/manual-chunks-dynamic-facades/_expected/es/generated-dynamic.js @@ -0,0 +1,9 @@ +const DEP = 'DEP'; + +const DYNAMIC_2 = 'DYNAMIC_2'; + +const DYNAMIC_3 = 'DYNAMIC_3'; + +const DYNAMIC_1 = 'DYNAMIC_1'; + +export { DYNAMIC_1, DEP, DYNAMIC_2, DYNAMIC_3 }; diff --git a/test/chunking-form/samples/manual-chunks-dynamic-facades/_expected/es/generated-dynamic2.js b/test/chunking-form/samples/manual-chunks-dynamic-facades/_expected/es/generated-dynamic2.js new file mode 100644 index 00000000000..73f483cb3eb --- /dev/null +++ b/test/chunking-form/samples/manual-chunks-dynamic-facades/_expected/es/generated-dynamic2.js @@ -0,0 +1 @@ +export { DYNAMIC_2 } from './generated-dynamic.js'; diff --git a/test/chunking-form/samples/manual-chunks-dynamic-facades/_expected/es/generated-dynamic3.js b/test/chunking-form/samples/manual-chunks-dynamic-facades/_expected/es/generated-dynamic3.js new file mode 100644 index 00000000000..44dcc838b09 --- /dev/null +++ b/test/chunking-form/samples/manual-chunks-dynamic-facades/_expected/es/generated-dynamic3.js @@ -0,0 +1 @@ +export { DYNAMIC_3 } from './generated-dynamic.js'; diff --git a/test/chunking-form/samples/manual-chunks-dynamic-facades/_expected/es/main.js b/test/chunking-form/samples/manual-chunks-dynamic-facades/_expected/es/main.js new file mode 100644 index 00000000000..4ed1bade3c1 --- /dev/null +++ b/test/chunking-form/samples/manual-chunks-dynamic-facades/_expected/es/main.js @@ -0,0 +1,5 @@ +import { DEP } from './generated-dynamic.js'; + +Promise.all([import('./generated-dynamic.js'), import('./generated-dynamic2.js'), import('./generated-dynamic3.js')]).then( + results => console.log(results, DEP) +); diff --git a/test/chunking-form/samples/manual-chunks-dynamic-facades/_expected/system/generated-dynamic.js b/test/chunking-form/samples/manual-chunks-dynamic-facades/_expected/system/generated-dynamic.js new file mode 100644 index 00000000000..297f23add80 --- /dev/null +++ b/test/chunking-form/samples/manual-chunks-dynamic-facades/_expected/system/generated-dynamic.js @@ -0,0 +1,16 @@ +System.register([], function (exports, module) { + 'use strict'; + return { + execute: function () { + + const DEP = exports('DEP', 'DEP'); + + const DYNAMIC_2 = exports('DYNAMIC_2', 'DYNAMIC_2'); + + const DYNAMIC_3 = exports('DYNAMIC_3', 'DYNAMIC_3'); + + const DYNAMIC_1 = exports('DYNAMIC_1', 'DYNAMIC_1'); + + } + }; +}); diff --git a/test/chunking-form/samples/manual-chunks-dynamic-facades/_expected/system/generated-dynamic2.js b/test/chunking-form/samples/manual-chunks-dynamic-facades/_expected/system/generated-dynamic2.js new file mode 100644 index 00000000000..3ea6944246f --- /dev/null +++ b/test/chunking-form/samples/manual-chunks-dynamic-facades/_expected/system/generated-dynamic2.js @@ -0,0 +1,13 @@ +System.register(['./generated-dynamic.js'], function (exports, module) { + 'use strict'; + return { + setters: [function (module) { + exports('DYNAMIC_2', module.DYNAMIC_2); + }], + execute: function () { + + + + } + }; +}); diff --git a/test/chunking-form/samples/manual-chunks-dynamic-facades/_expected/system/generated-dynamic3.js b/test/chunking-form/samples/manual-chunks-dynamic-facades/_expected/system/generated-dynamic3.js new file mode 100644 index 00000000000..9cd1dbdf3ed --- /dev/null +++ b/test/chunking-form/samples/manual-chunks-dynamic-facades/_expected/system/generated-dynamic3.js @@ -0,0 +1,13 @@ +System.register(['./generated-dynamic.js'], function (exports, module) { + 'use strict'; + return { + setters: [function (module) { + exports('DYNAMIC_3', module.DYNAMIC_3); + }], + execute: function () { + + + + } + }; +}); diff --git a/test/chunking-form/samples/manual-chunks-dynamic-facades/_expected/system/main.js b/test/chunking-form/samples/manual-chunks-dynamic-facades/_expected/system/main.js new file mode 100644 index 00000000000..3b527719e90 --- /dev/null +++ b/test/chunking-form/samples/manual-chunks-dynamic-facades/_expected/system/main.js @@ -0,0 +1,16 @@ +System.register(['./generated-dynamic.js'], function (exports, module) { + 'use strict'; + var DEP; + return { + setters: [function (module) { + DEP = module.DEP; + }], + execute: function () { + + Promise.all([module.import('./generated-dynamic.js'), module.import('./generated-dynamic2.js'), module.import('./generated-dynamic3.js')]).then( + results => console.log(results, DEP) + ); + + } + }; +}); diff --git a/test/chunking-form/samples/manual-chunks-dynamic-facades/dep.js b/test/chunking-form/samples/manual-chunks-dynamic-facades/dep.js new file mode 100644 index 00000000000..4be514fd761 --- /dev/null +++ b/test/chunking-form/samples/manual-chunks-dynamic-facades/dep.js @@ -0,0 +1 @@ +export const DEP = 'DEP'; diff --git a/test/chunking-form/samples/manual-chunks-dynamic-facades/dynamic1.js b/test/chunking-form/samples/manual-chunks-dynamic-facades/dynamic1.js new file mode 100644 index 00000000000..1591826eaf0 --- /dev/null +++ b/test/chunking-form/samples/manual-chunks-dynamic-facades/dynamic1.js @@ -0,0 +1,4 @@ +export * from './dep.js'; +export * from './dynamic2.js'; +export * from './dynamic3.js'; +export const DYNAMIC_1 = 'DYNAMIC_1'; diff --git a/test/chunking-form/samples/manual-chunks-dynamic-facades/dynamic2.js b/test/chunking-form/samples/manual-chunks-dynamic-facades/dynamic2.js new file mode 100644 index 00000000000..11eeeb42896 --- /dev/null +++ b/test/chunking-form/samples/manual-chunks-dynamic-facades/dynamic2.js @@ -0,0 +1 @@ +export const DYNAMIC_2 = 'DYNAMIC_2'; diff --git a/test/chunking-form/samples/manual-chunks-dynamic-facades/dynamic3.js b/test/chunking-form/samples/manual-chunks-dynamic-facades/dynamic3.js new file mode 100644 index 00000000000..439fa36aab0 --- /dev/null +++ b/test/chunking-form/samples/manual-chunks-dynamic-facades/dynamic3.js @@ -0,0 +1 @@ +export const DYNAMIC_3 = 'DYNAMIC_3'; diff --git a/test/chunking-form/samples/manual-chunks-dynamic-facades/main.js b/test/chunking-form/samples/manual-chunks-dynamic-facades/main.js new file mode 100644 index 00000000000..317e03b17c5 --- /dev/null +++ b/test/chunking-form/samples/manual-chunks-dynamic-facades/main.js @@ -0,0 +1,5 @@ +import { DEP } from './dep'; + +Promise.all([import('./dynamic1.js'), import('./dynamic2.js'), import('./dynamic3.js')]).then( + results => console.log(results, DEP) +); diff --git a/test/chunking-form/samples/manual-chunks-dynamic-name-conflict/_config.js b/test/chunking-form/samples/manual-chunks-dynamic-name-conflict/_config.js new file mode 100644 index 00000000000..860658f4950 --- /dev/null +++ b/test/chunking-form/samples/manual-chunks-dynamic-name-conflict/_config.js @@ -0,0 +1,12 @@ +module.exports = { + description: 'handles name conflicts in manual chunks', + options: { + input: ['main.js'], + manualChunks: { + dynamic: ['dynamic1.js'] + }, + output: { + chunkFileNames: 'generated-[name].js' + } + } +}; diff --git a/test/chunking-form/samples/manual-chunks-dynamic-name-conflict/_expected/amd/generated-dynamic.js b/test/chunking-form/samples/manual-chunks-dynamic-name-conflict/_expected/amd/generated-dynamic.js new file mode 100644 index 00000000000..1c1ce78581c --- /dev/null +++ b/test/chunking-form/samples/manual-chunks-dynamic-name-conflict/_expected/amd/generated-dynamic.js @@ -0,0 +1,13 @@ +define(['exports'], function (exports) { 'use strict'; + + console.log('dynamic2'); + + const DYNAMIC_A = 'DYNAMIC_A'; + const DYNAMIC_B = 'DYNAMIC_B'; + + console.log('dynamic1'); + + exports.DYNAMIC_A = DYNAMIC_A; + exports.DYNAMIC_B = DYNAMIC_B; + +}); diff --git a/test/chunking-form/samples/manual-chunks-dynamic-name-conflict/_expected/amd/generated-dynamic2.js b/test/chunking-form/samples/manual-chunks-dynamic-name-conflict/_expected/amd/generated-dynamic2.js new file mode 100644 index 00000000000..3fc5bfad3d6 --- /dev/null +++ b/test/chunking-form/samples/manual-chunks-dynamic-name-conflict/_expected/amd/generated-dynamic2.js @@ -0,0 +1,8 @@ +define(['exports', './generated-dynamic.js'], function (exports, dynamic) { 'use strict'; + + + + exports.DYNAMIC_B = dynamic.DYNAMIC_A; + exports.DYNAMIC_A = dynamic.DYNAMIC_B; + +}); diff --git a/test/chunking-form/samples/manual-chunks-dynamic-name-conflict/_expected/amd/main.js b/test/chunking-form/samples/manual-chunks-dynamic-name-conflict/_expected/amd/main.js new file mode 100644 index 00000000000..0e20039a5ed --- /dev/null +++ b/test/chunking-form/samples/manual-chunks-dynamic-name-conflict/_expected/amd/main.js @@ -0,0 +1,6 @@ +define(['require'], function (require) { 'use strict'; + + new Promise(function (resolve, reject) { require(['./generated-dynamic2.js'], resolve, reject) }).then(result => console.log(result)); + new Promise(function (resolve, reject) { require(['./generated-dynamic.js'], resolve, reject) }).then(result => console.log(result)); + +}); diff --git a/test/chunking-form/samples/manual-chunks-dynamic-name-conflict/_expected/cjs/generated-dynamic.js b/test/chunking-form/samples/manual-chunks-dynamic-name-conflict/_expected/cjs/generated-dynamic.js new file mode 100644 index 00000000000..19dd5e249f1 --- /dev/null +++ b/test/chunking-form/samples/manual-chunks-dynamic-name-conflict/_expected/cjs/generated-dynamic.js @@ -0,0 +1,11 @@ +'use strict'; + +console.log('dynamic2'); + +const DYNAMIC_A = 'DYNAMIC_A'; +const DYNAMIC_B = 'DYNAMIC_B'; + +console.log('dynamic1'); + +exports.DYNAMIC_A = DYNAMIC_A; +exports.DYNAMIC_B = DYNAMIC_B; diff --git a/test/chunking-form/samples/manual-chunks-dynamic-name-conflict/_expected/cjs/generated-dynamic2.js b/test/chunking-form/samples/manual-chunks-dynamic-name-conflict/_expected/cjs/generated-dynamic2.js new file mode 100644 index 00000000000..e053e77b359 --- /dev/null +++ b/test/chunking-form/samples/manual-chunks-dynamic-name-conflict/_expected/cjs/generated-dynamic2.js @@ -0,0 +1,8 @@ +'use strict'; + +var dynamic = require('./generated-dynamic.js'); + + + +exports.DYNAMIC_B = dynamic.DYNAMIC_A; +exports.DYNAMIC_A = dynamic.DYNAMIC_B; diff --git a/test/chunking-form/samples/manual-chunks-dynamic-name-conflict/_expected/cjs/main.js b/test/chunking-form/samples/manual-chunks-dynamic-name-conflict/_expected/cjs/main.js new file mode 100644 index 00000000000..0a28239769b --- /dev/null +++ b/test/chunking-form/samples/manual-chunks-dynamic-name-conflict/_expected/cjs/main.js @@ -0,0 +1,4 @@ +'use strict'; + +Promise.resolve(require('./generated-dynamic2.js')).then(result => console.log(result)); +Promise.resolve(require('./generated-dynamic.js')).then(result => console.log(result)); diff --git a/test/chunking-form/samples/manual-chunks-dynamic-name-conflict/_expected/es/generated-dynamic.js b/test/chunking-form/samples/manual-chunks-dynamic-name-conflict/_expected/es/generated-dynamic.js new file mode 100644 index 00000000000..a819dae41d1 --- /dev/null +++ b/test/chunking-form/samples/manual-chunks-dynamic-name-conflict/_expected/es/generated-dynamic.js @@ -0,0 +1,8 @@ +console.log('dynamic2'); + +const DYNAMIC_A = 'DYNAMIC_A'; +const DYNAMIC_B = 'DYNAMIC_B'; + +console.log('dynamic1'); + +export { DYNAMIC_A, DYNAMIC_B }; diff --git a/test/chunking-form/samples/manual-chunks-dynamic-name-conflict/_expected/es/generated-dynamic2.js b/test/chunking-form/samples/manual-chunks-dynamic-name-conflict/_expected/es/generated-dynamic2.js new file mode 100644 index 00000000000..c994f0671ad --- /dev/null +++ b/test/chunking-form/samples/manual-chunks-dynamic-name-conflict/_expected/es/generated-dynamic2.js @@ -0,0 +1 @@ +export { DYNAMIC_A as DYNAMIC_B, DYNAMIC_B as DYNAMIC_A } from './generated-dynamic.js'; diff --git a/test/chunking-form/samples/manual-chunks-dynamic-name-conflict/_expected/es/main.js b/test/chunking-form/samples/manual-chunks-dynamic-name-conflict/_expected/es/main.js new file mode 100644 index 00000000000..d191126a7d3 --- /dev/null +++ b/test/chunking-form/samples/manual-chunks-dynamic-name-conflict/_expected/es/main.js @@ -0,0 +1,2 @@ +import('./generated-dynamic2.js').then(result => console.log(result)); +import('./generated-dynamic.js').then(result => console.log(result)); diff --git a/test/chunking-form/samples/manual-chunks-dynamic-name-conflict/_expected/system/generated-dynamic.js b/test/chunking-form/samples/manual-chunks-dynamic-name-conflict/_expected/system/generated-dynamic.js new file mode 100644 index 00000000000..213666c17ca --- /dev/null +++ b/test/chunking-form/samples/manual-chunks-dynamic-name-conflict/_expected/system/generated-dynamic.js @@ -0,0 +1,15 @@ +System.register([], function (exports, module) { + 'use strict'; + return { + execute: function () { + + console.log('dynamic2'); + + const DYNAMIC_A = exports('DYNAMIC_A', 'DYNAMIC_A'); + const DYNAMIC_B = exports('DYNAMIC_B', 'DYNAMIC_B'); + + console.log('dynamic1'); + + } + }; +}); diff --git a/test/chunking-form/samples/manual-chunks-dynamic-name-conflict/_expected/system/generated-dynamic2.js b/test/chunking-form/samples/manual-chunks-dynamic-name-conflict/_expected/system/generated-dynamic2.js new file mode 100644 index 00000000000..27e6e17fb12 --- /dev/null +++ b/test/chunking-form/samples/manual-chunks-dynamic-name-conflict/_expected/system/generated-dynamic2.js @@ -0,0 +1,16 @@ +System.register(['./generated-dynamic.js'], function (exports, module) { + 'use strict'; + return { + setters: [function (module) { + var _setter = {}; + _setter.DYNAMIC_B = module.DYNAMIC_A; + _setter.DYNAMIC_A = module.DYNAMIC_B; + exports(_setter); + }], + execute: function () { + + + + } + }; +}); diff --git a/test/chunking-form/samples/manual-chunks-dynamic-name-conflict/_expected/system/main.js b/test/chunking-form/samples/manual-chunks-dynamic-name-conflict/_expected/system/main.js new file mode 100644 index 00000000000..fa189fe4b60 --- /dev/null +++ b/test/chunking-form/samples/manual-chunks-dynamic-name-conflict/_expected/system/main.js @@ -0,0 +1,11 @@ +System.register([], function (exports, module) { + 'use strict'; + return { + execute: function () { + + module.import('./generated-dynamic2.js').then(result => console.log(result)); + module.import('./generated-dynamic.js').then(result => console.log(result)); + + } + }; +}); diff --git a/test/chunking-form/samples/manual-chunks-dynamic-name-conflict/dynamic1.js b/test/chunking-form/samples/manual-chunks-dynamic-name-conflict/dynamic1.js new file mode 100644 index 00000000000..ee02308ddb4 --- /dev/null +++ b/test/chunking-form/samples/manual-chunks-dynamic-name-conflict/dynamic1.js @@ -0,0 +1,3 @@ +console.log('dynamic1'); + +export { DYNAMIC_A as DYNAMIC_B, DYNAMIC_B as DYNAMIC_A } from './dynamic2'; diff --git a/test/chunking-form/samples/manual-chunks-dynamic-name-conflict/dynamic2.js b/test/chunking-form/samples/manual-chunks-dynamic-name-conflict/dynamic2.js new file mode 100644 index 00000000000..6d087c59d00 --- /dev/null +++ b/test/chunking-form/samples/manual-chunks-dynamic-name-conflict/dynamic2.js @@ -0,0 +1,4 @@ +console.log('dynamic2'); + +export const DYNAMIC_A = 'DYNAMIC_A'; +export const DYNAMIC_B = 'DYNAMIC_B'; diff --git a/test/chunking-form/samples/manual-chunks-dynamic-name-conflict/main.js b/test/chunking-form/samples/manual-chunks-dynamic-name-conflict/main.js new file mode 100644 index 00000000000..9e2abfea069 --- /dev/null +++ b/test/chunking-form/samples/manual-chunks-dynamic-name-conflict/main.js @@ -0,0 +1,2 @@ +import('./dynamic1.js').then(result => console.log(result)); +import('./dynamic2.js').then(result => console.log(result)); diff --git a/test/chunking-form/samples/manual-chunks-dynamic/_config.js b/test/chunking-form/samples/manual-chunks-dynamic/_config.js index 6a02c734e3f..1a50241e392 100644 --- a/test/chunking-form/samples/manual-chunks-dynamic/_config.js +++ b/test/chunking-form/samples/manual-chunks-dynamic/_config.js @@ -1,10 +1,12 @@ module.exports = { - description: 'manual chunks to an empty dynamic chunk', - _single: true, + description: 'supports dynamic manual chunks', options: { input: ['main.js'], manualChunks: { dynamic: ['dynamic.js'] + }, + output: { + chunkFileNames: 'generated-[name].js' } } }; diff --git a/test/chunking-form/samples/manual-chunks-dynamic/_expected/amd/generated-dynamic.js b/test/chunking-form/samples/manual-chunks-dynamic/_expected/amd/generated-dynamic.js new file mode 100644 index 00000000000..94b0e40c8e0 --- /dev/null +++ b/test/chunking-form/samples/manual-chunks-dynamic/_expected/amd/generated-dynamic.js @@ -0,0 +1,7 @@ +define(['exports'], function (exports) { 'use strict'; + + const DYNAMIC_USED_BY_A = 'DYNAMIC_USED_BY_A'; + + exports.DYNAMIC_USED_BY_A = DYNAMIC_USED_BY_A; + +}); diff --git a/test/chunking-form/samples/manual-chunks-dynamic/_expected/amd/main.js b/test/chunking-form/samples/manual-chunks-dynamic/_expected/amd/main.js index 4ebb7e1db8e..bf87287061c 100644 --- a/test/chunking-form/samples/manual-chunks-dynamic/_expected/amd/main.js +++ b/test/chunking-form/samples/manual-chunks-dynamic/_expected/amd/main.js @@ -1,5 +1,5 @@ define(['require'], function (require) { 'use strict'; - new Promise(function (resolve, reject) { require(["./dynamic-10698fc3.js"], resolve, reject) }); + new Promise(function (resolve, reject) { require(['./generated-dynamic.js'], resolve, reject) }).then(({DYNAMIC_USED_BY_A}) => console.log(DYNAMIC_USED_BY_A)); }); diff --git a/test/chunking-form/samples/manual-chunks-dynamic/_expected/cjs/dynamic-5ab72169.js b/test/chunking-form/samples/manual-chunks-dynamic/_expected/cjs/dynamic-5ab72169.js deleted file mode 100644 index eb109abbed0..00000000000 --- a/test/chunking-form/samples/manual-chunks-dynamic/_expected/cjs/dynamic-5ab72169.js +++ /dev/null @@ -1,2 +0,0 @@ -'use strict'; - diff --git a/test/chunking-form/samples/manual-chunks-dynamic/_expected/cjs/generated-dynamic.js b/test/chunking-form/samples/manual-chunks-dynamic/_expected/cjs/generated-dynamic.js new file mode 100644 index 00000000000..28e15f91379 --- /dev/null +++ b/test/chunking-form/samples/manual-chunks-dynamic/_expected/cjs/generated-dynamic.js @@ -0,0 +1,5 @@ +'use strict'; + +const DYNAMIC_USED_BY_A = 'DYNAMIC_USED_BY_A'; + +exports.DYNAMIC_USED_BY_A = DYNAMIC_USED_BY_A; diff --git a/test/chunking-form/samples/manual-chunks-dynamic/_expected/cjs/main.js b/test/chunking-form/samples/manual-chunks-dynamic/_expected/cjs/main.js index f3310639beb..6dec24c5ece 100644 --- a/test/chunking-form/samples/manual-chunks-dynamic/_expected/cjs/main.js +++ b/test/chunking-form/samples/manual-chunks-dynamic/_expected/cjs/main.js @@ -1,3 +1,3 @@ 'use strict'; -Promise.resolve(require("./dynamic-5ab72169.js")); +Promise.resolve(require('./generated-dynamic.js')).then(({DYNAMIC_USED_BY_A}) => console.log(DYNAMIC_USED_BY_A)); diff --git a/test/chunking-form/samples/manual-chunks-dynamic/_expected/es/dynamic-12dc935a.js b/test/chunking-form/samples/manual-chunks-dynamic/_expected/es/dynamic-12dc935a.js deleted file mode 100644 index 8b137891791..00000000000 --- a/test/chunking-form/samples/manual-chunks-dynamic/_expected/es/dynamic-12dc935a.js +++ /dev/null @@ -1 +0,0 @@ - diff --git a/test/chunking-form/samples/manual-chunks-dynamic/_expected/es/generated-dynamic.js b/test/chunking-form/samples/manual-chunks-dynamic/_expected/es/generated-dynamic.js new file mode 100644 index 00000000000..4ccf6321419 --- /dev/null +++ b/test/chunking-form/samples/manual-chunks-dynamic/_expected/es/generated-dynamic.js @@ -0,0 +1,3 @@ +const DYNAMIC_USED_BY_A = 'DYNAMIC_USED_BY_A'; + +export { DYNAMIC_USED_BY_A }; diff --git a/test/chunking-form/samples/manual-chunks-dynamic/_expected/es/main.js b/test/chunking-form/samples/manual-chunks-dynamic/_expected/es/main.js index 0e83b245b59..aefad148dc7 100644 --- a/test/chunking-form/samples/manual-chunks-dynamic/_expected/es/main.js +++ b/test/chunking-form/samples/manual-chunks-dynamic/_expected/es/main.js @@ -1 +1 @@ -import("./dynamic-12dc935a.js"); +import('./generated-dynamic.js').then(({DYNAMIC_USED_BY_A}) => console.log(DYNAMIC_USED_BY_A)); diff --git a/test/chunking-form/samples/manual-chunks-dynamic/_expected/system/generated-dynamic.js b/test/chunking-form/samples/manual-chunks-dynamic/_expected/system/generated-dynamic.js new file mode 100644 index 00000000000..babdf3ed714 --- /dev/null +++ b/test/chunking-form/samples/manual-chunks-dynamic/_expected/system/generated-dynamic.js @@ -0,0 +1,10 @@ +System.register([], function (exports, module) { + 'use strict'; + return { + execute: function () { + + const DYNAMIC_USED_BY_A = exports('DYNAMIC_USED_BY_A', 'DYNAMIC_USED_BY_A'); + + } + }; +}); diff --git a/test/chunking-form/samples/manual-chunks-dynamic/_expected/system/main.js b/test/chunking-form/samples/manual-chunks-dynamic/_expected/system/main.js index 48d04548cf8..5c1d9db7c1e 100644 --- a/test/chunking-form/samples/manual-chunks-dynamic/_expected/system/main.js +++ b/test/chunking-form/samples/manual-chunks-dynamic/_expected/system/main.js @@ -3,7 +3,7 @@ System.register([], function (exports, module) { return { execute: function () { - module.import("./dynamic-e8bd5876.js"); + module.import('./generated-dynamic.js').then(({DYNAMIC_USED_BY_A}) => console.log(DYNAMIC_USED_BY_A)); } }; diff --git a/test/chunking-form/samples/manual-chunks-dynamic/main.js b/test/chunking-form/samples/manual-chunks-dynamic/main.js index a3d5cb1d641..c4c5988813a 100644 --- a/test/chunking-form/samples/manual-chunks-dynamic/main.js +++ b/test/chunking-form/samples/manual-chunks-dynamic/main.js @@ -1 +1 @@ -import('./dynamic.js'); \ No newline at end of file +import('./dynamic.js').then(({DYNAMIC_USED_BY_A}) => console.log(DYNAMIC_USED_BY_A)); diff --git a/test/chunking-form/samples/manual-chunks/_expected/amd/deps2and3-0c5d98d0.js b/test/chunking-form/samples/manual-chunks/_expected/amd/deps2and3-609a33db.js similarity index 86% rename from test/chunking-form/samples/manual-chunks/_expected/amd/deps2and3-0c5d98d0.js rename to test/chunking-form/samples/manual-chunks/_expected/amd/deps2and3-609a33db.js index b1034290429..a0f7deb92e5 100644 --- a/test/chunking-form/samples/manual-chunks/_expected/amd/deps2and3-0c5d98d0.js +++ b/test/chunking-form/samples/manual-chunks/_expected/amd/deps2and3-609a33db.js @@ -1,4 +1,4 @@ -define(['exports', './lib1-4c530ea2.js'], function (exports, __chunk_1) { 'use strict'; +define(['exports', './lib1-4c530ea2.js'], function (exports, __chunk_2) { 'use strict'; function fn () { console.log('lib2 fn'); @@ -10,7 +10,7 @@ define(['exports', './lib1-4c530ea2.js'], function (exports, __chunk_1) { 'use s } function fn$2 () { - __chunk_1.fn(); + __chunk_2.fn(); console.log('dep3 fn'); } diff --git a/test/chunking-form/samples/manual-chunks/_expected/amd/main.js b/test/chunking-form/samples/manual-chunks/_expected/amd/main.js index 8fc40e0fd45..4a0362d0325 100644 --- a/test/chunking-form/samples/manual-chunks/_expected/amd/main.js +++ b/test/chunking-form/samples/manual-chunks/_expected/amd/main.js @@ -1,4 +1,4 @@ -define(['./deps2and3-0c5d98d0.js', './lib1-4c530ea2.js'], function (__chunk_2, __chunk_1) { 'use strict'; +define(['./deps2and3-609a33db.js', './lib1-4c530ea2.js'], function (__chunk_1, __chunk_2) { 'use strict'; function fn () { console.log('dep1 fn'); @@ -7,8 +7,8 @@ define(['./deps2and3-0c5d98d0.js', './lib1-4c530ea2.js'], function (__chunk_2, _ class Main { constructor () { fn(); - __chunk_2.fn(); - __chunk_2.fn$1(); + __chunk_1.fn(); + __chunk_1.fn$1(); } } diff --git a/test/chunking-form/samples/manual-chunks/_expected/cjs/deps2and3-9aeb2d5b.js b/test/chunking-form/samples/manual-chunks/_expected/cjs/deps2and3-c8fe246d.js similarity index 76% rename from test/chunking-form/samples/manual-chunks/_expected/cjs/deps2and3-9aeb2d5b.js rename to test/chunking-form/samples/manual-chunks/_expected/cjs/deps2and3-c8fe246d.js index 4cac9e0c18f..48858923108 100644 --- a/test/chunking-form/samples/manual-chunks/_expected/cjs/deps2and3-9aeb2d5b.js +++ b/test/chunking-form/samples/manual-chunks/_expected/cjs/deps2and3-c8fe246d.js @@ -1,6 +1,6 @@ 'use strict'; -var __chunk_1 = require('./lib1-569e10cd.js'); +var __chunk_2 = require('./lib1-569e10cd.js'); function fn () { console.log('lib2 fn'); @@ -12,7 +12,7 @@ function fn$1 () { } function fn$2 () { - __chunk_1.fn(); + __chunk_2.fn(); console.log('dep3 fn'); } diff --git a/test/chunking-form/samples/manual-chunks/_expected/cjs/main.js b/test/chunking-form/samples/manual-chunks/_expected/cjs/main.js index a0e922407f9..da0bec22859 100644 --- a/test/chunking-form/samples/manual-chunks/_expected/cjs/main.js +++ b/test/chunking-form/samples/manual-chunks/_expected/cjs/main.js @@ -1,6 +1,6 @@ 'use strict'; -var __chunk_2 = require('./deps2and3-9aeb2d5b.js'); +var __chunk_1 = require('./deps2and3-c8fe246d.js'); require('./lib1-569e10cd.js'); function fn () { @@ -10,8 +10,8 @@ function fn () { class Main { constructor () { fn(); - __chunk_2.fn(); - __chunk_2.fn$1(); + __chunk_1.fn(); + __chunk_1.fn$1(); } } diff --git a/test/chunking-form/samples/namespace-reexports/_expected/es/index-6a71658c.js b/test/chunking-form/samples/namespace-reexports/_expected/es/index-6a71658c.js index 625de5eb307..3ac4915370c 100644 --- a/test/chunking-form/samples/namespace-reexports/_expected/es/index-6a71658c.js +++ b/test/chunking-form/samples/namespace-reexports/_expected/es/index-6a71658c.js @@ -1,4 +1,5 @@ import hsl2hsv from './hsl2hsv.js'; +export { default as b } from './hsl2hsv.js'; var hsl2hsv$1 = 'asdf'; @@ -8,4 +9,4 @@ var lib = /*#__PURE__*/Object.freeze({ hsl2hsv: hsl2hsv }); -export { hsl2hsv as a, lib as b }; +export { lib as a }; diff --git a/test/chunking-form/samples/namespace-reexports/_expected/es/index.js b/test/chunking-form/samples/namespace-reexports/_expected/es/index.js index 8956d87096a..9b940aa30ca 100644 --- a/test/chunking-form/samples/namespace-reexports/_expected/es/index.js +++ b/test/chunking-form/samples/namespace-reexports/_expected/es/index.js @@ -1,2 +1,2 @@ -export { a as hsl2hsv } from './index-6a71658c.js'; +export { b as hsl2hsv } from './index-6a71658c.js'; import './hsl2hsv.js'; diff --git a/test/chunking-form/samples/namespace-reexports/_expected/es/main.js b/test/chunking-form/samples/namespace-reexports/_expected/es/main.js index a4e5507ec23..82c8974ca04 100644 --- a/test/chunking-form/samples/namespace-reexports/_expected/es/main.js +++ b/test/chunking-form/samples/namespace-reexports/_expected/es/main.js @@ -1,5 +1,5 @@ -import { p } from './hsl2hsv.js'; -import { a as hsl2hsv, b as lib } from './index-6a71658c.js'; +import hsl2hsv, { p } from './hsl2hsv.js'; +import { a as lib } from './index-6a71658c.js'; console.log(p); var main = new Map(Object.entries(lib)); diff --git a/test/chunking-form/samples/namespace-reexports/_expected/system/index-8b381a8d.js b/test/chunking-form/samples/namespace-reexports/_expected/system/index-51f0f10d.js similarity index 85% rename from test/chunking-form/samples/namespace-reexports/_expected/system/index-8b381a8d.js rename to test/chunking-form/samples/namespace-reexports/_expected/system/index-51f0f10d.js index c61c6d81d0f..d0a0491b975 100644 --- a/test/chunking-form/samples/namespace-reexports/_expected/system/index-8b381a8d.js +++ b/test/chunking-form/samples/namespace-reexports/_expected/system/index-51f0f10d.js @@ -4,6 +4,7 @@ System.register(['./hsl2hsv.js'], function (exports, module) { return { setters: [function (module) { hsl2hsv = module.default; + exports('b', module.default); }], execute: function () { @@ -14,7 +15,7 @@ System.register(['./hsl2hsv.js'], function (exports, module) { var lib = /*#__PURE__*/Object.freeze({ hsl2hsv: hsl2hsv }); - exports('b', lib); + exports('a', lib); } }; diff --git a/test/chunking-form/samples/namespace-reexports/_expected/system/index.js b/test/chunking-form/samples/namespace-reexports/_expected/system/index.js index 6e1ba58f88e..0a81f1b3234 100644 --- a/test/chunking-form/samples/namespace-reexports/_expected/system/index.js +++ b/test/chunking-form/samples/namespace-reexports/_expected/system/index.js @@ -1,8 +1,8 @@ -System.register(['./index-8b381a8d.js', './hsl2hsv.js'], function (exports, module) { +System.register(['./index-51f0f10d.js', './hsl2hsv.js'], function (exports, module) { 'use strict'; return { setters: [function (module) { - exports('hsl2hsv', module.a); + exports('hsl2hsv', module.b); }, function () {}], execute: function () { diff --git a/test/chunking-form/samples/namespace-reexports/_expected/system/main.js b/test/chunking-form/samples/namespace-reexports/_expected/system/main.js index 41bff92da97..a3b0fe5fe3e 100644 --- a/test/chunking-form/samples/namespace-reexports/_expected/system/main.js +++ b/test/chunking-form/samples/namespace-reexports/_expected/system/main.js @@ -1,12 +1,12 @@ -System.register(['./hsl2hsv.js', './index-8b381a8d.js'], function (exports, module) { +System.register(['./hsl2hsv.js', './index-51f0f10d.js'], function (exports, module) { 'use strict'; - var p, hsl2hsv, lib; + var hsl2hsv, p, lib; return { setters: [function (module) { + hsl2hsv = module.default; p = module.p; }, function (module) { - hsl2hsv = module.a; - lib = module.b; + lib = module.a; }], execute: function () { diff --git a/test/chunking-form/samples/preserve-modules-dynamic-imports/_config.js b/test/chunking-form/samples/preserve-modules-dynamic-imports/_config.js new file mode 100644 index 00000000000..808cce48441 --- /dev/null +++ b/test/chunking-form/samples/preserve-modules-dynamic-imports/_config.js @@ -0,0 +1,7 @@ +module.exports = { + description: 'dynamic imports are handled correctly when preserving modules', + options: { + input: ['main.js'], + experimentalPreserveModules: true + } +}; diff --git a/test/chunking-form/samples/dynamic-import-treeshaking/_expected/amd/chunk-7b720877.js b/test/chunking-form/samples/preserve-modules-dynamic-imports/_expected/amd/dynamic-included.js similarity index 52% rename from test/chunking-form/samples/dynamic-import-treeshaking/_expected/amd/chunk-7b720877.js rename to test/chunking-form/samples/preserve-modules-dynamic-imports/_expected/amd/dynamic-included.js index 972a328006d..cf69ecdb66b 100644 --- a/test/chunking-form/samples/dynamic-import-treeshaking/_expected/amd/chunk-7b720877.js +++ b/test/chunking-form/samples/preserve-modules-dynamic-imports/_expected/amd/dynamic-included.js @@ -1,7 +1,7 @@ define(['exports'], function (exports) { 'use strict'; - var multiplier = 7; + const value = 'included'; - exports.multiplier = multiplier; + exports.value = value; }); diff --git a/test/chunking-form/samples/preserve-modules-dynamic-imports/_expected/amd/main.js b/test/chunking-form/samples/preserve-modules-dynamic-imports/_expected/amd/main.js new file mode 100644 index 00000000000..83b30a7c2ee --- /dev/null +++ b/test/chunking-form/samples/preserve-modules-dynamic-imports/_expected/amd/main.js @@ -0,0 +1,5 @@ +define(['require'], function (require) { 'use strict'; + + new Promise(function (resolve, reject) { require(['./dynamic-included.js'], resolve, reject) }).then(result => console.log(result)); + +}); diff --git a/test/chunking-form/samples/preserve-modules-dynamic-imports/_expected/cjs/dynamic-included.js b/test/chunking-form/samples/preserve-modules-dynamic-imports/_expected/cjs/dynamic-included.js new file mode 100644 index 00000000000..7ce0b0473fe --- /dev/null +++ b/test/chunking-form/samples/preserve-modules-dynamic-imports/_expected/cjs/dynamic-included.js @@ -0,0 +1,5 @@ +'use strict'; + +const value = 'included'; + +exports.value = value; diff --git a/test/chunking-form/samples/preserve-modules-dynamic-imports/_expected/cjs/main.js b/test/chunking-form/samples/preserve-modules-dynamic-imports/_expected/cjs/main.js new file mode 100644 index 00000000000..4c20525ca3f --- /dev/null +++ b/test/chunking-form/samples/preserve-modules-dynamic-imports/_expected/cjs/main.js @@ -0,0 +1,3 @@ +'use strict'; + +Promise.resolve(require('./dynamic-included.js')).then(result => console.log(result)); diff --git a/test/chunking-form/samples/preserve-modules-dynamic-imports/_expected/es/dynamic-included.js b/test/chunking-form/samples/preserve-modules-dynamic-imports/_expected/es/dynamic-included.js new file mode 100644 index 00000000000..6370bf94358 --- /dev/null +++ b/test/chunking-form/samples/preserve-modules-dynamic-imports/_expected/es/dynamic-included.js @@ -0,0 +1,3 @@ +const value = 'included'; + +export { value }; diff --git a/test/chunking-form/samples/preserve-modules-dynamic-imports/_expected/es/main.js b/test/chunking-form/samples/preserve-modules-dynamic-imports/_expected/es/main.js new file mode 100644 index 00000000000..72ed76ddf10 --- /dev/null +++ b/test/chunking-form/samples/preserve-modules-dynamic-imports/_expected/es/main.js @@ -0,0 +1 @@ +import('./dynamic-included.js').then(result => console.log(result)); diff --git a/test/chunking-form/samples/preserve-modules-dynamic-imports/_expected/system/dynamic-included.js b/test/chunking-form/samples/preserve-modules-dynamic-imports/_expected/system/dynamic-included.js new file mode 100644 index 00000000000..2d9619f0134 --- /dev/null +++ b/test/chunking-form/samples/preserve-modules-dynamic-imports/_expected/system/dynamic-included.js @@ -0,0 +1,10 @@ +System.register([], function (exports, module) { + 'use strict'; + return { + execute: function () { + + const value = exports('value', 'included'); + + } + }; +}); diff --git a/test/chunking-form/samples/preserve-modules-dynamic-imports/_expected/system/main.js b/test/chunking-form/samples/preserve-modules-dynamic-imports/_expected/system/main.js new file mode 100644 index 00000000000..26c21dcccb5 --- /dev/null +++ b/test/chunking-form/samples/preserve-modules-dynamic-imports/_expected/system/main.js @@ -0,0 +1,10 @@ +System.register([], function (exports, module) { + 'use strict'; + return { + execute: function () { + + module.import('./dynamic-included.js').then(result => console.log(result)); + + } + }; +}); diff --git a/test/chunking-form/samples/preserve-modules-dynamic-imports/dynamic-included.js b/test/chunking-form/samples/preserve-modules-dynamic-imports/dynamic-included.js new file mode 100644 index 00000000000..287c398f8d6 --- /dev/null +++ b/test/chunking-form/samples/preserve-modules-dynamic-imports/dynamic-included.js @@ -0,0 +1 @@ +export const value = 'included'; diff --git a/test/chunking-form/samples/preserve-modules-dynamic-imports/dynamic-removed.js b/test/chunking-form/samples/preserve-modules-dynamic-imports/dynamic-removed.js new file mode 100644 index 00000000000..a0203faa48b --- /dev/null +++ b/test/chunking-form/samples/preserve-modules-dynamic-imports/dynamic-removed.js @@ -0,0 +1 @@ +export const value = 'removed'; diff --git a/test/chunking-form/samples/preserve-modules-dynamic-imports/main.js b/test/chunking-form/samples/preserve-modules-dynamic-imports/main.js new file mode 100644 index 00000000000..9449616c8fe --- /dev/null +++ b/test/chunking-form/samples/preserve-modules-dynamic-imports/main.js @@ -0,0 +1,6 @@ +import('./dynamic-included').then(result => console.log(result)); + +const include = false; +if (include) { + import('./dynamic-removed').then(result => console.log(result)); +} diff --git a/test/form/samples/default-identifier-deshadowing/dep.js b/test/form/samples/default-identifier-deshadowing/dep.js index 8349860b51a..1e617709bd7 100644 --- a/test/form/samples/default-identifier-deshadowing/dep.js +++ b/test/form/samples/default-identifier-deshadowing/dep.js @@ -1,4 +1,4 @@ export default function a() { a = someGlobal; return a(); -} \ No newline at end of file +} diff --git a/test/form/samples/dynamic-import-inlining/_expected.js b/test/form/samples/dynamic-import-inlining/_expected.js index 06bbf4869d3..03ab247516e 100644 --- a/test/form/samples/dynamic-import-inlining/_expected.js +++ b/test/form/samples/dynamic-import-inlining/_expected.js @@ -1,10 +1,10 @@ +const bar = 2; +Promise.resolve().then(function () { return foo$1; }); + const foo = 1; var foo$1 = /*#__PURE__*/Object.freeze({ foo: foo }); -const bar = 2; -Promise.resolve().then(function () { return foo$1; }); - export { bar }; diff --git a/test/form/samples/dynamic-import-inlining/main.js b/test/form/samples/dynamic-import-inlining/main.js index 17d42f4d6f5..ee3e6a770d6 100644 --- a/test/form/samples/dynamic-import-inlining/main.js +++ b/test/form/samples/dynamic-import-inlining/main.js @@ -1,3 +1,2 @@ -import { foo } from './foo.js'; -export const bar = 2 -import('./foo.js') \ No newline at end of file +export const bar = 2; +import('./foo.js'); diff --git a/test/form/samples/inlined-treeshaken-dynamic-import/_config.js b/test/form/samples/inlined-treeshaken-dynamic-import/_config.js new file mode 100644 index 00000000000..b5257d549c5 --- /dev/null +++ b/test/form/samples/inlined-treeshaken-dynamic-import/_config.js @@ -0,0 +1,6 @@ +module.exports = { + description: 'completely removes tree-shaken dynamic imports ', + options: { + inlineDynamicImports: true + } +}; diff --git a/test/form/samples/inlined-treeshaken-dynamic-import/_expected/amd.js b/test/form/samples/inlined-treeshaken-dynamic-import/_expected/amd.js new file mode 100644 index 00000000000..126aa22ee83 --- /dev/null +++ b/test/form/samples/inlined-treeshaken-dynamic-import/_expected/amd.js @@ -0,0 +1,5 @@ +define(function () { 'use strict'; + + console.log('main'); + +}); diff --git a/test/form/samples/inlined-treeshaken-dynamic-import/_expected/cjs.js b/test/form/samples/inlined-treeshaken-dynamic-import/_expected/cjs.js new file mode 100644 index 00000000000..d0ed06d8c90 --- /dev/null +++ b/test/form/samples/inlined-treeshaken-dynamic-import/_expected/cjs.js @@ -0,0 +1,3 @@ +'use strict'; + +console.log('main'); diff --git a/test/form/samples/inlined-treeshaken-dynamic-import/_expected/es.js b/test/form/samples/inlined-treeshaken-dynamic-import/_expected/es.js new file mode 100644 index 00000000000..c0b933d7b56 --- /dev/null +++ b/test/form/samples/inlined-treeshaken-dynamic-import/_expected/es.js @@ -0,0 +1 @@ +console.log('main'); diff --git a/test/form/samples/inlined-treeshaken-dynamic-import/_expected/iife.js b/test/form/samples/inlined-treeshaken-dynamic-import/_expected/iife.js new file mode 100644 index 00000000000..d283cbce8ba --- /dev/null +++ b/test/form/samples/inlined-treeshaken-dynamic-import/_expected/iife.js @@ -0,0 +1,6 @@ +(function () { + 'use strict'; + + console.log('main'); + +}()); diff --git a/test/form/samples/inlined-treeshaken-dynamic-import/_expected/system.js b/test/form/samples/inlined-treeshaken-dynamic-import/_expected/system.js new file mode 100644 index 00000000000..ba798b19101 --- /dev/null +++ b/test/form/samples/inlined-treeshaken-dynamic-import/_expected/system.js @@ -0,0 +1,10 @@ +System.register([], function (exports, module) { + 'use strict'; + return { + execute: function () { + + console.log('main'); + + } + }; +}); diff --git a/test/form/samples/inlined-treeshaken-dynamic-import/_expected/umd.js b/test/form/samples/inlined-treeshaken-dynamic-import/_expected/umd.js new file mode 100644 index 00000000000..41674034421 --- /dev/null +++ b/test/form/samples/inlined-treeshaken-dynamic-import/_expected/umd.js @@ -0,0 +1,9 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory() : + typeof define === 'function' && define.amd ? define(factory) : + (factory()); +}(this, (function () { 'use strict'; + + console.log('main'); + +}))); diff --git a/test/form/samples/inlined-treeshaken-dynamic-import/dynamic.js b/test/form/samples/inlined-treeshaken-dynamic-import/dynamic.js new file mode 100644 index 00000000000..1d7a1acc1b8 --- /dev/null +++ b/test/form/samples/inlined-treeshaken-dynamic-import/dynamic.js @@ -0,0 +1,2 @@ +console.log('dynamic'); +export var dynamic = 42; diff --git a/test/form/samples/inlined-treeshaken-dynamic-import/main.js b/test/form/samples/inlined-treeshaken-dynamic-import/main.js new file mode 100644 index 00000000000..9b0aad2c210 --- /dev/null +++ b/test/form/samples/inlined-treeshaken-dynamic-import/main.js @@ -0,0 +1,2 @@ +console.log('main'); +const getFoo = () => import('./dynamic.js'); diff --git a/test/function/samples/cycles-pathological/A.js b/test/function/samples/cycles-pathological/A.js deleted file mode 100644 index 9e0fd2e72cc..00000000000 --- a/test/function/samples/cycles-pathological/A.js +++ /dev/null @@ -1,11 +0,0 @@ -import B from './B'; - -export default class A { - constructor () { - this.isA = true; - } - - b () { - return new B(); - } -} diff --git a/test/function/samples/cycles-pathological/B.js b/test/function/samples/cycles-pathological/B.js deleted file mode 100644 index 1c8e9b4b3e5..00000000000 --- a/test/function/samples/cycles-pathological/B.js +++ /dev/null @@ -1,8 +0,0 @@ -import A from './A'; - -export default class B extends A { - constructor () { - super(); - this.isB = true; - } -} diff --git a/test/function/samples/cycles-pathological/C.js b/test/function/samples/cycles-pathological/C.js deleted file mode 100644 index 313bba7af02..00000000000 --- a/test/function/samples/cycles-pathological/C.js +++ /dev/null @@ -1,8 +0,0 @@ -import D from './D'; - -export default class C extends D { - constructor () { - super(); - this.isC = true; - } -} diff --git a/test/function/samples/cycles-pathological/D.js b/test/function/samples/cycles-pathological/D.js deleted file mode 100644 index 2d8a405328d..00000000000 --- a/test/function/samples/cycles-pathological/D.js +++ /dev/null @@ -1,11 +0,0 @@ -import C from './C'; - -export default class D { - constructor () { - this.isD = true; - } - - c () { - return new C(); - } -} diff --git a/test/function/samples/cycles-pathological/_config.js b/test/function/samples/cycles-pathological/_config.js deleted file mode 100644 index c400adbf775..00000000000 --- a/test/function/samples/cycles-pathological/_config.js +++ /dev/null @@ -1,17 +0,0 @@ -module.exports = { - skip: true, - description: 'resolves pathological cyclical dependencies gracefully', - buble: true, - warnings: [ - { - code: 'CIRCULAR_DEPENDENCY', - importer: 'A.js', - message: 'Circular dependency: A.js -> B.js -> A.js' - }, - { - code: 'CIRCULAR_DEPENDENCY', - importer: 'C.js', - message: 'Circular dependency: C.js -> D.js -> C.js' - } - ] -}; diff --git a/test/function/samples/cycles-pathological/main.js b/test/function/samples/cycles-pathological/main.js deleted file mode 100644 index f4c19dbcddb..00000000000 --- a/test/function/samples/cycles-pathological/main.js +++ /dev/null @@ -1,12 +0,0 @@ -import A from './A'; -import B from './B'; - -import C from './C'; -import D from './D'; - -export const a = new A(); -export const b1 = a.b(); -export const b2 = new B(); -export const c1 = new C(); -export const d = new D(); -export const c2 = d.c(); diff --git a/test/function/samples/iife-strong-dependencies/A.js b/test/function/samples/iife-strong-dependencies/A.js deleted file mode 100644 index 2c51ca572ab..00000000000 --- a/test/function/samples/iife-strong-dependencies/A.js +++ /dev/null @@ -1,15 +0,0 @@ -import { B } from './B'; - -export var A = function () { - this.isA = true; -}; - -A.prototype = { - b: function () { - var Constructor = B; - - return function () { - return new Constructor(); - }; - }() -}; diff --git a/test/function/samples/iife-strong-dependencies/B.js b/test/function/samples/iife-strong-dependencies/B.js deleted file mode 100644 index f06d45d100e..00000000000 --- a/test/function/samples/iife-strong-dependencies/B.js +++ /dev/null @@ -1,11 +0,0 @@ -import { A } from './A'; - -export var B = function () { - this.isB = true; -}; - -B.prototype = { - a: function () { - return new A(); - } -}; diff --git a/test/function/samples/iife-strong-dependencies/C.js b/test/function/samples/iife-strong-dependencies/C.js deleted file mode 100644 index 9da83316bec..00000000000 --- a/test/function/samples/iife-strong-dependencies/C.js +++ /dev/null @@ -1,11 +0,0 @@ -import { D } from './D'; - -export var C = function () { - this.isC = true; -}; - -C.prototype = { - d: function () { - return new D(); - } -}; diff --git a/test/function/samples/iife-strong-dependencies/D.js b/test/function/samples/iife-strong-dependencies/D.js deleted file mode 100644 index ad3afa0b7e3..00000000000 --- a/test/function/samples/iife-strong-dependencies/D.js +++ /dev/null @@ -1,15 +0,0 @@ -import { C } from './C'; - -export var D = function () { - this.isD = true; -}; - -D.prototype = { - c: function () { - var Constructor = C; - - return function () { - return new Constructor(); - }; - }() -}; diff --git a/test/function/samples/iife-strong-dependencies/_config.js b/test/function/samples/iife-strong-dependencies/_config.js deleted file mode 100644 index f1e515689ab..00000000000 --- a/test/function/samples/iife-strong-dependencies/_config.js +++ /dev/null @@ -1,16 +0,0 @@ -module.exports = { - skip: true, - description: 'does not treat references inside IIFEs as weak dependencies', // edge case encountered in THREE.js codebase - warnings: [ - { - code: 'CIRCULAR_DEPENDENCY', - importer: 'A.js', - message: 'Circular dependency: A.js -> B.js -> A.js' - }, - { - code: 'CIRCULAR_DEPENDENCY', - importer: 'C.js', - message: 'Circular dependency: C.js -> D.js -> C.js' - } - ] -}; diff --git a/test/function/samples/iife-strong-dependencies/main.js b/test/function/samples/iife-strong-dependencies/main.js deleted file mode 100644 index 1eaa49de80e..00000000000 --- a/test/function/samples/iife-strong-dependencies/main.js +++ /dev/null @@ -1,14 +0,0 @@ -import { A } from './A'; -import { B } from './B'; -import { C } from './C'; -import { D } from './D'; - -export var a1 = new A(); -export var b1 = new B(); -export var c1 = new C(); -export var d1 = new D(); - -export var a2 = b1.a(); -export var b2 = a1.b(); -export var c2 = d1.c(); -export var d2 = c1.d(); diff --git a/test/function/samples/inline-imports-with-manual/_config.js b/test/function/samples/inline-imports-with-manual/_config.js new file mode 100644 index 00000000000..c77cccc9faf --- /dev/null +++ b/test/function/samples/inline-imports-with-manual/_config.js @@ -0,0 +1,15 @@ +module.exports = { + description: 'Manual chunks are not supported when inlining dynamic imports', + options: { + input: ['main.js'], + experimentalCodeSplitting: true, + inlineDynamicImports: true, + manualChunks: { + lib: ['lib.js'] + } + }, + error: { + code: 'INVALID_OPTION', + message: '"manualChunks" option is not supported for inlineDynamicImports.' + } +}; diff --git a/test/function/samples/inline-imports-with-manual/lib.js b/test/function/samples/inline-imports-with-manual/lib.js new file mode 100644 index 00000000000..46d3ca8c61f --- /dev/null +++ b/test/function/samples/inline-imports-with-manual/lib.js @@ -0,0 +1 @@ +export const value = 42; diff --git a/test/function/samples/inline-imports-with-manual/main.js b/test/function/samples/inline-imports-with-manual/main.js new file mode 100644 index 00000000000..4869dc82f38 --- /dev/null +++ b/test/function/samples/inline-imports-with-manual/main.js @@ -0,0 +1 @@ +import('./lib').then(({value}) => assert.equal(value, 42)); diff --git a/test/function/samples/inline-imports-with-multiple/_config.js b/test/function/samples/inline-imports-with-multiple/_config.js new file mode 100644 index 00000000000..c114010bc87 --- /dev/null +++ b/test/function/samples/inline-imports-with-multiple/_config.js @@ -0,0 +1,12 @@ +module.exports = { + description: 'Having multiple inputs is not supported when inlining dynamic imports', + options: { + input: ['main.js'], + experimentalCodeSplitting: true, + inlineDynamicImports: true + }, + error: { + code: 'INVALID_OPTION', + message: 'Multiple inputs are not supported for inlineDynamicImports.' + } +}; diff --git a/test/function/samples/inline-imports-with-multiple/lib.js b/test/function/samples/inline-imports-with-multiple/lib.js new file mode 100644 index 00000000000..46d3ca8c61f --- /dev/null +++ b/test/function/samples/inline-imports-with-multiple/lib.js @@ -0,0 +1 @@ +export const value = 42; diff --git a/test/function/samples/inline-imports-with-multiple/main.js b/test/function/samples/inline-imports-with-multiple/main.js new file mode 100644 index 00000000000..4869dc82f38 --- /dev/null +++ b/test/function/samples/inline-imports-with-multiple/main.js @@ -0,0 +1 @@ +import('./lib').then(({value}) => assert.equal(value, 42)); diff --git a/test/function/samples/inline-imports-with-optimize/_config.js b/test/function/samples/inline-imports-with-optimize/_config.js new file mode 100644 index 00000000000..13b6aa67ad5 --- /dev/null +++ b/test/function/samples/inline-imports-with-optimize/_config.js @@ -0,0 +1,13 @@ +module.exports = { + description: 'Optimizing chunks is not supported when inlining dynamic imports', + options: { + input: ['main.js'], + experimentalCodeSplitting: true, + inlineDynamicImports: true, + experimentalOptimizeChunks: true + }, + error: { + code: 'INVALID_OPTION', + message: '"experimentalOptimizeChunks" option is not supported for inlineDynamicImports.' + } +}; diff --git a/test/function/samples/inline-imports-with-optimize/lib.js b/test/function/samples/inline-imports-with-optimize/lib.js new file mode 100644 index 00000000000..46d3ca8c61f --- /dev/null +++ b/test/function/samples/inline-imports-with-optimize/lib.js @@ -0,0 +1 @@ +export const value = 42; diff --git a/test/function/samples/inline-imports-with-optimize/main.js b/test/function/samples/inline-imports-with-optimize/main.js new file mode 100644 index 00000000000..4869dc82f38 --- /dev/null +++ b/test/function/samples/inline-imports-with-optimize/main.js @@ -0,0 +1 @@ +import('./lib').then(({value}) => assert.equal(value, 42)); diff --git a/test/function/samples/preserve-modules-with-inline/_config.js b/test/function/samples/preserve-modules-with-inline/_config.js new file mode 100644 index 00000000000..621aec7d0cf --- /dev/null +++ b/test/function/samples/preserve-modules-with-inline/_config.js @@ -0,0 +1,13 @@ +module.exports = { + description: 'Inlining dynamic imports is not supported when preserving modules', + options: { + input: ['main.js'], + experimentalCodeSplitting: true, + experimentalPreserveModules: true, + inlineDynamicImports: true + }, + error: { + code: 'INVALID_OPTION', + message: 'experimentalPreserveModules does not support the inlineDynamicImports option.' + } +}; diff --git a/test/function/samples/preserve-modules-with-inline/lib.js b/test/function/samples/preserve-modules-with-inline/lib.js new file mode 100644 index 00000000000..46d3ca8c61f --- /dev/null +++ b/test/function/samples/preserve-modules-with-inline/lib.js @@ -0,0 +1 @@ +export const value = 42; diff --git a/test/function/samples/preserve-modules-with-inline/main.js b/test/function/samples/preserve-modules-with-inline/main.js new file mode 100644 index 00000000000..4869dc82f38 --- /dev/null +++ b/test/function/samples/preserve-modules-with-inline/main.js @@ -0,0 +1 @@ +import('./lib').then(({value}) => assert.equal(value, 42)); diff --git a/test/function/samples/preserve-modules-with-manual/_config.js b/test/function/samples/preserve-modules-with-manual/_config.js new file mode 100644 index 00000000000..76cb53b8b9e --- /dev/null +++ b/test/function/samples/preserve-modules-with-manual/_config.js @@ -0,0 +1,15 @@ +module.exports = { + description: 'Assigning manual chunks fails when preserving modules', + options: { + input: ['main.js'], + experimentalCodeSplitting: true, + experimentalPreserveModules: true, + manualChunks: { + lib: ['lib.js'] + } + }, + error: { + code: 'INVALID_OPTION', + message: 'experimentalPreserveModules does not support the manualChunks option.' + } +}; diff --git a/test/function/samples/preserve-modules-with-manual/lib.js b/test/function/samples/preserve-modules-with-manual/lib.js new file mode 100644 index 00000000000..46d3ca8c61f --- /dev/null +++ b/test/function/samples/preserve-modules-with-manual/lib.js @@ -0,0 +1 @@ +export const value = 42; diff --git a/test/function/samples/preserve-modules-with-manual/main.js b/test/function/samples/preserve-modules-with-manual/main.js new file mode 100644 index 00000000000..0786352d0f9 --- /dev/null +++ b/test/function/samples/preserve-modules-with-manual/main.js @@ -0,0 +1,3 @@ +import { value } from './lib'; + +assert.equal(value, 42); diff --git a/test/function/samples/preserve-modules-with-optimize/_config.js b/test/function/samples/preserve-modules-with-optimize/_config.js new file mode 100644 index 00000000000..f93fc307106 --- /dev/null +++ b/test/function/samples/preserve-modules-with-optimize/_config.js @@ -0,0 +1,13 @@ +module.exports = { + description: 'Optimizing chunks fails when preserving modules', + options: { + input: ['main.js'], + experimentalCodeSplitting: true, + experimentalPreserveModules: true, + experimentalOptimizeChunks: true + }, + error: { + code: 'INVALID_OPTION', + message: 'experimentalPreserveModules does not support the experimentalOptimizeChunks option.' + } +}; diff --git a/test/function/samples/preserve-modules-with-optimize/lib.js b/test/function/samples/preserve-modules-with-optimize/lib.js new file mode 100644 index 00000000000..46d3ca8c61f --- /dev/null +++ b/test/function/samples/preserve-modules-with-optimize/lib.js @@ -0,0 +1 @@ +export const value = 42; diff --git a/test/function/samples/preserve-modules-with-optimize/main.js b/test/function/samples/preserve-modules-with-optimize/main.js new file mode 100644 index 00000000000..0786352d0f9 --- /dev/null +++ b/test/function/samples/preserve-modules-with-optimize/main.js @@ -0,0 +1,3 @@ +import { value } from './lib'; + +assert.equal(value, 42); diff --git a/test/hooks/index.js b/test/hooks/index.js index 628ece9564f..7e4dc1a4963 100644 --- a/test/hooks/index.js +++ b/test/hooks/index.js @@ -1102,7 +1102,7 @@ module.exports = input; .then(bundle => bundle.generate({ entryFileNames: '[name].js', - chunkFileNames: '[name].js', + chunkFileNames: 'generated-[name].js', format: 'esm' }) ) @@ -1114,18 +1114,18 @@ module.exports = input; modules: ['input'] }, { - fileName: 'a.js', - imports: ['chunk.js'], + fileName: 'generated-chunk.js', + imports: ['generated-chunk2.js'], modules: ['d', 'a'] }, { - fileName: 'chunk.js', + fileName: 'generated-chunk2.js', imports: [], modules: ['c'] }, { - fileName: 'b.js', - imports: ['chunk.js'], + fileName: 'generated-chunk3.js', + imports: ['generated-chunk2.js'], modules: ['b'] } ]); diff --git a/test/misc/acorn-plugins.js b/test/misc/acorn-plugins.js new file mode 100644 index 00000000000..1cb8a9f7d9c --- /dev/null +++ b/test/misc/acorn-plugins.js @@ -0,0 +1,124 @@ +const assert = require('assert'); +const rollup = require('../../dist/rollup'); +const { executeBundle, loader } = require('../utils.js'); + +describe('acorn plugins', () => { + // Acorn registers plugins globally per process. The tests in this suite + // use unique plugin names to make sure each plugin is registered in its + // proper test rather than in a test that ran earlier. + + it('injects plugins passed in acornInjectPlugins', () => { + let pluginAInjected = false; + let pluginBInjected = false; + + return rollup + .rollup({ + input: 'x.js', + plugins: [loader({ 'x.js': `export default 42` })], + acornInjectPlugins: [ + function pluginA(acorn) { + pluginAInjected = true; + return acorn; + }, + function pluginB(acorn) { + pluginBInjected = true; + return acorn; + } + ] + }) + .then(executeBundle) + .then(result => { + assert.equal(result, 42); + assert( + pluginAInjected, + 'A plugin passed via acornInjectPlugins should inject itself into Acorn.' + ); + assert( + pluginBInjected, + 'A plugin passed via acornInjectPlugins should inject itself into Acorn.' + ); + }); + }); + + it('injected plugins are registered with Acorn only if acorn.plugins is set', () => { + let pluginCRegistered = false; + let pluginDRegistered = false; + + function pluginC(acorn) { + acorn.plugins.pluginC = () => (pluginCRegistered = true); + return acorn; + } + + function pluginD(acorn) { + acorn.plugins.pluginD = () => (pluginDRegistered = true); + return acorn; + } + + return rollup + .rollup({ + input: 'x.js', + plugins: [loader({ 'x.js': `export default 42` })], + acorn: { + plugins: { + pluginC: true + } + }, + acornInjectPlugins: [pluginC, pluginD] + }) + .then(executeBundle) + .then(result => { + assert.equal(result, 42); + assert.equal( + pluginCRegistered, + true, + 'A plugin enabled in acorn.plugins should register with Acorn.' + ); + assert.equal( + pluginDRegistered, + false, + 'A plugin not enabled in acorn.plugins should not register with Acorn.' + ); + }); + }); + + it('throws if acorn.plugins is set and acornInjectPlugins is missing', () => { + return rollup + .rollup({ + input: 'x.js', + plugins: [loader({ 'x.js': `export default 42` })], + acorn: { + plugins: { + pluginE: true + } + } + }) + .then(executeBundle) + .then(() => { + throw new Error('Missing expected error'); + }) + .catch(error => { + assert.equal(error.message, "Plugin 'pluginE' not found"); + }); + }); + + it('throws if acorn.plugins is set and acornInjectPlugins is empty', () => { + return rollup + .rollup({ + input: 'x.js', + plugins: [loader({ 'x.js': `export default 42` })], + acorn: { + plugins: { + pluginF: true + } + }, + acornInjectPlugins: [] + }) + .then(executeBundle) + .then(() => { + throw new Error('Missing expected error'); + }) + .catch(error => { + assert.equal(error.message, "Plugin 'pluginF' not found"); + }); + }); +}); diff --git a/test/misc/bundle-information.js b/test/misc/bundle-information.js new file mode 100644 index 00000000000..f332600bc9c --- /dev/null +++ b/test/misc/bundle-information.js @@ -0,0 +1,419 @@ +const assert = require('assert'); +const rollup = require('../../dist/rollup'); +const { loader } = require('../utils.js'); + +describe('The bundle object', () => { + it('contains information about the generated chunks', () => { + return rollup + .rollup({ + input: ['input1', 'input2'], + experimentalCodeSplitting: true, + plugins: [ + loader({ + input1: 'import "shared";console.log("input1");export const out = true;', + input2: 'import "shared";console.log("input2");export default 42', + shared: 'console.log("shared");export const unused = null;' + }) + ] + }) + .then(bundle => + bundle.generate({ + format: 'esm', + dir: 'dist', + chunkFileNames: 'generated-[name]-[hash].js', + entryFileNames: '[name]-[hash].js' + }) + ) + .then(({ output }) => { + const sortedOutput = Object.keys(output) + .sort() + .map(key => output[key]); + assert.deepEqual( + sortedOutput.map(chunk => chunk.fileName), + ['generated-chunk-dc742c8f.js', 'input1-00b2c9b1.js', 'input2-e2618782.js'], + 'fileName' + ); + assert.deepEqual( + sortedOutput.map(chunk => chunk.code), + [ + 'console.log("shared");\n', + `import './generated-chunk-dc742c8f.js';\n\nconsole.log("input1");const out = true;\n\nexport { out };\n`, + `import './generated-chunk-dc742c8f.js';\n\nconsole.log("input2");var input2 = 42;\n\nexport default input2;\n` + ], + 'code' + ); + assert.deepEqual(sortedOutput.map(chunk => chunk.map), [null, null, null], 'map'); + assert.deepEqual(sortedOutput.map(chunk => chunk.isEntry), [false, true, true], 'isEntry'); + assert.deepEqual( + sortedOutput.map(chunk => chunk.name), + ['chunk', 'input1', 'input2'], + 'name' + ); + assert.deepEqual( + sortedOutput.map(chunk => chunk.facadeModuleId), + [null, 'input1', 'input2'], + 'facadeModuleId' + ); + assert.deepEqual( + sortedOutput.map(chunk => chunk.imports), + [[], ['generated-chunk-dc742c8f.js'], ['generated-chunk-dc742c8f.js']], + 'imports' + ); + assert.deepEqual( + sortedOutput.map(chunk => chunk.dynamicImports), + [[], [], []], + 'dynamicImports' + ); + assert.deepEqual( + sortedOutput.map(chunk => chunk.exports), + [[], ['out'], ['default']], + 'exports' + ); + assert.deepEqual( + sortedOutput.map(chunk => chunk.modules), + [ + { + shared: { + originalLength: 49, + removedExports: ['unused'], + renderedExports: [], + renderedLength: 22 + } + }, + { + input1: { + originalLength: 62, + removedExports: [], + renderedExports: ['out'], + renderedLength: 39 + } + }, + { + input2: { + originalLength: 55, + removedExports: [], + renderedExports: ['default'], + renderedLength: 38 + } + } + ], + 'modules' + ); + }); + }); + + it('handles entry facades as entry points but not the facaded chunk', () => { + return rollup + .rollup({ + input: ['input1', 'input2'], + experimentalCodeSplitting: true, + plugins: [ + loader({ + input1: + 'import {shared} from "shared";import {input2} from "input2";console.log(input2, shared);', + input2: 'import {shared} from "shared";export const input2 = "input2";', + shared: 'export const shared = "shared"' + }) + ] + }) + .then(bundle => + bundle.generate({ + format: 'esm', + dir: 'dist', + chunkFileNames: 'generated-[name].js' + }) + ) + .then(({ output }) => { + const sortedOutput = Object.keys(output) + .sort() + .map(key => output[key]); + assert.deepEqual( + sortedOutput.map(chunk => chunk.fileName), + ['generated-input2.js', 'input1.js', 'input2.js'], + 'fileName' + ); + assert.deepEqual( + sortedOutput.map(chunk => Object.keys(chunk.modules)), + [['shared', 'input2'], ['input1'], []], + 'modules' + ); + assert.deepEqual(sortedOutput.map(chunk => chunk.isEntry), [false, true, true], 'isEntry'); + assert.deepEqual( + sortedOutput.map(chunk => chunk.facadeModuleId), + [null, 'input1', 'input2'], + 'facadeModuleId' + ); + }); + }); + + it('prioritizes the proper facade name over the proper facaded chunk name', () => { + return rollup + .rollup({ + input: ['input1', 'input2'], + experimentalCodeSplitting: true, + plugins: [ + loader({ + input1: + 'import {shared} from "shared";import {input2} from "input2";console.log(input2, shared);', + input2: 'import {shared} from "shared";export const input2 = "input2";', + shared: 'export const shared = "shared"' + }) + ] + }) + .then(bundle => + bundle.generate({ + format: 'esm', + dir: 'dist', + entryFileNames: '[name].js', + chunkFileNames: '[name].js' + }) + ) + .then(({ output }) => { + const sortedOutput = Object.keys(output) + .sort() + .map(key => output[key]); + assert.deepEqual( + sortedOutput.map(chunk => chunk.fileName), + ['input1.js', 'input2.js', 'input22.js'], + 'fileName' + ); + assert.deepEqual( + sortedOutput.map(chunk => chunk.facadeModuleId), + ['input1', 'input2', null], + 'facadeModuleId' + ); + }); + }); + + it('marks dynamic entry points but only marks them as normal entry points if they actually are', () => { + return rollup + .rollup({ + input: ['input', 'dynamic1'], + experimentalCodeSplitting: true, + plugins: [ + loader({ + input: `Promise.all([import('dynamic1'), import('dynamic2')]).then(([{dynamic1}, {dynamic2}]) => console.log(dynamic1, dynamic2));`, + dynamic1: 'export const dynamic1 = "dynamic1"', + dynamic2: 'export const dynamic2 = "dynamic2"' + }) + ] + }) + .then(bundle => + bundle.generate({ + format: 'esm', + dir: 'dist', + entryFileNames: '[name].js', + chunkFileNames: 'generated-[name].js' + }) + ) + .then(({ output }) => { + const sortedOutput = Object.keys(output) + .sort() + .map(key => output[key]); + assert.deepEqual( + sortedOutput.map(chunk => chunk.fileName), + ['dynamic1.js', 'generated-chunk.js', 'input.js'], + 'fileName' + ); + assert.deepEqual(sortedOutput.map(chunk => chunk.isEntry), [true, false, true], 'isEntry'); + assert.deepEqual( + sortedOutput.map(chunk => chunk.code), + [ + 'const dynamic1 = "dynamic1";\n\nexport { dynamic1 };\n', + 'const dynamic2 = "dynamic2";\n\nexport { dynamic2 };\n', + `Promise.all([import('./dynamic1.js'), import('./generated-chunk.js')]).then(([{dynamic1}, {dynamic2}]) => console.log(dynamic1, dynamic2));\n` + ], + 'code' + ); + assert.deepEqual( + sortedOutput.map(chunk => chunk.isDynamicEntry), + [true, true, false], + 'isDynamicEntry' + ); + assert.deepEqual( + sortedOutput.map(chunk => chunk.facadeModuleId), + ['dynamic1', 'dynamic2', 'input'], + 'facadeModuleId' + ); + assert.deepEqual( + sortedOutput.map(chunk => chunk.dynamicImports), + [[], [], ['dynamic1.js', 'generated-chunk.js']], + 'dynamicImports' + ); + }); + }); + + it('handles dynamic entry facades as dynamic entries but not the facaded chunk', () => { + return rollup + .rollup({ + input: ['input1', 'input2'], + experimentalCodeSplitting: true, + plugins: [ + loader({ + input1: `import('dynamic').then(({dynamic}) => console.log(dynamic));`, + input2: `import {dep} from 'dep'; import {dynamic} from 'dynamic'; console.log(dep, dynamic);`, + dynamic: `import {dep} from 'dep'; console.log(dep); export const dynamic = 'dynamic';`, + dep: `export const dep = 'dep';` + }) + ] + }) + .then(bundle => + bundle.generate({ + format: 'esm', + dir: 'dist', + entryFileNames: '[name].js', + chunkFileNames: 'generated-[name].js' + }) + ) + .then(({ output }) => { + const sortedOutput = Object.keys(output) + .sort() + .map(key => output[key]); + assert.deepEqual( + sortedOutput.map(chunk => chunk.fileName), + ['generated-chunk.js', 'generated-chunk2.js', 'input1.js', 'input2.js'], + 'fileName' + ); + assert.deepEqual( + sortedOutput.map(chunk => Object.keys(chunk.modules)), + [['dep', 'dynamic'], [], ['input1'], ['input2']], + 'modules' + ); + assert.deepEqual( + sortedOutput.map(chunk => chunk.isDynamicEntry), + [false, true, false, false], + 'isDynamicEntry' + ); + assert.deepEqual( + sortedOutput.map(chunk => chunk.facadeModuleId), + [null, 'dynamic', 'input1', 'input2'], + 'facadeModuleId' + ); + assert.deepEqual( + sortedOutput.map(chunk => chunk.dynamicImports), + [[], [], ['generated-chunk.js'], []], + 'dynamicImports' + ); + }); + }); + + it('adds correct flags to files when preserving modules', () => { + return rollup + .rollup({ + input: ['input', 'dynamic1'], + experimentalCodeSplitting: true, + experimentalPreserveModules: true, + plugins: [ + loader({ + input: `import {other} from "other";console.log(other);Promise.all([import('dynamic1'), import('dynamic2')]).then(([{dynamic1}, {dynamic2}]) => console.log(dynamic1, dynamic2));`, + dynamic1: 'export const dynamic1 = "dynamic1"', + dynamic2: 'export const dynamic2 = "dynamic2"', + other: 'export const other = "other"' + }) + ] + }) + .then(bundle => + bundle.generate({ + format: 'esm', + dir: 'dist', + entryFileNames: '[name].js', + chunkFileNames: 'generated-[name].js' + }) + ) + .then(({ output }) => { + const sortedOutput = Object.keys(output) + .sort() + .map(key => output[key]); + assert.deepEqual( + sortedOutput.map(chunk => chunk.fileName), + ['_virtual/dynamic1', '_virtual/dynamic2', '_virtual/input', '_virtual/other'], + 'fileName' + ); + assert.deepEqual( + sortedOutput.map(chunk => chunk.isEntry), + [true, false, true, false], + 'isEntry' + ); + assert.deepEqual( + sortedOutput.map(chunk => chunk.code), + [ + 'const dynamic1 = "dynamic1";\n\nexport { dynamic1 };\n', + 'const dynamic2 = "dynamic2";\n\nexport { dynamic2 };\n', + `import { other } from './other'; + +console.log(other);Promise.all([import('./dynamic1'), import('./dynamic2')]).then(([{dynamic1}, {dynamic2}]) => console.log(dynamic1, dynamic2));\n`, + 'const other = "other";\n\nexport { other };\n' + ], + 'code' + ); + assert.deepEqual( + sortedOutput.map(chunk => chunk.name), + ['dynamic1', 'chunk', 'input', 'chunk'], + 'name' + ); + assert.deepEqual( + sortedOutput.map(chunk => chunk.imports), + [[], [], ['_virtual/other'], []], + 'imports' + ); + assert.deepEqual( + sortedOutput.map(chunk => chunk.exports), + [['dynamic1'], ['dynamic2'], [], ['other']], + 'exports' + ); + assert.deepEqual( + sortedOutput.map(chunk => chunk.dynamicImports), + [[], [], ['_virtual/dynamic1', '_virtual/dynamic2'], []], + 'dynamicImports' + ); + assert.deepEqual( + sortedOutput.map(chunk => chunk.modules), + [ + { + dynamic1: { + originalLength: 34, + removedExports: [], + renderedExports: ['dynamic1'], + renderedLength: 28 + } + }, + { + dynamic2: { + originalLength: 34, + removedExports: [], + renderedExports: ['dynamic2'], + renderedLength: 28 + } + }, + { + input: { + originalLength: 169, + removedExports: [], + renderedExports: [], + renderedLength: 141 + } + }, + { + other: { + originalLength: 28, + removedExports: [], + renderedExports: ['other'], + renderedLength: 22 + } + } + ], + 'modules' + ); + assert.deepEqual( + sortedOutput.map(chunk => chunk.isDynamicEntry), + [true, true, false, false], + 'isDynamicEntry' + ); + assert.deepEqual( + sortedOutput.map(chunk => chunk.facadeModuleId), + ['dynamic1', 'dynamic2', 'input', 'other'], + 'facadeModuleId' + ); + }); + }); +}); diff --git a/test/misc/deprecations.js b/test/misc/deprecations.js new file mode 100644 index 00000000000..0740aef7084 --- /dev/null +++ b/test/misc/deprecations.js @@ -0,0 +1,93 @@ +const assert = require('assert'); +const rollup = require('../../dist/rollup'); +const { executeBundle, loader } = require('../utils.js'); + +describe('deprecations', () => { + it('warns on options.entry, but handles', () => { + const warnings = []; + return rollup + .rollup({ + entry: 'x', + plugins: [loader({ x: `export default 42` })], + onwarn: warning => { + warnings.push(warning); + } + }) + .then(executeBundle) + .then(result => { + assert.equal(result, 42); + assert.deepEqual(warnings, [ + { + code: 'DEPRECATED_OPTIONS', + deprecations: [ + { + new: 'input', + old: 'entry' + } + ], + message: `The following options have been renamed — please update your config: entry -> input` + } + ]); + }); + }); + + it('adds deprecations correctly for rollup', () => { + const warnings = []; + return rollup + .rollup({ + entry: 'x', + format: 'cjs', + indent: true, + sourceMap: true, + plugins: [loader({ x: `export default 42` })], + onwarn: warning => { + warnings.push(warning); + } + }) + .then(executeBundle) + .then(result => { + assert.equal(result, 42); + const deprecations = warnings[0].deprecations; + assert.equal(deprecations.length, 4); + assert.deepEqual(deprecations, [ + { new: 'input', old: 'entry' }, + { new: 'output.indent', old: 'indent' }, + { new: 'output.sourcemap', old: 'sourceMap' }, + { new: 'output.format', old: 'format' } + ]); + }); + }); + + it('throws a useful error on accessing code/map properties of bundle.generate promise', () => { + return rollup + .rollup({ + input: 'x', + plugins: [loader({ x: `console.log( 42 );` })] + }) + .then(bundle => { + let errored = false; + + try { + const { code, map } = bundle.generate({ format: 'es' }); + console.log(code, map); + } catch (err) { + assert.equal( + err.message, + `bundle.generate(...) now returns a Promise instead of a { code, map } object` + ); + errored = true; + } + + assert.ok(errored); + }); + }); + + it('supports esm format alias', () => { + return rollup + .rollup({ input: 'x', plugins: [loader({ x: 'export const x = function () {}' })] }) + .then(bundle => bundle.generate({ format: 'esm' })) + .then(({ code }) => { + assert.equal(code, 'const x = function () {};\n\nexport { x };\n'); + }); + }); +}); diff --git a/test/misc/in-memory-sourcemaps.js b/test/misc/in-memory-sourcemaps.js new file mode 100644 index 00000000000..2fb9308494a --- /dev/null +++ b/test/misc/in-memory-sourcemaps.js @@ -0,0 +1,33 @@ +const assert = require('assert'); +const path = require('path'); +const rollup = require('../../dist/rollup'); +const { loader } = require('../utils.js'); +const { SourceMapConsumer } = require('source-map'); +const { getLocator } = require('locate-character'); + +describe('in-memory sourcemaps', () => { + it('generates an in-memory sourcemap', () => { + return rollup + .rollup({ + input: 'main', + plugins: [loader({ main: `console.log( 42 );` })] + }) + .then(bundle => { + return bundle.generate({ + format: 'cjs', + sourcemap: true, + sourcemapFile: path.resolve('bundle.js') + }); + }) + .then(generated => { + const smc = new SourceMapConsumer(generated.map); + const locator = getLocator(generated.code, { offsetLine: 1 }); + + const generatedLoc = locator('42'); + const loc = smc.originalPositionFor(generatedLoc); // 42 + assert.equal(loc.source, 'main'); + assert.equal(loc.line, 1); + assert.equal(loc.column, 13); + }); + }); +}); diff --git a/test/misc/index.js b/test/misc/index.js index 447e667e1b8..805a21b32a5 100644 --- a/test/misc/index.js +++ b/test/misc/index.js @@ -1,583 +1,7 @@ -const assert = require('assert'); -const path = require('path'); -const rollup = require('../../dist/rollup'); -const { executeBundle, loader } = require('../utils.js'); -const { SourceMapConsumer } = require('source-map'); -const { getLocator } = require('locate-character'); - -describe('sanity checks', () => { - it('exists', () => { - assert.ok(!!rollup); - }); - - it('has a rollup method', () => { - assert.equal(typeof rollup.rollup, 'function'); - }); - - it('fails without options', () => { - return rollup - .rollup() - .then(() => { - throw new Error('Missing expected error'); - }) - .catch(err => { - assert.equal(err.message, 'You must supply an options object to rollup'); - }); - }); - - it('node API passes warning and default handler to custom onwarn function', () => { - let args = []; - return rollup - .rollup({ - entry: 'x', - plugins: [loader({ x: `console.log( 42 );` })], - onwarn(warning, onwarn) { - args = [warning, onwarn]; - } - }) - .then(() => { - assert.deepEqual(args[0], { - code: 'DEPRECATED_OPTIONS', - deprecations: [ - { - new: 'input', - old: 'entry' - } - ], - message: `The following options have been renamed — please update your config: entry -> input` - }); - assert.equal(typeof args[1], 'function'); - }); - }); - - it('fails without options.input', () => { - return rollup - .rollup({}) - .then(() => { - throw new Error('Missing expected error'); - }) - .catch(err => { - assert.equal(err.message, 'You must supply options.input to rollup'); - }); - }); - - it('fails with invalid keys', () => { - const warnings = []; - const onwarn = warning => warnings.push(warning); - return rollup - .rollup({ input: 'x', onwarn, plUgins: [], plugins: [loader({ x: `console.log( 42 );` })] }) - .then(() => { - assert.deepEqual(warnings, [ - { - code: 'UNKNOWN_OPTION', - message: - 'Unknown input option: plUgins. Allowed options: ' + require('./optionList').input - } - ]); - }); - }); - - it('treats Literals as leaf nodes, even if first literal encountered is null', () => { - // this test has to be up here, otherwise the bug doesn't have - // an opportunity to present itself - return rollup.rollup({ - input: 'x', - plugins: [loader({ x: `var a = null; a = 'a string';` })] - }); - }); - - it('includes a newline at the end of the bundle', () => { - return rollup - .rollup({ - input: 'x', - plugins: [loader({ x: `console.log( 42 );` })] - }) - .then(bundle => { - return bundle.generate({ format: 'iife' }); - }) - .then(({ code }) => { - assert.ok(code[code.length - 1] === '\n'); - }); - }); - - it('throws on missing output options', () => { - const warnings = []; - - return rollup - .rollup({ - input: 'x', - plugins: [loader({ x: `console.log( 42 );` })], - onwarn: warning => warnings.push(warning) - }) - .then(bundle => { - assert.throws(() => { - bundle.generate(); - }, /You must supply an options object/); - }); - }); - - it('throws on missing format option', () => { - const warnings = []; - - return rollup - .rollup({ - input: 'x', - plugins: [loader({ x: `console.log( 42 );` })], - onwarn: warning => warnings.push(warning) - }) - .then(bundle => { - assert.throws(() => { - bundle.generate({ file: 'x' }); - }, /You must specify output\.format, which can be one of 'amd', 'cjs', 'system', 'esm', 'iife' or 'umd'/); - }); - }); - - it('reuses existing error object', () => { - let error; - - class CustomError extends Error { - constructor(message, x) { - super(message); - this.prop = x.toUpperCase(); - } - } - - return rollup - .rollup({ - input: 'x', - plugins: [ - loader({ x: `console.log( 42 );` }), - { - transform(code) { - error = new CustomError('foo', 'bar'); - this.error(error); - } - } - ] - }) - .catch(e => { - assert.equal(e, error); - }); - }); -}); - -describe('in-memory sourcemaps', () => { - it('generates an in-memory sourcemap', () => { - return rollup - .rollup({ - input: 'main', - plugins: [loader({ main: `console.log( 42 );` })] - }) - .then(bundle => { - return bundle.generate({ - format: 'cjs', - sourcemap: true, - sourcemapFile: path.resolve('bundle.js') - }); - }) - .then(generated => { - const smc = new SourceMapConsumer(generated.map); - const locator = getLocator(generated.code, { offsetLine: 1 }); - - const generatedLoc = locator('42'); - const loc = smc.originalPositionFor(generatedLoc); // 42 - assert.equal(loc.source, 'main'); - assert.equal(loc.line, 1); - assert.equal(loc.column, 13); - }); - }); -}); - -describe('deprecations', () => { - it('warns on options.entry, but handles', () => { - const warnings = []; - return rollup - .rollup({ - entry: 'x', - plugins: [loader({ x: `export default 42` })], - onwarn: warning => { - warnings.push(warning); - } - }) - .then(executeBundle) - .then(result => { - assert.equal(result, 42); - assert.deepEqual(warnings, [ - { - code: 'DEPRECATED_OPTIONS', - deprecations: [ - { - new: 'input', - old: 'entry' - } - ], - message: `The following options have been renamed — please update your config: entry -> input` - } - ]); - }); - }); - - it('adds deprecations correctly for rollup', () => { - const warnings = []; - return rollup - .rollup({ - entry: 'x', - format: 'cjs', - indent: true, - sourceMap: true, - plugins: [loader({ x: `export default 42` })], - onwarn: warning => { - warnings.push(warning); - } - }) - .then(executeBundle) - .then(result => { - assert.equal(result, 42); - const deprecations = warnings[0].deprecations; - assert.equal(deprecations.length, 4); - assert.deepEqual(deprecations, [ - { new: 'input', old: 'entry' }, - { new: 'output.indent', old: 'indent' }, - { new: 'output.sourcemap', old: 'sourceMap' }, - { new: 'output.format', old: 'format' } - ]); - }); - }); - - it('throws a useful error on accessing code/map properties of bundle.generate promise', () => { - return rollup - .rollup({ - input: 'x', - plugins: [loader({ x: `console.log( 42 );` })] - }) - .then(bundle => { - let errored = false; - - try { - const { code, map } = bundle.generate({ format: 'es' }); - console.log(code, map); - } catch (err) { - assert.equal( - err.message, - `bundle.generate(...) now returns a Promise instead of a { code, map } object` - ); - errored = true; - } - - assert.ok(errored); - }); - }); - - it('supports esm format alias', () => { - return rollup - .rollup({ input: 'x', plugins: [loader({ x: 'export const x = function () {}' })] }) - .then(bundle => bundle.generate({ format: 'esm' })) - .then(({ code }) => { - assert.equal(code, 'const x = function () {};\n\nexport { x };\n'); - }); - }); -}); - -describe('bundle.write()', () => { - it('fails without options or options.file', () => { - return rollup - .rollup({ - input: 'x', - plugins: [ - { - resolveId: () => { - return 'test'; - }, - load: () => { - return '// empty'; - } - } - ] - }) - .then(bundle => { - assert.throws(() => { - bundle.write(); - }, /You must specify output\.file/); - - assert.throws(() => { - bundle.write({}); - }, /You must specify output\.file/); - }); - }); - - it('expects output.name for IIFE and UMD bundles', () => { - let bundle; - - return rollup - .rollup({ - input: 'x', - plugins: [ - { - resolveId: () => { - return 'test'; - }, - load: () => { - return 'export var foo = 42;'; - } - } - ] - }) - .then(rollupInstance => { - bundle = rollupInstance; - return bundle.generate({ - format: 'umd' - }); - }) - .catch(err => { - assert.throws(() => { - throw err; - }, /You must supply output\.name for UMD bundles/); - }) - .then(() => { - return bundle.generate({ - format: 'iife' - }); - }) - .catch(err => { - assert.throws(() => { - throw err; - }, /You must supply output\.name for IIFE bundles/); - }); - }); - - it('throws on es6 format', () => { - return rollup - .rollup({ - input: 'x', - plugins: [ - { - resolveId: () => { - return 'test'; - }, - load: () => { - return '// empty'; - } - } - ] - }) - .then(bundle => { - assert.throws(() => { - return bundle.generate({ format: 'es6' }); - }, /The `es6` output format is deprecated – use `es` instead/); - }); - }); - - it('works when output options is an array', () => { - const warnings = []; - const options = { - input: 'x', - plugins: [loader({ x: `console.log( 42 );` })], - onwarn: warning => warnings.push(warning), - output: [ - { - format: 'cjs' - }, - { - format: 'es' - } - ] - }; - return rollup.rollup(options).then(bundle => { - assert.equal(warnings.length, 0, 'No warnings for UNKNOWN'); - assert.throws(() => { - return Promise.all(options.output.map(o => bundle.write(o))); - }, /You must specify output\.file/); - }); - }); -}); - -describe('acorn plugins', () => { - // Acorn registers plugins globally per process. The tests in this suite - // use unique plugin names to make sure each plugin is registered in its - // proper test rather than in a test that ran earlier. - - it('injects plugins passed in acornInjectPlugins', () => { - let pluginAInjected = false; - let pluginBInjected = false; - - return rollup - .rollup({ - input: 'x.js', - plugins: [loader({ 'x.js': `export default 42` })], - acornInjectPlugins: [ - function pluginA(acorn) { - pluginAInjected = true; - return acorn; - }, - function pluginB(acorn) { - pluginBInjected = true; - return acorn; - } - ] - }) - .then(executeBundle) - .then(result => { - assert.equal(result, 42); - assert( - pluginAInjected, - 'A plugin passed via acornInjectPlugins should inject itself into Acorn.' - ); - assert( - pluginBInjected, - 'A plugin passed via acornInjectPlugins should inject itself into Acorn.' - ); - }); - }); - - it('injected plugins are registered with Acorn only if acorn.plugins is set', () => { - let pluginCRegistered = false; - let pluginDRegistered = false; - - function pluginC(acorn) { - acorn.plugins.pluginC = () => (pluginCRegistered = true); - return acorn; - } - - function pluginD(acorn) { - acorn.plugins.pluginD = () => (pluginDRegistered = true); - return acorn; - } - - return rollup - .rollup({ - input: 'x.js', - plugins: [loader({ 'x.js': `export default 42` })], - acorn: { - plugins: { - pluginC: true - } - }, - acornInjectPlugins: [pluginC, pluginD] - }) - .then(executeBundle) - .then(result => { - assert.equal(result, 42); - assert.equal( - pluginCRegistered, - true, - 'A plugin enabled in acorn.plugins should register with Acorn.' - ); - assert.equal( - pluginDRegistered, - false, - 'A plugin not enabled in acorn.plugins should not register with Acorn.' - ); - }); - }); - - it('throws if acorn.plugins is set and acornInjectPlugins is missing', () => { - return rollup - .rollup({ - input: 'x.js', - plugins: [loader({ 'x.js': `export default 42` })], - acorn: { - plugins: { - pluginE: true - } - } - }) - .then(executeBundle) - .then(() => { - throw new Error('Missing expected error'); - }) - .catch(error => { - assert.equal(error.message, "Plugin 'pluginE' not found"); - }); - }); - - it('throws if acorn.plugins is set and acornInjectPlugins is empty', () => { - return rollup - .rollup({ - input: 'x.js', - plugins: [loader({ 'x.js': `export default 42` })], - acorn: { - plugins: { - pluginF: true - } - }, - acornInjectPlugins: [] - }) - .then(executeBundle) - .then(() => { - throw new Error('Missing expected error'); - }) - .catch(error => { - assert.equal(error.message, "Plugin 'pluginF' not found"); - }); - }); -}); - -describe('misc', () => { - it('warns if node builtins are unresolved in a non-CJS, non-ES bundle (#1051)', () => { - const warnings = []; - - return rollup - .rollup({ - input: 'input', - plugins: [ - loader({ - input: `import { format } from 'util';\nexport default format( 'this is a %s', 'formatted string' );` - }) - ], - onwarn: warning => warnings.push(warning) - }) - .then(bundle => - bundle.generate({ - format: 'iife', - name: 'myBundle' - }) - ) - .then(() => { - const relevantWarnings = warnings.filter( - warning => warning.code === 'MISSING_NODE_BUILTINS' - ); - assert.equal(relevantWarnings.length, 1); - assert.equal( - relevantWarnings[0].message, - `Creating a browser bundle that depends on Node.js built-in module ('util'). You might need to include https://www.npmjs.com/package/rollup-plugin-node-builtins` - ); - }); - }); - - it('warns when globals option is specified and a global module name is guessed in a UMD bundle (#2358)', () => { - const warnings = []; - - return rollup - .rollup({ - input: 'input', - plugins: [ - loader({ - input: `import * as _ from 'lodash'` - }) - ], - onwarn: warning => warnings.push(warning) - }) - .then(bundle => - bundle.generate({ - format: 'umd', - globals: [], - name: 'myBundle' - }) - ) - .then(() => { - const relevantWarnings = warnings.filter(warning => warning.code === 'MISSING_GLOBAL_NAME'); - assert.equal(relevantWarnings.length, 1); - assert.equal( - relevantWarnings[0].message, - `No name was provided for external module 'lodash' in output.globals – guessing 'lodash'` - ); - }); - }); - - it('ignores falsy plugins', () => { - return rollup.rollup({ - input: 'x', - plugins: [loader({ x: `console.log( 42 );` }), null, false, undefined] - }); - }); -}); +require('./acorn-plugins'); +require('./bundle-information'); +require('./deprecations'); +require('./in-memory-sourcemaps'); +require('./misc'); +require('./sanity-checks'); +require('./write-bundle'); diff --git a/test/misc/misc.js b/test/misc/misc.js new file mode 100644 index 00000000000..1f3d335773e --- /dev/null +++ b/test/misc/misc.js @@ -0,0 +1,73 @@ +const assert = require('assert'); +const rollup = require('../../dist/rollup'); +const { loader } = require('../utils.js'); + +describe('misc', () => { + it('warns if node builtins are unresolved in a non-CJS, non-ES bundle (#1051)', () => { + const warnings = []; + + return rollup + .rollup({ + input: 'input', + plugins: [ + loader({ + input: `import { format } from 'util';\nexport default format( 'this is a %s', 'formatted string' );` + }) + ], + onwarn: warning => warnings.push(warning) + }) + .then(bundle => + bundle.generate({ + format: 'iife', + name: 'myBundle' + }) + ) + .then(() => { + const relevantWarnings = warnings.filter( + warning => warning.code === 'MISSING_NODE_BUILTINS' + ); + assert.equal(relevantWarnings.length, 1); + assert.equal( + relevantWarnings[0].message, + `Creating a browser bundle that depends on Node.js built-in module ('util'). You might need to include https://www.npmjs.com/package/rollup-plugin-node-builtins` + ); + }); + }); + + it('warns when globals option is specified and a global module name is guessed in a UMD bundle (#2358)', () => { + const warnings = []; + + return rollup + .rollup({ + input: 'input', + plugins: [ + loader({ + input: `import * as _ from 'lodash'` + }) + ], + onwarn: warning => warnings.push(warning) + }) + .then(bundle => + bundle.generate({ + format: 'umd', + globals: [], + name: 'myBundle' + }) + ) + .then(() => { + const relevantWarnings = warnings.filter(warning => warning.code === 'MISSING_GLOBAL_NAME'); + assert.equal(relevantWarnings.length, 1); + assert.equal( + relevantWarnings[0].message, + `No name was provided for external module 'lodash' in output.globals – guessing 'lodash'` + ); + }); + }); + + it('ignores falsy plugins', () => { + return rollup.rollup({ + input: 'x', + plugins: [loader({ x: `console.log( 42 );` }), null, false, undefined] + }); + }); +}); diff --git a/test/misc/optionList.js b/test/misc/optionList.js index ef786cb1d18..4d6298aab5b 100644 --- a/test/misc/optionList.js +++ b/test/misc/optionList.js @@ -1,3 +1,3 @@ -exports.input = 'acorn, acornInjectPlugins, cache, chunkGroupingSize, context, entry, experimentalCacheExpiry, experimentalCodeSplitting, experimentalPreserveModules, experimentalTopLevelAwait, external, inlineDynamicImports, input, manualChunks, moduleContext, onwarn, optimizeChunks, perf, plugins, preferConst, preserveSymlinks, shimMissingExports, treeshake, watch'; -exports.flags = 'acorn, acornInjectPlugins, amd, assetFileNames, banner, c, cache, chunkFileNames, chunkGroupingSize, compact, config, context, dir, e, entry, entryFileNames, environment, esModule, experimentalCacheExpiry, experimentalCodeSplitting, experimentalPreserveModules, experimentalTopLevelAwait, exports, extend, external, f, file, footer, format, freeze, g, globals, h, i, indent, inlineDynamicImports, input, interop, intro, m, manualChunks, moduleContext, n, name, namespaceToStringTag, noConflict, o, onwarn, optimizeChunks, outro, paths, perf, plugins, preferConst, preserveSymlinks, shimMissingExports, silent, sourcemap, sourcemapExcludeSources, sourcemapFile, strict, treeshake, v, w, watch'; +exports.input = 'acorn, acornInjectPlugins, cache, chunkGroupingSize, context, entry, experimentalCacheExpiry, experimentalCodeSplitting, experimentalOptimizeChunks, experimentalPreserveModules, experimentalTopLevelAwait, external, inlineDynamicImports, input, manualChunks, moduleContext, onwarn, perf, plugins, preferConst, preserveSymlinks, shimMissingExports, treeshake, watch'; +exports.flags = 'acorn, acornInjectPlugins, amd, assetFileNames, banner, c, cache, chunkFileNames, chunkGroupingSize, compact, config, context, dir, e, entry, entryFileNames, environment, esModule, experimentalCacheExpiry, experimentalCodeSplitting, experimentalOptimizeChunks, experimentalPreserveModules, experimentalTopLevelAwait, exports, extend, external, f, file, footer, format, freeze, g, globals, h, i, indent, inlineDynamicImports, input, interop, intro, m, manualChunks, moduleContext, n, name, namespaceToStringTag, noConflict, o, onwarn, outro, paths, perf, plugins, preferConst, preserveSymlinks, shimMissingExports, silent, sourcemap, sourcemapExcludeSources, sourcemapFile, strict, treeshake, v, w, watch'; exports.output = 'amd, assetFileNames, banner, dir, chunkFileNames, compact, entryFileNames, esModule, exports, extend, file, footer, format, freeze, globals, indent, interop, intro, name, namespaceToStringTag, noConflict, outro, paths, sourcemap, sourcemapExcludeSources, sourcemapFile, sourcemapPathTransform, strict'; diff --git a/test/misc/sanity-checks.js b/test/misc/sanity-checks.js new file mode 100644 index 00000000000..5bab7c44483 --- /dev/null +++ b/test/misc/sanity-checks.js @@ -0,0 +1,159 @@ +const assert = require('assert'); +const rollup = require('../../dist/rollup'); +const { loader } = require('../utils.js'); + +describe('sanity checks', () => { + it('exists', () => { + assert.ok(!!rollup); + }); + + it('has a rollup method', () => { + assert.equal(typeof rollup.rollup, 'function'); + }); + + it('fails without options', () => { + return rollup + .rollup() + .then(() => { + throw new Error('Missing expected error'); + }) + .catch(err => { + assert.equal(err.message, 'You must supply an options object to rollup'); + }); + }); + + it('node API passes warning and default handler to custom onwarn function', () => { + let args = []; + return rollup + .rollup({ + entry: 'x', + plugins: [loader({ x: `console.log( 42 );` })], + onwarn(warning, onwarn) { + args = [warning, onwarn]; + } + }) + .then(() => { + assert.deepEqual(args[0], { + code: 'DEPRECATED_OPTIONS', + deprecations: [ + { + new: 'input', + old: 'entry' + } + ], + message: `The following options have been renamed — please update your config: entry -> input` + }); + assert.equal(typeof args[1], 'function'); + }); + }); + + it('fails without options.input', () => { + return rollup + .rollup({}) + .then(() => { + throw new Error('Missing expected error'); + }) + .catch(err => { + assert.equal(err.message, 'You must supply options.input to rollup'); + }); + }); + + it('fails with invalid keys', () => { + const warnings = []; + const onwarn = warning => warnings.push(warning); + return rollup + .rollup({ input: 'x', onwarn, plUgins: [], plugins: [loader({ x: `console.log( 42 );` })] }) + .then(() => { + assert.deepEqual(warnings, [ + { + code: 'UNKNOWN_OPTION', + message: + 'Unknown input option: plUgins. Allowed options: ' + require('./optionList').input + } + ]); + }); + }); + + it('treats Literals as leaf nodes, even if first literal encountered is null', () => { + // this test has to be up here, otherwise the bug doesn't have + // an opportunity to present itself + return rollup.rollup({ + input: 'x', + plugins: [loader({ x: `var a = null; a = 'a string';` })] + }); + }); + + it('includes a newline at the end of the bundle', () => { + return rollup + .rollup({ + input: 'x', + plugins: [loader({ x: `console.log( 42 );` })] + }) + .then(bundle => { + return bundle.generate({ format: 'iife' }); + }) + .then(({ code }) => { + assert.ok(code[code.length - 1] === '\n'); + }); + }); + + it('throws on missing output options', () => { + const warnings = []; + + return rollup + .rollup({ + input: 'x', + plugins: [loader({ x: `console.log( 42 );` })], + onwarn: warning => warnings.push(warning) + }) + .then(bundle => { + assert.throws(() => { + bundle.generate(); + }, /You must supply an options object/); + }); + }); + + it('throws on missing format option', () => { + const warnings = []; + + return rollup + .rollup({ + input: 'x', + plugins: [loader({ x: `console.log( 42 );` })], + onwarn: warning => warnings.push(warning) + }) + .then(bundle => { + assert.throws(() => { + bundle.generate({ file: 'x' }); + }, /You must specify output\.format, which can be one of 'amd', 'cjs', 'system', 'esm', 'iife' or 'umd'/); + }); + }); + + it('reuses existing error object', () => { + let error; + + class CustomError extends Error { + constructor(message, x) { + super(message); + this.prop = x.toUpperCase(); + } + } + + return rollup + .rollup({ + input: 'x', + plugins: [ + loader({ x: `console.log( 42 );` }), + { + transform(code) { + error = new CustomError('foo', 'bar'); + this.error(error); + } + } + ] + }) + .catch(e => { + assert.equal(e, error); + }); + }); +}); diff --git a/test/misc/write-bundle.js b/test/misc/write-bundle.js new file mode 100644 index 00000000000..64e3d3f0979 --- /dev/null +++ b/test/misc/write-bundle.js @@ -0,0 +1,116 @@ +const assert = require('assert'); +const rollup = require('../../dist/rollup'); +const { loader } = require('../utils.js'); + +describe('bundle.write()', () => { + it('fails without options or options.file', () => { + return rollup + .rollup({ + input: 'x', + plugins: [ + { + resolveId: () => { + return 'test'; + }, + load: () => { + return '// empty'; + } + } + ] + }) + .then(bundle => { + assert.throws(() => { + bundle.write(); + }, /You must specify output\.file/); + + assert.throws(() => { + bundle.write({}); + }, /You must specify output\.file/); + }); + }); + + it('expects output.name for IIFE and UMD bundles', () => { + let bundle; + + return rollup + .rollup({ + input: 'x', + plugins: [ + { + resolveId: () => { + return 'test'; + }, + load: () => { + return 'export var foo = 42;'; + } + } + ] + }) + .then(rollupInstance => { + bundle = rollupInstance; + return bundle.generate({ + format: 'umd' + }); + }) + .catch(err => { + assert.throws(() => { + throw err; + }, /You must supply output\.name for UMD bundles/); + }) + .then(() => { + return bundle.generate({ + format: 'iife' + }); + }) + .catch(err => { + assert.throws(() => { + throw err; + }, /You must supply output\.name for IIFE bundles/); + }); + }); + + it('throws on es6 format', () => { + return rollup + .rollup({ + input: 'x', + plugins: [ + { + resolveId: () => { + return 'test'; + }, + load: () => { + return '// empty'; + } + } + ] + }) + .then(bundle => { + assert.throws(() => { + return bundle.generate({ format: 'es6' }); + }, /The `es6` output format is deprecated – use `es` instead/); + }); + }); + + it('works when output options is an array', () => { + const warnings = []; + const options = { + input: 'x', + plugins: [loader({ x: `console.log( 42 );` })], + onwarn: warning => warnings.push(warning), + output: [ + { + format: 'cjs' + }, + { + format: 'es' + } + ] + }; + return rollup.rollup(options).then(bundle => { + assert.equal(warnings.length, 0, 'No warnings for UNKNOWN'); + assert.throws(() => { + return Promise.all(options.output.map(o => bundle.write(o))); + }, /You must specify output\.file/); + }); + }); +});