diff --git a/docs/999-big-list-of-options.md b/docs/999-big-list-of-options.md
index a0863c232bc..786902dfd3b 100755
--- a/docs/999-big-list-of-options.md
+++ b/docs/999-big-list-of-options.md
@@ -420,6 +420,8 @@ The pattern to use for chunks created from entry points. Pattern supports the fo
Forward slashes `/` can be used to place files in sub-directories. See also [`output.assetFileNames`](guide/en/#outputassetfilenames), [`output.chunkFileNames`](guide/en/#outputchunkfilenames).
+This pattern will also be used when using the [`preserveModules`](guide/en/#preservemodules) option. Note however that when preserving modules, hashes are not yet supported.
+
#### output.extend
Type: `boolean`
CLI: `--extend`/`--no-extend`
diff --git a/src/Chunk.ts b/src/Chunk.ts
index 7b80a01ffb0..ed864b92c8e 100644
--- a/src/Chunk.ts
+++ b/src/Chunk.ts
@@ -277,17 +277,27 @@ export default class Chunk {
generateIdPreserveModules(
preserveModulesRelativeDir: string,
+ options: OutputOptions,
existingNames: Record
): string {
const sanitizedId = sanitizeFileName(this.orderedModules[0].id);
- return makeUnique(
- normalize(
- isAbsolute(this.orderedModules[0].id)
- ? relative(preserveModulesRelativeDir, sanitizedId)
- : '_virtual/' + basename(sanitizedId)
- ),
- existingNames
- );
+
+ let path: string;
+ if (isAbsolute(this.orderedModules[0].id)) {
+ const name = renderNamePattern(
+ options.entryFileNames || '[name].js',
+ 'output.entryFileNames',
+ {
+ format: () => (options.format === 'es' ? 'esm' : (options.format as string)),
+ name: () => this.getChunkName()
+ }
+ );
+
+ path = relative(preserveModulesRelativeDir, `${dirname(sanitizedId)}/${name}`);
+ } else {
+ path = `_virtual/${basename(sanitizedId)}`;
+ }
+ return makeUnique(normalize(path), existingNames);
}
generateInternalExports(options: OutputOptions) {
diff --git a/src/utils/assignChunkIds.ts b/src/utils/assignChunkIds.ts
index 5ed2d58faaa..ae479ae4684 100644
--- a/src/utils/assignChunkIds.ts
+++ b/src/utils/assignChunkIds.ts
@@ -27,7 +27,7 @@ export function assignChunkIds(
if (outputOptions.file) {
chunk.id = basename(outputOptions.file);
} else if (inputOptions.preserveModules) {
- chunk.id = chunk.generateIdPreserveModules(inputBase, bundle);
+ chunk.id = chunk.generateIdPreserveModules(inputBase, outputOptions, bundle);
} else {
chunk.id = chunk.generateId(addons, outputOptions, bundle, true);
}
diff --git a/test/chunking-form/samples/preserve-modules-filename-pattern/_config.js b/test/chunking-form/samples/preserve-modules-filename-pattern/_config.js
new file mode 100644
index 00000000000..6ef707ebe57
--- /dev/null
+++ b/test/chunking-form/samples/preserve-modules-filename-pattern/_config.js
@@ -0,0 +1,10 @@
+module.exports = {
+ description: 'entryFileNames pattern supported in combination with preserveModules',
+ options: {
+ input: 'src/main.ts',
+ output: {
+ entryFileNames: 'entry-[name]-[format].js'
+ },
+ preserveModules: true
+ }
+};
diff --git a/test/chunking-form/samples/preserve-modules-filename-pattern/_expected/amd/entry-foo-amd.js b/test/chunking-form/samples/preserve-modules-filename-pattern/_expected/amd/entry-foo-amd.js
new file mode 100644
index 00000000000..47c3c10e378
--- /dev/null
+++ b/test/chunking-form/samples/preserve-modules-filename-pattern/_expected/amd/entry-foo-amd.js
@@ -0,0 +1,7 @@
+define(['exports'], function (exports) { 'use strict';
+
+ var foo = 42;
+
+ exports.default = foo;
+
+});
diff --git a/test/chunking-form/samples/preserve-modules-filename-pattern/_expected/amd/entry-main-amd.js b/test/chunking-form/samples/preserve-modules-filename-pattern/_expected/amd/entry-main-amd.js
new file mode 100644
index 00000000000..8164513e994
--- /dev/null
+++ b/test/chunking-form/samples/preserve-modules-filename-pattern/_expected/amd/entry-main-amd.js
@@ -0,0 +1,11 @@
+define(['exports', './entry-foo-amd', './nested/entry-bar-amd', './nested/entry-baz-amd'], function (exports, foo, bar, baz) { 'use strict';
+
+
+
+ exports.foo = foo.default;
+ exports.bar = bar.default;
+ exports.baz = baz.default;
+
+ Object.defineProperty(exports, '__esModule', { value: true });
+
+});
diff --git a/test/chunking-form/samples/preserve-modules-filename-pattern/_expected/amd/nested/entry-bar-amd.js b/test/chunking-form/samples/preserve-modules-filename-pattern/_expected/amd/nested/entry-bar-amd.js
new file mode 100644
index 00000000000..2325d908c80
--- /dev/null
+++ b/test/chunking-form/samples/preserve-modules-filename-pattern/_expected/amd/nested/entry-bar-amd.js
@@ -0,0 +1,7 @@
+define(['exports'], function (exports) { 'use strict';
+
+ var bar = 'banana';
+
+ exports.default = bar;
+
+});
diff --git a/test/chunking-form/samples/preserve-modules-filename-pattern/_expected/amd/nested/entry-baz-amd.js b/test/chunking-form/samples/preserve-modules-filename-pattern/_expected/amd/nested/entry-baz-amd.js
new file mode 100644
index 00000000000..e5b31b1c50c
--- /dev/null
+++ b/test/chunking-form/samples/preserve-modules-filename-pattern/_expected/amd/nested/entry-baz-amd.js
@@ -0,0 +1,7 @@
+define(['exports'], function (exports) { 'use strict';
+
+ var baz = 'whatever';
+
+ exports.default = baz;
+
+});
diff --git a/test/chunking-form/samples/preserve-modules-filename-pattern/_expected/cjs/entry-foo-cjs.js b/test/chunking-form/samples/preserve-modules-filename-pattern/_expected/cjs/entry-foo-cjs.js
new file mode 100644
index 00000000000..8eee837072f
--- /dev/null
+++ b/test/chunking-form/samples/preserve-modules-filename-pattern/_expected/cjs/entry-foo-cjs.js
@@ -0,0 +1,5 @@
+'use strict';
+
+var foo = 42;
+
+exports.default = foo;
diff --git a/test/chunking-form/samples/preserve-modules-filename-pattern/_expected/cjs/entry-main-cjs.js b/test/chunking-form/samples/preserve-modules-filename-pattern/_expected/cjs/entry-main-cjs.js
new file mode 100644
index 00000000000..5614f572fac
--- /dev/null
+++ b/test/chunking-form/samples/preserve-modules-filename-pattern/_expected/cjs/entry-main-cjs.js
@@ -0,0 +1,13 @@
+'use strict';
+
+Object.defineProperty(exports, '__esModule', { value: true });
+
+var foo = require('./entry-foo-cjs.js');
+var bar = require('./nested/entry-bar-cjs.js');
+var baz = require('./nested/entry-baz-cjs.js');
+
+
+
+exports.foo = foo.default;
+exports.bar = bar.default;
+exports.baz = baz.default;
diff --git a/test/chunking-form/samples/preserve-modules-filename-pattern/_expected/cjs/nested/entry-bar-cjs.js b/test/chunking-form/samples/preserve-modules-filename-pattern/_expected/cjs/nested/entry-bar-cjs.js
new file mode 100644
index 00000000000..779c3ce4618
--- /dev/null
+++ b/test/chunking-form/samples/preserve-modules-filename-pattern/_expected/cjs/nested/entry-bar-cjs.js
@@ -0,0 +1,5 @@
+'use strict';
+
+var bar = 'banana';
+
+exports.default = bar;
diff --git a/test/chunking-form/samples/preserve-modules-filename-pattern/_expected/cjs/nested/entry-baz-cjs.js b/test/chunking-form/samples/preserve-modules-filename-pattern/_expected/cjs/nested/entry-baz-cjs.js
new file mode 100644
index 00000000000..c6710344d5b
--- /dev/null
+++ b/test/chunking-form/samples/preserve-modules-filename-pattern/_expected/cjs/nested/entry-baz-cjs.js
@@ -0,0 +1,5 @@
+'use strict';
+
+var baz = 'whatever';
+
+exports.default = baz;
diff --git a/test/chunking-form/samples/preserve-modules-filename-pattern/_expected/es/entry-foo-esm.js b/test/chunking-form/samples/preserve-modules-filename-pattern/_expected/es/entry-foo-esm.js
new file mode 100644
index 00000000000..8ac2b2169a4
--- /dev/null
+++ b/test/chunking-form/samples/preserve-modules-filename-pattern/_expected/es/entry-foo-esm.js
@@ -0,0 +1,3 @@
+var foo = 42;
+
+export default foo;
diff --git a/test/chunking-form/samples/preserve-modules-filename-pattern/_expected/es/entry-main-esm.js b/test/chunking-form/samples/preserve-modules-filename-pattern/_expected/es/entry-main-esm.js
new file mode 100644
index 00000000000..d59ddf791ad
--- /dev/null
+++ b/test/chunking-form/samples/preserve-modules-filename-pattern/_expected/es/entry-main-esm.js
@@ -0,0 +1,3 @@
+export { default as foo } from './entry-foo-esm.js';
+export { default as bar } from './nested/entry-bar-esm.js';
+export { default as baz } from './nested/entry-baz-esm.js';
diff --git a/test/chunking-form/samples/preserve-modules-filename-pattern/_expected/es/nested/entry-bar-esm.js b/test/chunking-form/samples/preserve-modules-filename-pattern/_expected/es/nested/entry-bar-esm.js
new file mode 100644
index 00000000000..bbf65d4599d
--- /dev/null
+++ b/test/chunking-form/samples/preserve-modules-filename-pattern/_expected/es/nested/entry-bar-esm.js
@@ -0,0 +1,3 @@
+var bar = 'banana';
+
+export default bar;
diff --git a/test/chunking-form/samples/preserve-modules-filename-pattern/_expected/es/nested/entry-baz-esm.js b/test/chunking-form/samples/preserve-modules-filename-pattern/_expected/es/nested/entry-baz-esm.js
new file mode 100644
index 00000000000..03a3023d32b
--- /dev/null
+++ b/test/chunking-form/samples/preserve-modules-filename-pattern/_expected/es/nested/entry-baz-esm.js
@@ -0,0 +1,3 @@
+var baz = 'whatever';
+
+export default baz;
diff --git a/test/chunking-form/samples/preserve-modules-filename-pattern/_expected/system/entry-foo-system.js b/test/chunking-form/samples/preserve-modules-filename-pattern/_expected/system/entry-foo-system.js
new file mode 100644
index 00000000000..81b45b772a8
--- /dev/null
+++ b/test/chunking-form/samples/preserve-modules-filename-pattern/_expected/system/entry-foo-system.js
@@ -0,0 +1,10 @@
+System.register([], function (exports) {
+ 'use strict';
+ return {
+ execute: function () {
+
+ var foo = exports('default', 42);
+
+ }
+ };
+});
diff --git a/test/chunking-form/samples/preserve-modules-filename-pattern/_expected/system/entry-main-system.js b/test/chunking-form/samples/preserve-modules-filename-pattern/_expected/system/entry-main-system.js
new file mode 100644
index 00000000000..bf1071e0e79
--- /dev/null
+++ b/test/chunking-form/samples/preserve-modules-filename-pattern/_expected/system/entry-main-system.js
@@ -0,0 +1,17 @@
+System.register(['./entry-foo-system.js', './nested/entry-bar-system.js', './nested/entry-baz-system.js'], function (exports) {
+ 'use strict';
+ return {
+ setters: [function (module) {
+ exports('foo', module.default);
+ }, function (module) {
+ exports('bar', module.default);
+ }, function (module) {
+ exports('baz', module.default);
+ }],
+ execute: function () {
+
+
+
+ }
+ };
+});
diff --git a/test/chunking-form/samples/preserve-modules-filename-pattern/_expected/system/nested/entry-bar-system.js b/test/chunking-form/samples/preserve-modules-filename-pattern/_expected/system/nested/entry-bar-system.js
new file mode 100644
index 00000000000..5ef23f15879
--- /dev/null
+++ b/test/chunking-form/samples/preserve-modules-filename-pattern/_expected/system/nested/entry-bar-system.js
@@ -0,0 +1,10 @@
+System.register([], function (exports) {
+ 'use strict';
+ return {
+ execute: function () {
+
+ var bar = exports('default', 'banana');
+
+ }
+ };
+});
diff --git a/test/chunking-form/samples/preserve-modules-filename-pattern/_expected/system/nested/entry-baz-system.js b/test/chunking-form/samples/preserve-modules-filename-pattern/_expected/system/nested/entry-baz-system.js
new file mode 100644
index 00000000000..a0526b56624
--- /dev/null
+++ b/test/chunking-form/samples/preserve-modules-filename-pattern/_expected/system/nested/entry-baz-system.js
@@ -0,0 +1,10 @@
+System.register([], function (exports) {
+ 'use strict';
+ return {
+ execute: function () {
+
+ var baz = exports('default', 'whatever');
+
+ }
+ };
+});
diff --git a/test/chunking-form/samples/preserve-modules-filename-pattern/src/foo.ts b/test/chunking-form/samples/preserve-modules-filename-pattern/src/foo.ts
new file mode 100644
index 00000000000..7a4e8a723a4
--- /dev/null
+++ b/test/chunking-form/samples/preserve-modules-filename-pattern/src/foo.ts
@@ -0,0 +1 @@
+export default 42;
diff --git a/test/chunking-form/samples/preserve-modules-filename-pattern/src/main.ts b/test/chunking-form/samples/preserve-modules-filename-pattern/src/main.ts
new file mode 100644
index 00000000000..61e9cfcdb73
--- /dev/null
+++ b/test/chunking-form/samples/preserve-modules-filename-pattern/src/main.ts
@@ -0,0 +1,6 @@
+// @ts-ignore
+export { default as foo } from './foo.ts';
+// @ts-ignore
+export { default as bar } from './nested/bar.ts';
+// @ts-ignore
+export { default as baz } from './nested/baz.ts';
diff --git a/test/chunking-form/samples/preserve-modules-filename-pattern/src/nested/bar.ts b/test/chunking-form/samples/preserve-modules-filename-pattern/src/nested/bar.ts
new file mode 100644
index 00000000000..7d79d5a99a8
--- /dev/null
+++ b/test/chunking-form/samples/preserve-modules-filename-pattern/src/nested/bar.ts
@@ -0,0 +1 @@
+export default 'banana';
diff --git a/test/chunking-form/samples/preserve-modules-filename-pattern/src/nested/baz.ts b/test/chunking-form/samples/preserve-modules-filename-pattern/src/nested/baz.ts
new file mode 100644
index 00000000000..6d70feca8ec
--- /dev/null
+++ b/test/chunking-form/samples/preserve-modules-filename-pattern/src/nested/baz.ts
@@ -0,0 +1 @@
+export default 'whatever';