diff --git a/docs/999-big-list-of-options.md b/docs/999-big-list-of-options.md
index 4e8c7d97432..c56f112a454 100755
--- a/docs/999-big-list-of-options.md
+++ b/docs/999-big-list-of-options.md
@@ -1320,6 +1320,14 @@ Default: `false`
Generate `const` declarations for exports rather than `var` declarations.
+#### output.sanitizeFileName
+Type: `boolean | (string) => string`
+Default: `true`
+
+Set to `false` to disable all chunk name sanitizations (removal of `\0`, `?` and `*` characters).
+
+Alternatively set to a function to allow custom chunk name sanitization.
+
#### output.strict
Type: `boolean`
CLI: `--strict`/`--no-strict`
diff --git a/src/Chunk.ts b/src/Chunk.ts
index 0d79ffb1811..0ede0a52eb4 100644
--- a/src/Chunk.ts
+++ b/src/Chunk.ts
@@ -430,6 +430,14 @@ export default class Chunk {
);
}
+ sanitizeFileName (id: string) {
+ if (this.outputOptions.sanitizeFileName === false)
+ return id;
+ else if (typeof this.outputOptions.sanitizeFileName === 'function')
+ return this.outputOptions.sanitizeFileName(id);
+ return sanitizeFileName(id);
+ }
+
generateIdPreserveModules(
preserveModulesRelativeDir: string,
options: NormalizedOutputOptions,
@@ -437,7 +445,7 @@ export default class Chunk {
unsetOptions: Set
): string {
const id = this.orderedModules[0].id;
- const sanitizedId = sanitizeFileName(id);
+ const sanitizedId = this.sanitizeFileName(id);
let path: string;
if (isAbsolute(id)) {
const extension = extname(id);
@@ -501,7 +509,7 @@ export default class Chunk {
}
getChunkName(): string {
- return this.name || (this.name = sanitizeFileName(this.getFallbackChunkName()));
+ return this.name || (this.name = this.sanitizeFileName(this.getFallbackChunkName()));
}
getExportNames(): string[] {
@@ -816,7 +824,7 @@ export default class Chunk {
if (fileName) {
this.fileName = fileName;
} else {
- this.name = sanitizeFileName(name || getChunkNameFromModule(facadedModule));
+ this.name = this.sanitizeFileName(name || getChunkNameFromModule(facadedModule));
}
}
diff --git a/src/rollup/types.d.ts b/src/rollup/types.d.ts
index b9dda715aa8..efc06e77f57 100644
--- a/src/rollup/types.d.ts
+++ b/src/rollup/types.d.ts
@@ -693,6 +693,7 @@ export interface NormalizedOutputOptions {
preferConst: boolean;
preserveModules: boolean;
preserveModulesRoot: string | undefined;
+ sanitizeFileName: boolean | ((string) => string);
sourcemap: boolean | 'inline' | 'hidden';
sourcemapExcludeSources: boolean;
sourcemapFile: string | undefined;
diff --git a/src/utils/options/normalizeOutputOptions.ts b/src/utils/options/normalizeOutputOptions.ts
index 5cf14024e29..5218a1cc805 100644
--- a/src/utils/options/normalizeOutputOptions.ts
+++ b/src/utils/options/normalizeOutputOptions.ts
@@ -66,6 +66,7 @@ export function normalizeOutputOptions(
preferConst: (config.preferConst as boolean | undefined) || false,
preserveModules,
preserveModulesRoot: getPreserveModulesRoot(config),
+ sanitizeFileName: config.sanitizeFileName as NormalizedOutputOptions['sanitizeFileName'] ?? true,
sourcemap: (config.sourcemap as boolean | 'inline' | 'hidden' | undefined) || false,
sourcemapExcludeSources: (config.sourcemapExcludeSources as boolean | undefined) || false,
sourcemapFile: config.sourcemapFile as string | undefined,
diff --git a/src/utils/sanitizeFileName.ts b/src/utils/sanitizeFileName.ts
index 14ceb33e2d1..b38e8681ea9 100644
--- a/src/utils/sanitizeFileName.ts
+++ b/src/utils/sanitizeFileName.ts
@@ -1,8 +1,3 @@
export function sanitizeFileName(name: string): string {
- const match = /^[a-z]:/i.exec(name);
- const driveLetter = match ? match[0] : "";
-
- // A `:` is only allowed as part of a windows drive letter (ex: C:\foo)
- // Otherwise, avoid them because they can refer to NTFS alternate data streams.
- return driveLetter + name.substr(driveLetter.length).replace(/[\0?*:]/g, '_');
+ return name.replace(/[\0?*]/g, '_');
}
diff --git a/test/chunking-form/samples/sanitize-chunk-names/_config.js b/test/chunking-form/samples/sanitize-chunk-names/_config.js
index ef6faaae57c..66b25abfdbb 100644
--- a/test/chunking-form/samples/sanitize-chunk-names/_config.js
+++ b/test/chunking-form/samples/sanitize-chunk-names/_config.js
@@ -5,7 +5,7 @@ module.exports = {
plugins: [
{
options(options) {
- options.input = ['\0virtual:entry-1', '\0virtual:entry-2'];
+ options.input = ['\0virtual-entry-1', '\0virtual-entry-2'];
return options;
},
resolveId(id) {
diff --git a/test/chunking-form/samples/sanitize-chunk-names/_expected/amd/_virtual-entry-1.js b/test/chunking-form/samples/sanitize-chunk-names/_expected/amd/_virtual-entry-1.js
new file mode 100644
index 00000000000..23620df2e74
--- /dev/null
+++ b/test/chunking-form/samples/sanitize-chunk-names/_expected/amd/_virtual-entry-1.js
@@ -0,0 +1,7 @@
+define(function () { 'use strict';
+
+ var _virtualEntry1 = "\u0000virtual-entry-1";
+
+ return _virtualEntry1;
+
+});
diff --git a/test/chunking-form/samples/sanitize-chunk-names/_expected/amd/_virtual-entry-2.js b/test/chunking-form/samples/sanitize-chunk-names/_expected/amd/_virtual-entry-2.js
new file mode 100644
index 00000000000..17e375503d8
--- /dev/null
+++ b/test/chunking-form/samples/sanitize-chunk-names/_expected/amd/_virtual-entry-2.js
@@ -0,0 +1,7 @@
+define(function () { 'use strict';
+
+ var _virtualEntry2 = "\u0000virtual-entry-2";
+
+ return _virtualEntry2;
+
+});
diff --git a/test/chunking-form/samples/sanitize-chunk-names/_expected/amd/_virtual_entry-1.js b/test/chunking-form/samples/sanitize-chunk-names/_expected/amd/_virtual_entry-1.js
deleted file mode 100644
index f41ce27ab24..00000000000
--- a/test/chunking-form/samples/sanitize-chunk-names/_expected/amd/_virtual_entry-1.js
+++ /dev/null
@@ -1,7 +0,0 @@
-define(function () { 'use strict';
-
- var _virtual_entry1 = "\u0000virtual:entry-1";
-
- return _virtual_entry1;
-
-});
diff --git a/test/chunking-form/samples/sanitize-chunk-names/_expected/amd/_virtual_entry-2.js b/test/chunking-form/samples/sanitize-chunk-names/_expected/amd/_virtual_entry-2.js
deleted file mode 100644
index 5746e5e45e9..00000000000
--- a/test/chunking-form/samples/sanitize-chunk-names/_expected/amd/_virtual_entry-2.js
+++ /dev/null
@@ -1,7 +0,0 @@
-define(function () { 'use strict';
-
- var _virtual_entry2 = "\u0000virtual:entry-2";
-
- return _virtual_entry2;
-
-});
diff --git a/test/chunking-form/samples/sanitize-chunk-names/_expected/cjs/_virtual-entry-1.js b/test/chunking-form/samples/sanitize-chunk-names/_expected/cjs/_virtual-entry-1.js
new file mode 100644
index 00000000000..a234cb704b0
--- /dev/null
+++ b/test/chunking-form/samples/sanitize-chunk-names/_expected/cjs/_virtual-entry-1.js
@@ -0,0 +1,5 @@
+'use strict';
+
+var _virtualEntry1 = "\u0000virtual-entry-1";
+
+module.exports = _virtualEntry1;
diff --git a/test/chunking-form/samples/sanitize-chunk-names/_expected/cjs/_virtual-entry-2.js b/test/chunking-form/samples/sanitize-chunk-names/_expected/cjs/_virtual-entry-2.js
new file mode 100644
index 00000000000..5110d9276f1
--- /dev/null
+++ b/test/chunking-form/samples/sanitize-chunk-names/_expected/cjs/_virtual-entry-2.js
@@ -0,0 +1,5 @@
+'use strict';
+
+var _virtualEntry2 = "\u0000virtual-entry-2";
+
+module.exports = _virtualEntry2;
diff --git a/test/chunking-form/samples/sanitize-chunk-names/_expected/cjs/_virtual_entry-1.js b/test/chunking-form/samples/sanitize-chunk-names/_expected/cjs/_virtual_entry-1.js
deleted file mode 100644
index 437d8954ef4..00000000000
--- a/test/chunking-form/samples/sanitize-chunk-names/_expected/cjs/_virtual_entry-1.js
+++ /dev/null
@@ -1,5 +0,0 @@
-'use strict';
-
-var _virtual_entry1 = "\u0000virtual:entry-1";
-
-module.exports = _virtual_entry1;
diff --git a/test/chunking-form/samples/sanitize-chunk-names/_expected/cjs/_virtual_entry-2.js b/test/chunking-form/samples/sanitize-chunk-names/_expected/cjs/_virtual_entry-2.js
deleted file mode 100644
index d560356654a..00000000000
--- a/test/chunking-form/samples/sanitize-chunk-names/_expected/cjs/_virtual_entry-2.js
+++ /dev/null
@@ -1,5 +0,0 @@
-'use strict';
-
-var _virtual_entry2 = "\u0000virtual:entry-2";
-
-module.exports = _virtual_entry2;
diff --git a/test/chunking-form/samples/sanitize-chunk-names/_expected/es/_virtual-entry-1.js b/test/chunking-form/samples/sanitize-chunk-names/_expected/es/_virtual-entry-1.js
new file mode 100644
index 00000000000..822d3f7d317
--- /dev/null
+++ b/test/chunking-form/samples/sanitize-chunk-names/_expected/es/_virtual-entry-1.js
@@ -0,0 +1,3 @@
+var _virtualEntry1 = "\u0000virtual-entry-1";
+
+export default _virtualEntry1;
diff --git a/test/chunking-form/samples/sanitize-chunk-names/_expected/es/_virtual-entry-2.js b/test/chunking-form/samples/sanitize-chunk-names/_expected/es/_virtual-entry-2.js
new file mode 100644
index 00000000000..0e7995ff4b2
--- /dev/null
+++ b/test/chunking-form/samples/sanitize-chunk-names/_expected/es/_virtual-entry-2.js
@@ -0,0 +1,3 @@
+var _virtualEntry2 = "\u0000virtual-entry-2";
+
+export default _virtualEntry2;
diff --git a/test/chunking-form/samples/sanitize-chunk-names/_expected/es/_virtual_entry-1.js b/test/chunking-form/samples/sanitize-chunk-names/_expected/es/_virtual_entry-1.js
deleted file mode 100644
index 9fa2c9b2926..00000000000
--- a/test/chunking-form/samples/sanitize-chunk-names/_expected/es/_virtual_entry-1.js
+++ /dev/null
@@ -1,3 +0,0 @@
-var _virtual_entry1 = "\u0000virtual:entry-1";
-
-export default _virtual_entry1;
diff --git a/test/chunking-form/samples/sanitize-chunk-names/_expected/es/_virtual_entry-2.js b/test/chunking-form/samples/sanitize-chunk-names/_expected/es/_virtual_entry-2.js
deleted file mode 100644
index c228f2ab38b..00000000000
--- a/test/chunking-form/samples/sanitize-chunk-names/_expected/es/_virtual_entry-2.js
+++ /dev/null
@@ -1,3 +0,0 @@
-var _virtual_entry2 = "\u0000virtual:entry-2";
-
-export default _virtual_entry2;
diff --git a/test/chunking-form/samples/sanitize-chunk-names/_expected/system/_virtual_entry-1.js b/test/chunking-form/samples/sanitize-chunk-names/_expected/system/_virtual-entry-1.js
similarity index 60%
rename from test/chunking-form/samples/sanitize-chunk-names/_expected/system/_virtual_entry-1.js
rename to test/chunking-form/samples/sanitize-chunk-names/_expected/system/_virtual-entry-1.js
index 26aafc0c353..c8ebce7cbc9 100644
--- a/test/chunking-form/samples/sanitize-chunk-names/_expected/system/_virtual_entry-1.js
+++ b/test/chunking-form/samples/sanitize-chunk-names/_expected/system/_virtual-entry-1.js
@@ -3,7 +3,7 @@ System.register([], function (exports) {
return {
execute: function () {
- var _virtual_entry1 = exports('default', "\u0000virtual:entry-1");
+ var _virtualEntry1 = exports('default', "\u0000virtual-entry-1");
}
};
diff --git a/test/chunking-form/samples/sanitize-chunk-names/_expected/system/_virtual_entry-2.js b/test/chunking-form/samples/sanitize-chunk-names/_expected/system/_virtual-entry-2.js
similarity index 60%
rename from test/chunking-form/samples/sanitize-chunk-names/_expected/system/_virtual_entry-2.js
rename to test/chunking-form/samples/sanitize-chunk-names/_expected/system/_virtual-entry-2.js
index af4edfd003e..7d34ce4b2fb 100644
--- a/test/chunking-form/samples/sanitize-chunk-names/_expected/system/_virtual_entry-2.js
+++ b/test/chunking-form/samples/sanitize-chunk-names/_expected/system/_virtual-entry-2.js
@@ -3,7 +3,7 @@ System.register([], function (exports) {
return {
execute: function () {
- var _virtual_entry2 = exports('default', "\u0000virtual:entry-2");
+ var _virtualEntry2 = exports('default', "\u0000virtual-entry-2");
}
};
diff --git a/test/form/samples/no-sanitize/_config.js b/test/form/samples/no-sanitize/_config.js
new file mode 100644
index 00000000000..7bac20fc520
--- /dev/null
+++ b/test/form/samples/no-sanitize/_config.js
@@ -0,0 +1,6 @@
+module.exports = {
+ description: 'supports disabling sanitization',
+ options: {
+ sanitizeFileName: false
+ }
+};
diff --git a/test/form/samples/no-sanitize/_expected/amd.js b/test/form/samples/no-sanitize/_expected/amd.js
new file mode 100644
index 00000000000..3b864a9ba7a
--- /dev/null
+++ b/test/form/samples/no-sanitize/_expected/amd.js
@@ -0,0 +1,9 @@
+define(['?do-not-sanitize'], function (external) { 'use strict';
+
+ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
+
+ var external__default = /*#__PURE__*/_interopDefaultLegacy(external);
+
+ console.log(external__default['default']);
+
+});
diff --git a/test/form/samples/no-sanitize/_expected/cjs.js b/test/form/samples/no-sanitize/_expected/cjs.js
new file mode 100644
index 00000000000..ea81323c4d0
--- /dev/null
+++ b/test/form/samples/no-sanitize/_expected/cjs.js
@@ -0,0 +1,9 @@
+'use strict';
+
+var external = require('\0do-not-sanitize');
+
+function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
+
+var external__default = /*#__PURE__*/_interopDefaultLegacy(external);
+
+console.log(external__default['default']);
diff --git a/test/form/samples/no-sanitize/_expected/es.js b/test/form/samples/no-sanitize/_expected/es.js
new file mode 100644
index 00000000000..c1a1ed0868f
--- /dev/null
+++ b/test/form/samples/no-sanitize/_expected/es.js
@@ -0,0 +1,3 @@
+import external from '\0do-not-sanitize';
+
+console.log(external);
diff --git a/test/form/samples/no-sanitize/_expected/iife.js b/test/form/samples/no-sanitize/_expected/iife.js
new file mode 100644
index 00000000000..db1e304cd12
--- /dev/null
+++ b/test/form/samples/no-sanitize/_expected/iife.js
@@ -0,0 +1,10 @@
+(function (external) {
+ 'use strict';
+
+ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
+
+ var external__default = /*#__PURE__*/_interopDefaultLegacy(external);
+
+ console.log(external__default['default']);
+
+}(external));
diff --git a/test/form/samples/no-sanitize/_expected/system.js b/test/form/samples/no-sanitize/_expected/system.js
new file mode 100644
index 00000000000..c3693d2a84a
--- /dev/null
+++ b/test/form/samples/no-sanitize/_expected/system.js
@@ -0,0 +1,14 @@
+System.register(['\0do-not-sanitize'], function () {
+ 'use strict';
+ var external;
+ return {
+ setters: [function (module) {
+ external = module.default;
+ }],
+ execute: function () {
+
+ console.log(external);
+
+ }
+ };
+});
diff --git a/test/form/samples/no-sanitize/_expected/umd.js b/test/form/samples/no-sanitize/_expected/umd.js
new file mode 100644
index 00000000000..3c42d2a349e
--- /dev/null
+++ b/test/form/samples/no-sanitize/_expected/umd.js
@@ -0,0 +1,13 @@
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(require(':do-not-sanitize')) :
+ typeof define === 'function' && define.amd ? define([':do-not-sanitize'], factory) :
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.external));
+}(this, (function (external) { 'use strict';
+
+ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
+
+ var external__default = /*#__PURE__*/_interopDefaultLegacy(external);
+
+ console.log(external__default['default']);
+
+})));
diff --git a/test/form/samples/no-sanitize/main.js b/test/form/samples/no-sanitize/main.js
new file mode 100644
index 00000000000..647e6149f14
--- /dev/null
+++ b/test/form/samples/no-sanitize/main.js
@@ -0,0 +1,3 @@
+import external from ':do-not-sanitize';
+
+console.log(external);
\ No newline at end of file