Skip to content

Commit

Permalink
adding output.devtoolNamespace option
Browse files Browse the repository at this point in the history
When loading multiple libraries built with webpack, you can run into
collisions of the sourcemap file paths. For examle, both have
"webpack:///src/index.js".

This change addresses the problem by introducing a new output option
`output.devtoolNamespace` which defaults to `output.library` when
not specified. The defaults moduleFilenameTemplates in all the
sourcemap plugins have been modified to start with:
"webpack://[namespace]/...", where [namespace] will be replaced by
the `output.devtoolNamespace`.

Notice that there are only two slashes following "webpack:" now.
This is to make it behave just as before when not building with a
namespace. When building with a namespace you only get the two
slashes, but from what I've seen the chrome dev tools only care
about the first 2 slashes anyways.

webpack#5767
  • Loading branch information
Stephan Badragan committed Oct 17, 2017
1 parent 168f923 commit 7d14c16
Show file tree
Hide file tree
Showing 6 changed files with 26 additions and 6 deletions.
2 changes: 1 addition & 1 deletion lib/EvalDevToolModuleTemplatePlugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const ModuleFilenameHelpers = require("./ModuleFilenameHelpers");
class EvalDevToolModuleTemplatePlugin {
constructor(sourceUrlComment, moduleFilenameTemplate) {
this.sourceUrlComment = sourceUrlComment || "\n//# sourceURL=[url]";
this.moduleFilenameTemplate = moduleFilenameTemplate || "webpack:///[resourcePath]?[loaders]";
this.moduleFilenameTemplate = moduleFilenameTemplate || "webpack://[namespace]/[resourcePath]?[loaders]";
}

apply(moduleTemplate) {
Expand Down
2 changes: 1 addition & 1 deletion lib/EvalSourceMapDevToolModuleTemplatePlugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class EvalSourceMapDevToolModuleTemplatePlugin {
constructor(compilation, options) {
this.compilation = compilation;
this.sourceMapComment = options.append || "//# sourceURL=[module]\n//# sourceMappingURL=[url]";
this.moduleFilenameTemplate = options.moduleFilenameTemplate || "webpack:///[resource-path]?[hash]";
this.moduleFilenameTemplate = options.moduleFilenameTemplate || "webpack://[namespace]/[resource-path]?[hash]";
this.options = options;
}

Expand Down
13 changes: 11 additions & 2 deletions lib/ModuleFilenameHelpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ ModuleFilenameHelpers.ID = "[id]";
ModuleFilenameHelpers.REGEXP_ID = /\[id\]/gi;
ModuleFilenameHelpers.HASH = "[hash]";
ModuleFilenameHelpers.REGEXP_HASH = /\[hash\]/gi;
ModuleFilenameHelpers.NAMESPACE = "[namespace]";
ModuleFilenameHelpers.REGEXP_NAMESPACE = /\[namespace\]/gi;

function getAfter(str, token) {
const idx = str.indexOf(token);
Expand Down Expand Up @@ -73,6 +75,7 @@ ModuleFilenameHelpers.createFilename = function createFilename(module, moduleFil
const allLoaders = getBefore(identifier, "!");
const query = getAfter(resource, "?");
const resourcePath = resource.substr(0, resource.length - query.length);
const namespace = this._moduleNamespace || "";
if(typeof moduleFilenameTemplate === "function") {
return moduleFilenameTemplate({
identifier: identifier,
Expand All @@ -83,7 +86,8 @@ ModuleFilenameHelpers.createFilename = function createFilename(module, moduleFil
allLoaders: allLoaders,
query: query,
moduleId: moduleId,
hash: hash
hash: hash,
namespace: namespace
});
}
return moduleFilenameTemplate
Expand All @@ -96,7 +100,8 @@ ModuleFilenameHelpers.createFilename = function createFilename(module, moduleFil
.replace(ModuleFilenameHelpers.REGEXP_LOADERS, loaders)
.replace(ModuleFilenameHelpers.REGEXP_QUERY, query)
.replace(ModuleFilenameHelpers.REGEXP_ID, moduleId)
.replace(ModuleFilenameHelpers.REGEXP_HASH, hash);
.replace(ModuleFilenameHelpers.REGEXP_HASH, hash)
.replace(ModuleFilenameHelpers.REGEXP_NAMESPACE, namespace);
};

ModuleFilenameHelpers.createFooter = function createFooter(module, requestShortener) {
Expand Down Expand Up @@ -160,3 +165,7 @@ ModuleFilenameHelpers.matchObject = function matchObject(obj, str) {
if(ModuleFilenameHelpers.matchPart(str, obj.exclude)) return false;
return true;
};

ModuleFilenameHelpers.setModuleNamespace = function setModuleNamespace(moduleNamespace) {
this._moduleNamespace = moduleNamespace;
};
4 changes: 2 additions & 2 deletions lib/SourceMapDevToolPlugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@ class SourceMapDevToolPlugin {
if(!options) options = {};
this.sourceMapFilename = options.filename;
this.sourceMappingURLComment = options.append === false ? false : options.append || "\n//# sourceMappingURL=[url]";
this.moduleFilenameTemplate = options.moduleFilenameTemplate || "webpack:///[resourcePath]";
this.fallbackModuleFilenameTemplate = options.fallbackModuleFilenameTemplate || "webpack:///[resourcePath]?[hash]";
this.moduleFilenameTemplate = options.moduleFilenameTemplate || "webpack://[namespace]/[resourcePath]";
this.fallbackModuleFilenameTemplate = options.fallbackModuleFilenameTemplate || "webpack://[namespace]/[resourcePath]?[hash]";
this.options = options;
}

Expand Down
7 changes: 7 additions & 0 deletions lib/WebpackOptionsApply.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ const FlagDependencyExportsPlugin = require("./FlagDependencyExportsPlugin");
const SizeLimitsPlugin = require("./performance/SizeLimitsPlugin");

const ResolverFactory = require("enhanced-resolve").ResolverFactory;
const ModuleFilenameHelpers = require("./ModuleFilenameHelpers");

class WebpackOptionsApply extends OptionsApply {
constructor() {
Expand Down Expand Up @@ -193,6 +194,12 @@ class WebpackOptionsApply extends OptionsApply {
ExternalsPlugin = require("./ExternalsPlugin");
compiler.apply(new ExternalsPlugin(options.output.libraryTarget, options.externals));
}

if(!options.output.devtoolNamespace) {
options.output.devtoolNamespace = options.output.library;
}
ModuleFilenameHelpers.setModuleNamespace(options.output.devtoolNamespace);

let noSources;
let legacy;
let modern;
Expand Down
4 changes: 4 additions & 0 deletions schemas/webpackOptionsSchema.json
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,10 @@
}
]
},
"devtoolNamespace": {
"description": "Module namespace to use when interpolating filename template string for the sources array in a generated SourceMap. Defaults to `output.library` if not set. It's useful for avoiding runtime collisions in sourcemaps from multiple webpack projects built as libraries.",
"type": "string"
},
"filename": {
"description": "Specifies the name of each output file on disk. You must **not** specify an absolute path here! The `output.path` option determines the location on disk the files are written to, filename is used solely for naming the individual files.",
"type": "string",
Expand Down

0 comments on commit 7d14c16

Please sign in to comment.