/* 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"); const CommentCompilationWarning = require("../CommentCompilationWarning"); 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 { options: importOptions, errors: commentErrors } = parser.parseCommentOptions(expr.range); if (commentErrors) { for (const e of commentErrors) { const { comment } = e; parser.state.module.warnings.push( new CommentCompilationWarning( `Compilation error while processing magic comment(-s): /*${ comment.value }*/: ${e.message}`, parser.state.module, comment.loc ) ); } } if (importOptions) { if (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()` if `webpackIgnore` is `true` if (importOptions.webpackIgnore) { return false; } } } if (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 (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 (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 (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 (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 (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 }, parser ); if (!dep) return; dep.loc = expr.loc; dep.optional = !!parser.scope.inTry; parser.state.current.addDependency(dep); return true; } }); } } module.exports = ImportParserPlugin;