mirror of https://github.com/webpack/webpack.git
refactor to simpler way of extracting options from comments
This commit is contained in:
parent
83aeea8c46
commit
180f5e541c
|
@ -4,11 +4,15 @@
|
|||
*/
|
||||
var acorn = require("acorn-dynamic-import").default;
|
||||
var Tapable = require("tapable");
|
||||
var json5 = require("json5");
|
||||
var BasicEvaluatedExpression = require("./BasicEvaluatedExpression");
|
||||
|
||||
function Parser(options) {
|
||||
Tapable.call(this);
|
||||
this.options = options;
|
||||
this.scope = undefined;
|
||||
this.state = undefined;
|
||||
this.comments = undefined;
|
||||
this.initializeEvaluating();
|
||||
}
|
||||
module.exports = Parser;
|
||||
|
@ -1187,16 +1191,19 @@ Parser.prototype.parse = function parse(source, initialState) {
|
|||
throw new Error("Source couldn't be parsed");
|
||||
var oldScope = this.scope;
|
||||
var oldState = this.state;
|
||||
var oldComments = this.comments;
|
||||
this.scope = {
|
||||
inTry: false,
|
||||
definitions: [],
|
||||
renames: {}
|
||||
};
|
||||
var state = this.state = initialState || {};
|
||||
this.comments = comments;
|
||||
if(this.applyPluginsBailResult("program", ast, comments) === undefined)
|
||||
this.walkStatements(ast.body);
|
||||
this.scope = oldScope;
|
||||
this.state = oldState;
|
||||
this.comments = oldComments;
|
||||
return state;
|
||||
};
|
||||
|
||||
|
@ -1216,3 +1223,20 @@ Parser.prototype.evaluate = function evaluate(source) {
|
|||
throw new Error("evaluate: Source is not a expression");
|
||||
return this.evaluateExpression(ast.body[0].expression);
|
||||
};
|
||||
|
||||
Parser.prototype.getComments = function getComments(range) {
|
||||
return this.comments.filter(comment => comment.range[0] >= range[0] && comment.range[1] <= range[1]);
|
||||
};
|
||||
|
||||
Parser.prototype.getCommentOptions = function getCommentOptions(range) {
|
||||
var comments = this.getComments(range);
|
||||
if(comments.length === 0) return null;
|
||||
var options = comments.map(comment => {
|
||||
try {
|
||||
return json5.parse(`{${comment.value}}`);
|
||||
} catch(e) {
|
||||
return {};
|
||||
}
|
||||
});
|
||||
return options.reduce((o, i) => Object.assign(o, i), {});
|
||||
};
|
||||
|
|
|
@ -15,47 +15,21 @@ class ImportParserPlugin {
|
|||
|
||||
apply(parser) {
|
||||
const options = this.options;
|
||||
let parsedComments, chunkNameAssignment;
|
||||
|
||||
parser.plugin("program", (ast, comments) => {
|
||||
parsedComments = comments;
|
||||
});
|
||||
|
||||
// use /* webpackChunkName = "chunkName" */ to specify a chunkName
|
||||
parser.plugin("evaluate AssignmentExpression", (assignment) => {
|
||||
if(assignment.left.name === "webpackChunkName") {
|
||||
chunkNameAssignment = assignment;
|
||||
}
|
||||
});
|
||||
|
||||
parser.plugin(["call System.import", "import-call"], (expr) => {
|
||||
if(expr.arguments.length !== 1)
|
||||
throw new Error("Incorrect number of arguments provided to 'import(module: string) -> Promise'.");
|
||||
|
||||
const param = parser.evaluateExpression(expr.arguments[0]);
|
||||
const exprEndPos = expr.end;
|
||||
const paramEndPos = expr.arguments[0].end;
|
||||
|
||||
let chunkName = null;
|
||||
|
||||
//check chunkName from comments
|
||||
if(parsedComments.length && exprEndPos - paramEndPos > "/*webpackChunkName=*/".length) {
|
||||
for(let i = 0; i < parsedComments.length; i++) {
|
||||
let comment = parsedComments[i];
|
||||
// should match the location and length
|
||||
if(comment.type === "Block" && comment.start >= paramEndPos && comment.end < exprEndPos) {
|
||||
chunkNameAssignment = null;
|
||||
parser.evaluate(comment.value);
|
||||
// expect an AssignmentExpression after evaluate
|
||||
if(chunkNameAssignment) {
|
||||
const chunkNameExpr = parser.evaluateExpression(chunkNameAssignment.right);
|
||||
if(chunkNameExpr.isString()) {
|
||||
chunkName = chunkNameExpr.string;
|
||||
} else {
|
||||
throw new Error(`\`webpackChunkName\` expected a String, but received: ${comment.value} .`);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
const importOptions = parser.getCommentOptions(expr.range);
|
||||
if(importOptions) {
|
||||
if(typeof importOptions.webpackChunkName !== "undefined") {
|
||||
if(typeof importOptions.webpackChunkName !== "string")
|
||||
throw new Error(`\`webpackChunkName\` expected a string, but received: ${importOptions.webpackChunkName}.`);
|
||||
chunkName = importOptions.webpackChunkName;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
"enhanced-resolve": "^3.0.0",
|
||||
"interpret": "^1.0.0",
|
||||
"json-loader": "^0.5.4",
|
||||
"json5": "^0.5.1",
|
||||
"loader-runner": "^2.3.0",
|
||||
"loader-utils": "^0.2.16",
|
||||
"memory-fs": "~0.4.1",
|
||||
|
|
|
@ -69,18 +69,20 @@ it("should handle empty named chunks when there is an error callback", function(
|
|||
sync = false;
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
it("should be able to use named chunks in import()", function(done) {
|
||||
var sync = false;
|
||||
import("./empty?import1-in-chunk1" /* webpackChunkName = "import-named-chunk-1" */).then(function(result){
|
||||
import("./empty?import2-in-chunk1" /* webpackChunkName = "import-named-chunk-1" */).then(function(result){
|
||||
import("./empty?import1-in-chunk1" /* webpackChunkName: "import-named-chunk-1" */).then(function(result){
|
||||
var i = 0;
|
||||
import("./empty?import2-in-chunk1" /* webpackChunkName: "import-named-chunk-1" */).then(function(result){
|
||||
sync.should.be.ok();
|
||||
if(i++ > 0) done();
|
||||
}).catch(function(err){
|
||||
done(err);
|
||||
});
|
||||
import("./empty?import3-in-chunk2" /* webpackChunkName = "import-named-chunk-2" */).then(function(result){
|
||||
import("./empty?import3-in-chunk2" /* webpackChunkName: "import-named-chunk-2" */).then(function(result){
|
||||
sync.should.not.be.ok();
|
||||
done();
|
||||
if(i++ > 0) done();
|
||||
}).catch(function(err){
|
||||
done(err);
|
||||
});
|
||||
|
@ -94,15 +96,17 @@ it("should be able to use named chunks in import()", function(done) {
|
|||
it("should be able to use named chunk in context import()", function(done) {
|
||||
var mpty = "mpty";
|
||||
var sync = false;
|
||||
import("./e" + mpty + "2" /* webpackChunkName = "context-named-chunk" */).then(function(result) {
|
||||
import("./e" + mpty + "3" /* webpackChunkName = "context-named-chunk" */).then(function(result){
|
||||
import("./e" + mpty + "2" /* webpackChunkName: "context-named-chunk" */).then(function(result) {
|
||||
var i = 0;
|
||||
import("./e" + mpty + "3" /* webpackChunkName: "context-named-chunk" */).then(function(result){
|
||||
sync.should.be.ok();
|
||||
if(i++ > 0) done();
|
||||
}).catch(function(err){
|
||||
done(err);
|
||||
});
|
||||
import("./e" + mpty + "4" /* webpackChunkName = "context-named-chunk-2" */).then(function(result){
|
||||
import("./e" + mpty + "4" /* webpackChunkName: "context-named-chunk-2" */).then(function(result){
|
||||
sync.should.not.be.ok();
|
||||
done();
|
||||
if(i++ > 0) done();
|
||||
}).catch(function(err){
|
||||
done(err);
|
||||
});
|
||||
|
|
|
@ -47,10 +47,14 @@ acorn@^3.0.4:
|
|||
version "3.3.0"
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a"
|
||||
|
||||
acorn@^4.0.3, acorn@^4.0.4:
|
||||
acorn@^4.0.3:
|
||||
version "4.0.11"
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-4.0.11.tgz#edcda3bd937e7556410d42ed5860f67399c794c0"
|
||||
|
||||
acorn@^5.0.0:
|
||||
version "5.0.3"
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.0.3.tgz#c460df08491463f028ccb82eab3730bf01087b3d"
|
||||
|
||||
agent-base@2:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-2.0.1.tgz#bd8f9e86a8eb221fffa07bd14befd55df142815e"
|
||||
|
@ -2102,7 +2106,7 @@ json3@3.3.2:
|
|||
version "3.3.2"
|
||||
resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.2.tgz#3c0434743df93e2f5c42aee7b19bcb483575f4e1"
|
||||
|
||||
json5@^0.5.0:
|
||||
json5@^0.5.0, json5@^0.5.1:
|
||||
version "0.5.1"
|
||||
resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821"
|
||||
|
||||
|
|
Loading…
Reference in New Issue