Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

adding output.devtoolNamespace option #5844

Merged
merged 6 commits into from
Nov 16, 2017
Merged

adding output.devtoolNamespace option #5844

merged 6 commits into from
Nov 16, 2017

Conversation

MagicDuck
Copy link
Contributor

What kind of change does this PR introduce?
feature

Did you add tests for your changes?
yes

If relevant, link to documentation update:

webpack/webpack.js.org#1653

Summary

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.

Discussed with sokra here:
#5767

Does this PR introduce a breaking change?

No

Other information

@jsf-clabot
Copy link

jsf-clabot commented Oct 17, 2017

CLA assistant check
All committers have signed the CLA.

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.

Discussed with sokra here:
webpack#5767
@@ -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;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't use static variables.

Instead pass the namespace to the createFilename method.

createFilename(module, options, requestShortener)

options: { namespace, moduleFilenameTemplate }

Also add a backward-compatibility layer when typeof options === "string"

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As it's now refactored to use options you can remove this method.

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

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pass namespace to the SourceMapDevtoolPlugin (next section) instead. Similar to devtoolModuleFilenameTemplate

@webpack-bot
Copy link
Contributor

@MagicDuck Thanks for your update.

I labeled the Pull Request so reviewers will review it again.

@sokra Please review the new changes.

@webpack-bot
Copy link
Contributor

Hi @MagicDuck.

Just a little hint from a friendly bot about the best practice when submitting pull requests:

Don't submit pull request from your own master branch. It's recommended to create a feature branch for the PR.

You don't have to change it for this PR, just make sure to follow this hint the next time you submit a PR.

@MagicDuck
Copy link
Contributor Author

I'll make it default to empty string in the webpack options defaulter to pass the tests.

@@ -14,7 +14,7 @@ class EvalDevToolModulePlugin {

apply(compiler) {
compiler.plugin("compilation", (compilation) => {
compilation.moduleTemplate.apply(new EvalDevToolModuleTemplatePlugin(this.sourceUrlComment, this.moduleFilenameTemplate));
compilation.moduleTemplate.apply(new EvalDevToolModuleTemplatePlugin(this.sourceUrlComment, this.moduleFilenameTemplate, compiler.options.output.devtoolNamespace));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

change the EvalDevToolModulePlugin constructor to EvalDevToolModulePlugin(options) with options including sourceUrlComment, moduleFilenameTemplate and namespace.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you guys have any standard for documenting what the options are?
There is no way to guess from seeing something like:

	constructor(options) {
		this.options = options;
	}

Should I add some jsdoc comments?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

or do you completely destructure all options in the constructor?

@@ -8,15 +8,19 @@ const RawSource = require("webpack-sources").RawSource;
const ModuleFilenameHelpers = require("./ModuleFilenameHelpers");

class EvalDevToolModuleTemplatePlugin {
constructor(sourceUrlComment, moduleFilenameTemplate) {
constructor(sourceUrlComment, moduleFilenameTemplate, namespace) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

constructor(options)

@@ -11,7 +11,8 @@ 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.namespace = compilation.options.output.devtoolNamespace;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add namespace to options

@@ -48,7 +50,17 @@ function asRegExp(test) {
return test;
}

ModuleFilenameHelpers.createFilename = function createFilename(module, moduleFilenameTemplate, requestShortener) {
ModuleFilenameHelpers.createFilename = function createFilename(module, options, requestShortener) {
let opts;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could do something like:

const opts = Object.assign({
  namespace: "",
  moduleFilenameTemplate: ""
}, typeof options === "object" ? options : { moduleFilenameTemplate: options });

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using Object.assign() can have weird consequences sometimes for your defaults:

Object.assign({foo: "default"}, {foo: undefined})  --> {foo: undefined}

Can we use extend lib instead? (https://www.npmjs.com/package/extend)

var extend = require("extend")
extend({foo: "default"}, {foo: undefined}) ---> {foo: "default"}

https://runkit.com/magicduck/59e8fd082fe1da001215d79f

opts = options;
} else {
opts = {
moduleFilenameTemplate: arguments[1],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general try to avoid using arguments.

@@ -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;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As it's now refactored to use options you can remove this method.

@@ -72,6 +72,7 @@ class SourceMapDevToolPlugin {
const sourceMappingURLComment = this.sourceMappingURLComment;
const moduleFilenameTemplate = this.moduleFilenameTemplate;
const fallbackModuleFilenameTemplate = this.fallbackModuleFilenameTemplate;
const namespace = compiler.options.output.devtoolNamespace;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't use compiler.options. The plugin could be used directly without using devtool.

Pass namespace via the options object in the constructor.

@@ -193,6 +193,11 @@ 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;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should not happen here. You can do this in WebpackOptionsDefaulter.

@MagicDuck
Copy link
Contributor Author

@sokra when you get a chance, let me know what approach I should follow regarding documenting and defaulting options (see my comments)

@webpack-bot
Copy link
Contributor

Thank you for your pull request! The most important CI builds succeeded, we’ll review the pull request soon.

@sokra sokra changed the base branch from master to next November 6, 2017 16:55
@sokra sokra closed this Nov 6, 2017
@sokra sokra reopened this Nov 6, 2017
@sokra sokra closed this Nov 16, 2017
@sokra sokra reopened this Nov 16, 2017
@sokra
Copy link
Member

sokra commented Nov 16, 2017

Thanks

@MagicDuck
Copy link
Contributor Author

Yay, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants