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