Skip to content

Commit 310cf6c

Browse files
authored
Merge pull request webpack#7409 from ronanamsterdam/feature/webpack-options-compile-errors-warning
Issue webpack#7395: webpack import options comments warning propagation update
2 parents 949890a + f65a24d commit 310cf6c

File tree

11 files changed

+129
-15
lines changed

11 files changed

+129
-15
lines changed

lib/CommentCompilationWarning.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/*
2+
MIT License http://www.opensource.org/licenses/mit-license.php
3+
Author Tobias Koppers @sokra
4+
*/
5+
"use strict";
6+
7+
const WebpackError = require("./WebpackError");
8+
9+
class CommentCompilationWarning extends WebpackError {
10+
constructor(message, module, loc) {
11+
super(message);
12+
13+
this.name = "CommentCompilationWarning";
14+
15+
this.module = module;
16+
this.loc = loc;
17+
18+
Error.captureStackTrace(this, this.constructor);
19+
}
20+
}
21+
22+
module.exports = CommentCompilationWarning;

lib/Parser.js

Lines changed: 37 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
// Syntax: https://developer.mozilla.org/en/SpiderMonkey/Parser_API
88

99
const acorn = require("acorn-dynamic-import").default;
10-
const { Tapable, SyncBailHook } = require("tapable");
11-
const HookMap = require("tapable/lib/HookMap");
10+
const { Tapable, SyncBailHook, HookMap } = require("tapable");
11+
const util = require("util");
1212
const vm = require("vm");
1313
const BasicEvaluatedExpression = require("./BasicEvaluatedExpression");
1414
const StackedSetMap = require("./util/StackedSetMap");
@@ -31,6 +31,14 @@ const defaultParserOptions = {
3131
}
3232
};
3333

34+
// regexp to match at lease one "magic comment"
35+
const webpackCommentRegExp = new RegExp(/(^|\W)webpack[A-Z]{1,}[A-Za-z]{1,}:/);
36+
37+
const EMPTY_COMMENT_OPTIONS = {
38+
options: null,
39+
errors: null
40+
};
41+
3442
class Parser extends Tapable {
3543
constructor(options, sourceType = "auto") {
3644
super();
@@ -2060,20 +2068,27 @@ class Parser extends Tapable {
20602068
);
20612069
}
20622070

2063-
getCommentOptions(range) {
2071+
parseCommentOptions(range) {
20642072
const comments = this.getComments(range);
2065-
if (comments.length === 0) return null;
2066-
const options = comments.map(comment => {
2067-
try {
2068-
let val = vm.runInNewContext(
2069-
`(function(){return {${comment.value}};})()`
2070-
);
2071-
return val;
2072-
} catch (e) {
2073-
return {};
2073+
if (comments.length === 0) {
2074+
return EMPTY_COMMENT_OPTIONS;
2075+
}
2076+
let options = {};
2077+
let errors = [];
2078+
for (const comment of comments) {
2079+
const { value } = comment;
2080+
if (value && webpackCommentRegExp.test(value)) {
2081+
// try compile only if webpack options comment is present
2082+
try {
2083+
const val = vm.runInNewContext(`(function(){return {${value}};})()`);
2084+
Object.assign(options, val);
2085+
} catch (e) {
2086+
e.comment = comment;
2087+
errors.push(e);
2088+
}
20742089
}
2075-
});
2076-
return options.reduce((o, i) => Object.assign(o, i), {});
2090+
}
2091+
return { options, errors };
20772092
}
20782093

20792094
getNameForExpression(expression) {
@@ -2161,4 +2176,12 @@ class Parser extends Tapable {
21612176
}
21622177
}
21632178

2179+
// TODO remove in webpack 5
2180+
Object.defineProperty(Parser.prototype, "getCommentOptions", {
2181+
configurable: false,
2182+
value: util.deprecate(function(range) {
2183+
return this.parseCommentOptions(range).options;
2184+
}, "Parser.getCommentOptions: Use Parser.parseCommentOptions(range) instead")
2185+
});
2186+
21642187
module.exports = Parser;

lib/dependencies/ImportParserPlugin.js

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ const ImportDependenciesBlock = require("./ImportDependenciesBlock");
1010
const ImportEagerDependency = require("./ImportEagerDependency");
1111
const ContextDependencyHelpers = require("./ContextDependencyHelpers");
1212
const UnsupportedFeatureWarning = require("../UnsupportedFeatureWarning");
13+
const CommentCompilationWarning = require("../CommentCompilationWarning");
1314

1415
class ImportParserPlugin {
1516
constructor(options) {
@@ -32,7 +33,26 @@ class ImportParserPlugin {
3233
let exclude = null;
3334
const groupOptions = {};
3435

35-
const importOptions = parser.getCommentOptions(expr.range);
36+
const {
37+
options: importOptions,
38+
errors: commentErrors
39+
} = parser.parseCommentOptions(expr.range);
40+
41+
if (commentErrors) {
42+
for (const e of commentErrors) {
43+
const { comment } = e;
44+
parser.state.module.warnings.push(
45+
new CommentCompilationWarning(
46+
`Compilation error while processing magic comment(-s): /*${
47+
comment.value
48+
}*/: ${e.message}`,
49+
parser.state.module,
50+
comment.loc
51+
)
52+
);
53+
}
54+
}
55+
3656
if (importOptions) {
3757
if (typeof importOptions.webpackIgnore !== "undefined") {
3858
if (typeof importOptions.webpackIgnore !== "boolean") {
@@ -239,4 +259,5 @@ class ImportParserPlugin {
239259
});
240260
}
241261
}
262+
242263
module.exports = ImportParserPlugin;

test/__snapshots__/StatsTestCases.test.js.snap

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1007,6 +1007,28 @@ Entrypoint entry = entry.js
10071007
[2] ./modules/a.js 37 bytes [built]"
10081008
`;
10091009

1010+
exports[`StatsTestCases should print correct stats for import-with-invalid-options-comments 1`] = `
1011+
"Built at: Thu Jan 01 1970 00:00:00 GMT
1012+
[0] ./chunk-a.js 27 bytes {2} [built]
1013+
[1] ./chunk-b.js 27 bytes {3} [built]
1014+
[2] ./chunk-c.js 27 bytes {4} [built]
1015+
[3] ./chunk-d.js 27 bytes {5} [built]
1016+
[4] ./chunk.js 401 bytes {0} [built] [3 warnings]
1017+
[5] ./index.js 50 bytes {1} [built]
1018+
1019+
WARNING in ./chunk.js 4:11-77
1020+
Compilation error while processing magic comment(-s): /* webpack Prefetch: 0, webpackChunkName: \\"notGoingToCompile-c\\" */: Unexpected identifier
1021+
@ ./index.js 1:0-49
1022+
1023+
WARNING in ./chunk.js 5:11-38
1024+
Compilation error while processing magic comment(-s): /* webpackPrefetch: nope */: nope is not defined
1025+
@ ./index.js 1:0-49
1026+
1027+
WARNING in ./chunk.js 2:11-84
1028+
Compilation error while processing magic comment(-s): /* webpackPrefetch: true, webpackChunkName: notGoingToCompileChunkName */: notGoingToCompileChunkName is not defined
1029+
@ ./index.js 1:0-49"
1030+
`;
1031+
10101032
exports[`StatsTestCases should print correct stats for limit-chunk-count-plugin 1`] = `
10111033
"Hash: 3c127dca42ce1c13b8eae6c0ceac1aa3be512946a5969fc94d792cce5364503bf42779f704747e2d
10121034
Child 1 chunks:
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module.exports = "chunk-a";
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module.exports = "chunk-b";
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module.exports = "chunk-c";
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module.exports = "chunk-d";
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
export default function() {
2+
import(/* webpackPrefetch: true, webpackChunkName: notGoingToCompileChunkName */ "./chunk-a");
3+
import(/* webpackPrefetch: 0, webpackChunkName: "goingToCompileChunkName-b" */ "./chunk-b");
4+
import(/* webpack Prefetch: 0, webpackChunkName: "notGoingToCompile-c" */ "./chunk-c");
5+
import(/* webpackPrefetch: nope */ /* webpackChunkName: "yep" */ "./chunk-d");
6+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
import(/* webpackChunkName: "chunk" */ "./chunk");

0 commit comments

Comments
 (0)