webpack/lib/dependencies/ImportParserPlugin.js

243 lines
6.7 KiB
JavaScript

/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
"use strict";
const ImportContextDependency = require("./ImportContextDependency");
const ImportWeakDependency = require("./ImportWeakDependency");
const ImportDependenciesBlock = require("./ImportDependenciesBlock");
const ImportEagerDependency = require("./ImportEagerDependency");
const ContextDependencyHelpers = require("./ContextDependencyHelpers");
const UnsupportedFeatureWarning = require("../UnsupportedFeatureWarning");
class ImportParserPlugin {
constructor(options) {
this.options = options;
}
apply(parser) {
parser.hooks.importCall.tap("ImportParserPlugin", 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]);
let chunkName = null;
let mode = "lazy";
let include = null;
let exclude = null;
const groupOptions = {};
const importOptions = parser.getCommentOptions(expr.range);
if (importOptions) {
if (typeof importOptions.webpackIgnore !== "undefined") {
if (typeof importOptions.webpackIgnore !== "boolean") {
parser.state.module.warnings.push(
new UnsupportedFeatureWarning(
parser.state.module,
`\`webpackIgnore\` expected a boolean, but received: ${
importOptions.webpackIgnore
}.`,
expr.loc
)
);
} else {
// Do not instrument `import()` is `webpackIgnore` is `true`
if (importOptions.webpackIgnore) {
return false;
}
}
}
if (typeof importOptions.webpackChunkName !== "undefined") {
if (typeof importOptions.webpackChunkName !== "string") {
parser.state.module.warnings.push(
new UnsupportedFeatureWarning(
parser.state.module,
`\`webpackChunkName\` expected a string, but received: ${
importOptions.webpackChunkName
}.`,
expr.loc
)
);
} else {
chunkName = importOptions.webpackChunkName;
}
}
if (typeof importOptions.webpackMode !== "undefined") {
if (typeof importOptions.webpackMode !== "string") {
parser.state.module.warnings.push(
new UnsupportedFeatureWarning(
parser.state.module,
`\`webpackMode\` expected a string, but received: ${
importOptions.webpackMode
}.`,
expr.loc
)
);
} else {
mode = importOptions.webpackMode;
}
}
if (typeof importOptions.webpackPrefetch !== "undefined") {
if (importOptions.webpackPrefetch === true) {
groupOptions.prefetchOrder = 0;
} else if (typeof importOptions.webpackPrefetch === "number") {
groupOptions.prefetchOrder = importOptions.webpackPrefetch;
} else {
parser.state.module.warnings.push(
new UnsupportedFeatureWarning(
parser.state.module,
`\`webpackPrefetch\` expected true or a number, but received: ${
importOptions.webpackPrefetch
}.`,
expr.loc
)
);
}
}
if (typeof importOptions.webpackPreload !== "undefined") {
if (importOptions.webpackPreload === true) {
groupOptions.preloadOrder = 0;
} else if (typeof importOptions.webpackPreload === "number") {
groupOptions.preloadOrder = importOptions.webpackPreload;
} else {
parser.state.module.warnings.push(
new UnsupportedFeatureWarning(
parser.state.module,
`\`webpackPreload\` expected true or a number, but received: ${
importOptions.webpackPreload
}.`,
expr.loc
)
);
}
}
if (typeof importOptions.webpackInclude !== "undefined") {
if (
!importOptions.webpackInclude ||
importOptions.webpackInclude.constructor.name !== "RegExp"
) {
parser.state.module.warnings.push(
new UnsupportedFeatureWarning(
parser.state.module,
`\`webpackInclude\` expected a regular expression, but received: ${
importOptions.webpackInclude
}.`,
expr.loc
)
);
} else {
include = new RegExp(importOptions.webpackInclude);
}
}
if (typeof importOptions.webpackExclude !== "undefined") {
if (
!importOptions.webpackExclude ||
importOptions.webpackExclude.constructor.name !== "RegExp"
) {
parser.state.module.warnings.push(
new UnsupportedFeatureWarning(
parser.state.module,
`\`webpackExclude\` expected a regular expression, but received: ${
importOptions.webpackExclude
}.`,
expr.loc
)
);
} else {
exclude = new RegExp(importOptions.webpackExclude);
}
}
}
if (param.isString()) {
if (mode !== "lazy" && mode !== "eager" && mode !== "weak") {
parser.state.module.warnings.push(
new UnsupportedFeatureWarning(
parser.state.module,
`\`webpackMode\` expected 'lazy', 'eager' or 'weak', but received: ${mode}.`,
expr.loc
)
);
}
if (mode === "eager") {
const dep = new ImportEagerDependency(
param.string,
parser.state.module,
expr.range
);
parser.state.current.addDependency(dep);
} else if (mode === "weak") {
const dep = new ImportWeakDependency(
param.string,
parser.state.module,
expr.range
);
parser.state.current.addDependency(dep);
} else {
const depBlock = new ImportDependenciesBlock(
param.string,
expr.range,
Object.assign(groupOptions, {
name: chunkName
}),
parser.state.module,
expr.loc,
parser.state.module
);
parser.state.current.addBlock(depBlock);
}
return true;
} else {
if (
mode !== "lazy" &&
mode !== "lazy-once" &&
mode !== "eager" &&
mode !== "weak"
) {
parser.state.module.warnings.push(
new UnsupportedFeatureWarning(
parser.state.module,
`\`webpackMode\` expected 'lazy', 'lazy-once', 'eager' or 'weak', but received: ${mode}.`,
expr.loc
)
);
mode = "lazy";
}
if (mode === "weak") {
mode = "async-weak";
}
const dep = ContextDependencyHelpers.create(
ImportContextDependency,
expr.range,
param,
expr,
this.options,
{
chunkName,
groupOptions,
include,
exclude,
mode,
namespaceObject: parser.state.module.buildMeta.strictHarmonyModule
? "strict"
: true
}
);
if (!dep) return;
dep.loc = expr.loc;
dep.optional = !!parser.scope.inTry;
parser.state.current.addDependency(dep);
return true;
}
});
}
}
module.exports = ImportParserPlugin;