| 1 | /*
|
|---|
| 2 | MIT License http://www.opensource.org/licenses/mit-license.php
|
|---|
| 3 | Author Tobias Koppers @sokra
|
|---|
| 4 | */
|
|---|
| 5 |
|
|---|
| 6 | "use strict";
|
|---|
| 7 |
|
|---|
| 8 | const AsyncDependenciesBlock = require("../AsyncDependenciesBlock");
|
|---|
| 9 | const CommentCompilationWarning = require("../errors/CommentCompilationWarning");
|
|---|
| 10 | const UnsupportedFeatureWarning = require("../errors/UnsupportedFeatureWarning");
|
|---|
| 11 | const {
|
|---|
| 12 | VariableInfo,
|
|---|
| 13 | getImportAttributes
|
|---|
| 14 | } = require("../javascript/JavascriptParser");
|
|---|
| 15 | const traverseDestructuringAssignmentProperties = require("../util/traverseDestructuringAssignmentProperties");
|
|---|
| 16 | const ContextDependencyHelpers = require("./ContextDependencyHelpers");
|
|---|
| 17 | const { getNonOptionalPart } = require("./HarmonyImportDependency");
|
|---|
| 18 | const ImportContextDependency = require("./ImportContextDependency");
|
|---|
| 19 | const ImportDependency = require("./ImportDependency");
|
|---|
| 20 | const ImportEagerDependency = require("./ImportEagerDependency");
|
|---|
| 21 | const { createGetImportPhase } = require("./ImportPhase");
|
|---|
| 22 | const ImportWeakDependency = require("./ImportWeakDependency");
|
|---|
| 23 |
|
|---|
| 24 | /** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */
|
|---|
| 25 | /** @typedef {import("../ChunkGroup").RawChunkGroupOptions} RawChunkGroupOptions */
|
|---|
| 26 | /** @typedef {import("../ContextModule").ContextMode} ContextMode */
|
|---|
| 27 | /** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */
|
|---|
| 28 | /** @typedef {import("../Dependency").RawReferencedExports} RawReferencedExports */
|
|---|
| 29 | /** @typedef {import("../Module").BuildMeta} BuildMeta */
|
|---|
| 30 | /** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */
|
|---|
| 31 | /** @typedef {import("../javascript/JavascriptParser").ImportExpression} ImportExpression */
|
|---|
| 32 | /** @typedef {import("../javascript/JavascriptParser").Range} Range */
|
|---|
| 33 | /** @typedef {import("../javascript/JavascriptParser").JavascriptParserState} JavascriptParserState */
|
|---|
| 34 | /** @typedef {import("../javascript/JavascriptParser").Members} Members */
|
|---|
| 35 | /** @typedef {import("../javascript/JavascriptParser").MembersOptionals} MembersOptionals */
|
|---|
| 36 | /** @typedef {import("../javascript/JavascriptParser").ArrowFunctionExpression} ArrowFunctionExpression */
|
|---|
| 37 | /** @typedef {import("../javascript/JavascriptParser").FunctionExpression} FunctionExpression */
|
|---|
| 38 | /** @typedef {import("../javascript/JavascriptParser").Identifier} Identifier */
|
|---|
| 39 | /** @typedef {import("../javascript/JavascriptParser").ObjectPattern} ObjectPattern */
|
|---|
| 40 | /** @typedef {import("../javascript/JavascriptParser").CallExpression} CallExpression */
|
|---|
| 41 |
|
|---|
| 42 | /** @typedef {{ references: RawReferencedExports, expression: ImportExpression }} ImportSettings */
|
|---|
| 43 | /** @typedef {WeakMap<ImportExpression, RawReferencedExports>} State */
|
|---|
| 44 |
|
|---|
| 45 | /** @type {WeakMap<JavascriptParserState, State>} */
|
|---|
| 46 | const parserStateMap = new WeakMap();
|
|---|
| 47 | const dynamicImportTag = Symbol("import()");
|
|---|
| 48 |
|
|---|
| 49 | /**
|
|---|
| 50 | * Returns import parser plugin state.
|
|---|
| 51 | * @param {JavascriptParser} parser javascript parser
|
|---|
| 52 | * @returns {State} import parser plugin state
|
|---|
| 53 | */
|
|---|
| 54 | function getState(parser) {
|
|---|
| 55 | if (!parserStateMap.has(parser.state)) {
|
|---|
| 56 | parserStateMap.set(parser.state, new WeakMap());
|
|---|
| 57 | }
|
|---|
| 58 | return /** @type {State} */ (parserStateMap.get(parser.state));
|
|---|
| 59 | }
|
|---|
| 60 |
|
|---|
| 61 | /**
|
|---|
| 62 | * Tag dynamic import referenced.
|
|---|
| 63 | * @param {JavascriptParser} parser javascript parser
|
|---|
| 64 | * @param {ImportExpression} importCall import expression
|
|---|
| 65 | * @param {string} variableName variable name
|
|---|
| 66 | */
|
|---|
| 67 | function tagDynamicImportReferenced(parser, importCall, variableName) {
|
|---|
| 68 | const state = getState(parser);
|
|---|
| 69 | /** @type {RawReferencedExports} */
|
|---|
| 70 | const references = state.get(importCall) || [];
|
|---|
| 71 | state.set(importCall, references);
|
|---|
| 72 | parser.tagVariable(
|
|---|
| 73 | variableName,
|
|---|
| 74 | dynamicImportTag,
|
|---|
| 75 | /** @type {ImportSettings} */ ({
|
|---|
| 76 | references,
|
|---|
| 77 | expression: importCall
|
|---|
| 78 | })
|
|---|
| 79 | );
|
|---|
| 80 | }
|
|---|
| 81 |
|
|---|
| 82 | /**
|
|---|
| 83 | * Gets fulfilled callback namespace obj.
|
|---|
| 84 | * @param {CallExpression} importThen import().then() call
|
|---|
| 85 | * @returns {Identifier | ObjectPattern | undefined} the dynamic imported namespace obj
|
|---|
| 86 | */
|
|---|
| 87 | function getFulfilledCallbackNamespaceObj(importThen) {
|
|---|
| 88 | const fulfilledCallback = importThen.arguments[0];
|
|---|
| 89 | if (
|
|---|
| 90 | fulfilledCallback &&
|
|---|
| 91 | (fulfilledCallback.type === "ArrowFunctionExpression" ||
|
|---|
| 92 | fulfilledCallback.type === "FunctionExpression") &&
|
|---|
| 93 | fulfilledCallback.params[0] &&
|
|---|
| 94 | (fulfilledCallback.params[0].type === "Identifier" ||
|
|---|
| 95 | fulfilledCallback.params[0].type === "ObjectPattern")
|
|---|
| 96 | ) {
|
|---|
| 97 | return fulfilledCallback.params[0];
|
|---|
| 98 | }
|
|---|
| 99 | }
|
|---|
| 100 |
|
|---|
| 101 | /**
|
|---|
| 102 | * Walk import then fulfilled callback.
|
|---|
| 103 | * @param {JavascriptParser} parser javascript parser
|
|---|
| 104 | * @param {ImportExpression} importCall import expression
|
|---|
| 105 | * @param {ArrowFunctionExpression | FunctionExpression} fulfilledCallback the fulfilled callback
|
|---|
| 106 | * @param {Identifier | ObjectPattern} namespaceObjArg the argument of namespace object=
|
|---|
| 107 | */
|
|---|
| 108 | function walkImportThenFulfilledCallback(
|
|---|
| 109 | parser,
|
|---|
| 110 | importCall,
|
|---|
| 111 | fulfilledCallback,
|
|---|
| 112 | namespaceObjArg
|
|---|
| 113 | ) {
|
|---|
| 114 | const arrow = fulfilledCallback.type === "ArrowFunctionExpression";
|
|---|
| 115 | const wasTopLevel = parser.scope.topLevelScope;
|
|---|
| 116 | parser.scope.topLevelScope = arrow ? (wasTopLevel ? "arrow" : false) : false;
|
|---|
| 117 | const scopeParams = [...fulfilledCallback.params];
|
|---|
| 118 |
|
|---|
| 119 | // Add function name in scope for recursive calls
|
|---|
| 120 | if (!arrow && fulfilledCallback.id) {
|
|---|
| 121 | scopeParams.push(fulfilledCallback.id);
|
|---|
| 122 | }
|
|---|
| 123 |
|
|---|
| 124 | parser.inFunctionScope(!arrow, scopeParams, () => {
|
|---|
| 125 | if (namespaceObjArg.type === "Identifier") {
|
|---|
| 126 | tagDynamicImportReferenced(parser, importCall, namespaceObjArg.name);
|
|---|
| 127 | } else {
|
|---|
| 128 | parser.enterDestructuringAssignment(namespaceObjArg, importCall);
|
|---|
| 129 | const referencedPropertiesInDestructuring =
|
|---|
| 130 | parser.destructuringAssignmentPropertiesFor(importCall);
|
|---|
| 131 | if (referencedPropertiesInDestructuring) {
|
|---|
| 132 | const state = getState(parser);
|
|---|
| 133 | const references = /** @type {RawReferencedExports} */ (
|
|---|
| 134 | state.get(importCall)
|
|---|
| 135 | );
|
|---|
| 136 | /** @type {RawReferencedExports} */
|
|---|
| 137 | const refsInDestructuring = [];
|
|---|
| 138 | traverseDestructuringAssignmentProperties(
|
|---|
| 139 | referencedPropertiesInDestructuring,
|
|---|
| 140 | (stack) => refsInDestructuring.push(stack.map((p) => p.id))
|
|---|
| 141 | );
|
|---|
| 142 | for (const ids of refsInDestructuring) {
|
|---|
| 143 | references.push(ids);
|
|---|
| 144 | }
|
|---|
| 145 | }
|
|---|
| 146 | }
|
|---|
| 147 | for (const param of fulfilledCallback.params) {
|
|---|
| 148 | parser.walkPattern(param);
|
|---|
| 149 | }
|
|---|
| 150 | if (fulfilledCallback.body.type === "BlockStatement") {
|
|---|
| 151 | parser.detectMode(fulfilledCallback.body.body);
|
|---|
| 152 | const prev = parser.prevStatement;
|
|---|
| 153 | parser.preWalkStatement(fulfilledCallback.body);
|
|---|
| 154 | parser.prevStatement = prev;
|
|---|
| 155 | parser.walkStatement(fulfilledCallback.body);
|
|---|
| 156 | } else {
|
|---|
| 157 | parser.walkExpression(fulfilledCallback.body);
|
|---|
| 158 | }
|
|---|
| 159 | });
|
|---|
| 160 | parser.scope.topLevelScope = wasTopLevel;
|
|---|
| 161 | }
|
|---|
| 162 |
|
|---|
| 163 | /**
|
|---|
| 164 | * Exports from enumerable.
|
|---|
| 165 | * @template T
|
|---|
| 166 | * @param {Iterable<T>} enumerable enumerable
|
|---|
| 167 | * @returns {T[][]} array of array
|
|---|
| 168 | */
|
|---|
| 169 | const exportsFromEnumerable = (enumerable) =>
|
|---|
| 170 | Array.from(enumerable, (e) => [e]);
|
|---|
| 171 |
|
|---|
| 172 | const PLUGIN_NAME = "ImportParserPlugin";
|
|---|
| 173 |
|
|---|
| 174 | class ImportParserPlugin {
|
|---|
| 175 | /**
|
|---|
| 176 | * Creates an instance of ImportParserPlugin.
|
|---|
| 177 | * @param {JavascriptParserOptions} options options
|
|---|
| 178 | */
|
|---|
| 179 | constructor(options) {
|
|---|
| 180 | this.options = options;
|
|---|
| 181 | }
|
|---|
| 182 |
|
|---|
| 183 | /**
|
|---|
| 184 | * Applies the plugin by registering its hooks on the compiler.
|
|---|
| 185 | * @param {JavascriptParser} parser the parser
|
|---|
| 186 | * @returns {void}
|
|---|
| 187 | */
|
|---|
| 188 | apply(parser) {
|
|---|
| 189 | parser.hooks.collectDestructuringAssignmentProperties.tap(
|
|---|
| 190 | PLUGIN_NAME,
|
|---|
| 191 | (expr) => {
|
|---|
| 192 | if (expr.type === "ImportExpression") return true;
|
|---|
| 193 | const nameInfo = parser.getNameForExpression(expr);
|
|---|
| 194 | if (
|
|---|
| 195 | nameInfo &&
|
|---|
| 196 | nameInfo.rootInfo instanceof VariableInfo &&
|
|---|
| 197 | nameInfo.rootInfo.name &&
|
|---|
| 198 | parser.getTagData(nameInfo.rootInfo.name, dynamicImportTag)
|
|---|
| 199 | ) {
|
|---|
| 200 | return true;
|
|---|
| 201 | }
|
|---|
| 202 | }
|
|---|
| 203 | );
|
|---|
| 204 | parser.hooks.preDeclarator.tap(PLUGIN_NAME, (decl) => {
|
|---|
| 205 | if (
|
|---|
| 206 | decl.init &&
|
|---|
| 207 | decl.init.type === "AwaitExpression" &&
|
|---|
| 208 | decl.init.argument.type === "ImportExpression" &&
|
|---|
| 209 | decl.id.type === "Identifier"
|
|---|
| 210 | ) {
|
|---|
| 211 | parser.defineVariable(decl.id.name);
|
|---|
| 212 | tagDynamicImportReferenced(parser, decl.init.argument, decl.id.name);
|
|---|
| 213 | }
|
|---|
| 214 | });
|
|---|
| 215 | parser.hooks.expression.for(dynamicImportTag).tap(PLUGIN_NAME, (expr) => {
|
|---|
| 216 | const settings = /** @type {ImportSettings} */ (parser.currentTagData);
|
|---|
| 217 | const referencedPropertiesInDestructuring =
|
|---|
| 218 | parser.destructuringAssignmentPropertiesFor(expr);
|
|---|
| 219 | if (referencedPropertiesInDestructuring) {
|
|---|
| 220 | /** @type {RawReferencedExports} */
|
|---|
| 221 | const refsInDestructuring = [];
|
|---|
| 222 | traverseDestructuringAssignmentProperties(
|
|---|
| 223 | referencedPropertiesInDestructuring,
|
|---|
| 224 | (stack) => refsInDestructuring.push(stack.map((p) => p.id))
|
|---|
| 225 | );
|
|---|
| 226 | for (const ids of refsInDestructuring) {
|
|---|
| 227 | settings.references.push(ids);
|
|---|
| 228 | }
|
|---|
| 229 | } else {
|
|---|
| 230 | settings.references.push([]);
|
|---|
| 231 | }
|
|---|
| 232 | return true;
|
|---|
| 233 | });
|
|---|
| 234 | parser.hooks.expressionMemberChain
|
|---|
| 235 | .for(dynamicImportTag)
|
|---|
| 236 | .tap(PLUGIN_NAME, (_expression, members, membersOptionals) => {
|
|---|
| 237 | const settings = /** @type {ImportSettings} */ (parser.currentTagData);
|
|---|
| 238 | const ids = getNonOptionalPart(members, membersOptionals);
|
|---|
| 239 | settings.references.push(ids);
|
|---|
| 240 | return true;
|
|---|
| 241 | });
|
|---|
| 242 | parser.hooks.callMemberChain
|
|---|
| 243 | .for(dynamicImportTag)
|
|---|
| 244 | .tap(PLUGIN_NAME, (expression, members, membersOptionals) => {
|
|---|
| 245 | const { arguments: args } = expression;
|
|---|
| 246 | const settings = /** @type {ImportSettings} */ (parser.currentTagData);
|
|---|
| 247 | let ids = getNonOptionalPart(members, membersOptionals);
|
|---|
| 248 | const directImport = members.length === 0;
|
|---|
| 249 | if (
|
|---|
| 250 | !directImport &&
|
|---|
| 251 | (this.options.strictThisContextOnImports || ids.length > 1)
|
|---|
| 252 | ) {
|
|---|
| 253 | ids = ids.slice(0, -1);
|
|---|
| 254 | }
|
|---|
| 255 | settings.references.push(ids);
|
|---|
| 256 | if (args) parser.walkExpressions(args);
|
|---|
| 257 | return true;
|
|---|
| 258 | });
|
|---|
| 259 | parser.hooks.importCall.tap(PLUGIN_NAME, (expr, importThen) => {
|
|---|
| 260 | const param = parser.evaluateExpression(expr.source);
|
|---|
| 261 |
|
|---|
| 262 | /** @type {null | string} */
|
|---|
| 263 | let chunkName = null;
|
|---|
| 264 | let mode = /** @type {ContextMode} */ (this.options.dynamicImportMode);
|
|---|
| 265 | /** @type {null | RegExp} */
|
|---|
| 266 | let include = null;
|
|---|
| 267 | /** @type {null | RegExp} */
|
|---|
| 268 | let exclude = null;
|
|---|
| 269 | /** @type {null | RawReferencedExports} */
|
|---|
| 270 | let exports = null;
|
|---|
| 271 | /** @type {RawChunkGroupOptions} */
|
|---|
| 272 | const groupOptions = {};
|
|---|
| 273 |
|
|---|
| 274 | const {
|
|---|
| 275 | dynamicImportPreload,
|
|---|
| 276 | dynamicImportPrefetch,
|
|---|
| 277 | dynamicImportFetchPriority
|
|---|
| 278 | } = this.options;
|
|---|
| 279 | if (
|
|---|
| 280 | dynamicImportPreload !== undefined &&
|
|---|
| 281 | dynamicImportPreload !== false
|
|---|
| 282 | ) {
|
|---|
| 283 | groupOptions.preloadOrder =
|
|---|
| 284 | dynamicImportPreload === true ? 0 : dynamicImportPreload;
|
|---|
| 285 | }
|
|---|
| 286 | if (
|
|---|
| 287 | dynamicImportPrefetch !== undefined &&
|
|---|
| 288 | dynamicImportPrefetch !== false
|
|---|
| 289 | ) {
|
|---|
| 290 | groupOptions.prefetchOrder =
|
|---|
| 291 | dynamicImportPrefetch === true ? 0 : dynamicImportPrefetch;
|
|---|
| 292 | }
|
|---|
| 293 | if (
|
|---|
| 294 | dynamicImportFetchPriority !== undefined &&
|
|---|
| 295 | dynamicImportFetchPriority !== false
|
|---|
| 296 | ) {
|
|---|
| 297 | groupOptions.fetchPriority = dynamicImportFetchPriority;
|
|---|
| 298 | }
|
|---|
| 299 |
|
|---|
| 300 | const { options: importOptions, errors: commentErrors } =
|
|---|
| 301 | parser.parseCommentOptions(/** @type {Range} */ (expr.range));
|
|---|
| 302 |
|
|---|
| 303 | if (commentErrors) {
|
|---|
| 304 | for (const e of commentErrors) {
|
|---|
| 305 | const { comment } = e;
|
|---|
| 306 | parser.state.module.addWarning(
|
|---|
| 307 | new CommentCompilationWarning(
|
|---|
| 308 | `Compilation error while processing magic comment(-s): /*${comment.value}*/: ${e.message}`,
|
|---|
| 309 | /** @type {DependencyLocation} */ (comment.loc)
|
|---|
| 310 | )
|
|---|
| 311 | );
|
|---|
| 312 | }
|
|---|
| 313 | }
|
|---|
| 314 |
|
|---|
| 315 | const phase = createGetImportPhase(
|
|---|
| 316 | this.options.deferImport,
|
|---|
| 317 | this.options.sourceImport
|
|---|
| 318 | )(parser, expr, () => importOptions);
|
|---|
| 319 |
|
|---|
| 320 | if (importOptions) {
|
|---|
| 321 | if (importOptions.webpackIgnore !== undefined) {
|
|---|
| 322 | if (typeof importOptions.webpackIgnore !== "boolean") {
|
|---|
| 323 | parser.state.module.addWarning(
|
|---|
| 324 | new UnsupportedFeatureWarning(
|
|---|
| 325 | `\`webpackIgnore\` expected a boolean, but received: ${importOptions.webpackIgnore}.`,
|
|---|
| 326 | /** @type {DependencyLocation} */ (expr.loc)
|
|---|
| 327 | )
|
|---|
| 328 | );
|
|---|
| 329 | } else if (importOptions.webpackIgnore) {
|
|---|
| 330 | // Do not instrument `import()` if `webpackIgnore` is `true`
|
|---|
| 331 | return false;
|
|---|
| 332 | }
|
|---|
| 333 | }
|
|---|
| 334 | if (importOptions.webpackChunkName !== undefined) {
|
|---|
| 335 | if (typeof importOptions.webpackChunkName !== "string") {
|
|---|
| 336 | parser.state.module.addWarning(
|
|---|
| 337 | new UnsupportedFeatureWarning(
|
|---|
| 338 | `\`webpackChunkName\` expected a string, but received: ${importOptions.webpackChunkName}.`,
|
|---|
| 339 | /** @type {DependencyLocation} */ (expr.loc)
|
|---|
| 340 | )
|
|---|
| 341 | );
|
|---|
| 342 | } else {
|
|---|
| 343 | chunkName = importOptions.webpackChunkName;
|
|---|
| 344 | }
|
|---|
| 345 | }
|
|---|
| 346 | if (importOptions.webpackMode !== undefined) {
|
|---|
| 347 | if (typeof importOptions.webpackMode !== "string") {
|
|---|
| 348 | parser.state.module.addWarning(
|
|---|
| 349 | new UnsupportedFeatureWarning(
|
|---|
| 350 | `\`webpackMode\` expected a string, but received: ${importOptions.webpackMode}.`,
|
|---|
| 351 | /** @type {DependencyLocation} */ (expr.loc)
|
|---|
| 352 | )
|
|---|
| 353 | );
|
|---|
| 354 | } else {
|
|---|
| 355 | mode = /** @type {ContextMode} */ (importOptions.webpackMode);
|
|---|
| 356 | }
|
|---|
| 357 | }
|
|---|
| 358 | if (importOptions.webpackPrefetch !== undefined) {
|
|---|
| 359 | if (importOptions.webpackPrefetch === true) {
|
|---|
| 360 | groupOptions.prefetchOrder = 0;
|
|---|
| 361 | } else if (typeof importOptions.webpackPrefetch === "number") {
|
|---|
| 362 | groupOptions.prefetchOrder = importOptions.webpackPrefetch;
|
|---|
| 363 | } else {
|
|---|
| 364 | parser.state.module.addWarning(
|
|---|
| 365 | new UnsupportedFeatureWarning(
|
|---|
| 366 | `\`webpackPrefetch\` expected true or a number, but received: ${importOptions.webpackPrefetch}.`,
|
|---|
| 367 | /** @type {DependencyLocation} */ (expr.loc)
|
|---|
| 368 | )
|
|---|
| 369 | );
|
|---|
| 370 | }
|
|---|
| 371 | }
|
|---|
| 372 | if (importOptions.webpackPreload !== undefined) {
|
|---|
| 373 | if (importOptions.webpackPreload === true) {
|
|---|
| 374 | groupOptions.preloadOrder = 0;
|
|---|
| 375 | } else if (typeof importOptions.webpackPreload === "number") {
|
|---|
| 376 | groupOptions.preloadOrder = importOptions.webpackPreload;
|
|---|
| 377 | } else {
|
|---|
| 378 | parser.state.module.addWarning(
|
|---|
| 379 | new UnsupportedFeatureWarning(
|
|---|
| 380 | `\`webpackPreload\` expected true or a number, but received: ${importOptions.webpackPreload}.`,
|
|---|
| 381 | /** @type {DependencyLocation} */ (expr.loc)
|
|---|
| 382 | )
|
|---|
| 383 | );
|
|---|
| 384 | }
|
|---|
| 385 | }
|
|---|
| 386 | if (importOptions.webpackFetchPriority !== undefined) {
|
|---|
| 387 | if (
|
|---|
| 388 | typeof importOptions.webpackFetchPriority === "string" &&
|
|---|
| 389 | ["high", "low", "auto"].includes(importOptions.webpackFetchPriority)
|
|---|
| 390 | ) {
|
|---|
| 391 | groupOptions.fetchPriority =
|
|---|
| 392 | /** @type {"low" | "high" | "auto"} */
|
|---|
| 393 | (importOptions.webpackFetchPriority);
|
|---|
| 394 | } else {
|
|---|
| 395 | parser.state.module.addWarning(
|
|---|
| 396 | new UnsupportedFeatureWarning(
|
|---|
| 397 | `\`webpackFetchPriority\` expected true or "low", "high" or "auto", but received: ${importOptions.webpackFetchPriority}.`,
|
|---|
| 398 | /** @type {DependencyLocation} */ (expr.loc)
|
|---|
| 399 | )
|
|---|
| 400 | );
|
|---|
| 401 | }
|
|---|
| 402 | }
|
|---|
| 403 | if (importOptions.webpackInclude !== undefined) {
|
|---|
| 404 | if (
|
|---|
| 405 | !importOptions.webpackInclude ||
|
|---|
| 406 | !(importOptions.webpackInclude instanceof RegExp)
|
|---|
| 407 | ) {
|
|---|
| 408 | parser.state.module.addWarning(
|
|---|
| 409 | new UnsupportedFeatureWarning(
|
|---|
| 410 | `\`webpackInclude\` expected a regular expression, but received: ${importOptions.webpackInclude}.`,
|
|---|
| 411 | /** @type {DependencyLocation} */ (expr.loc)
|
|---|
| 412 | )
|
|---|
| 413 | );
|
|---|
| 414 | } else {
|
|---|
| 415 | include = importOptions.webpackInclude;
|
|---|
| 416 | }
|
|---|
| 417 | }
|
|---|
| 418 | if (importOptions.webpackExclude !== undefined) {
|
|---|
| 419 | if (
|
|---|
| 420 | !importOptions.webpackExclude ||
|
|---|
| 421 | !(importOptions.webpackExclude instanceof RegExp)
|
|---|
| 422 | ) {
|
|---|
| 423 | parser.state.module.addWarning(
|
|---|
| 424 | new UnsupportedFeatureWarning(
|
|---|
| 425 | `\`webpackExclude\` expected a regular expression, but received: ${importOptions.webpackExclude}.`,
|
|---|
| 426 | /** @type {DependencyLocation} */ (expr.loc)
|
|---|
| 427 | )
|
|---|
| 428 | );
|
|---|
| 429 | } else {
|
|---|
| 430 | exclude = importOptions.webpackExclude;
|
|---|
| 431 | }
|
|---|
| 432 | }
|
|---|
| 433 | if (importOptions.webpackExports !== undefined) {
|
|---|
| 434 | if (
|
|---|
| 435 | !(
|
|---|
| 436 | typeof importOptions.webpackExports === "string" ||
|
|---|
| 437 | (Array.isArray(importOptions.webpackExports) &&
|
|---|
| 438 | importOptions.webpackExports.every(
|
|---|
| 439 | (item) => typeof item === "string"
|
|---|
| 440 | ))
|
|---|
| 441 | )
|
|---|
| 442 | ) {
|
|---|
| 443 | parser.state.module.addWarning(
|
|---|
| 444 | new UnsupportedFeatureWarning(
|
|---|
| 445 | `\`webpackExports\` expected a string or an array of strings, but received: ${importOptions.webpackExports}.`,
|
|---|
| 446 | /** @type {DependencyLocation} */ (expr.loc)
|
|---|
| 447 | )
|
|---|
| 448 | );
|
|---|
| 449 | } else if (typeof importOptions.webpackExports === "string") {
|
|---|
| 450 | exports = [[importOptions.webpackExports]];
|
|---|
| 451 | } else {
|
|---|
| 452 | exports = exportsFromEnumerable(importOptions.webpackExports);
|
|---|
| 453 | }
|
|---|
| 454 | }
|
|---|
| 455 | }
|
|---|
| 456 |
|
|---|
| 457 | if (
|
|---|
| 458 | mode !== "lazy" &&
|
|---|
| 459 | mode !== "lazy-once" &&
|
|---|
| 460 | mode !== "eager" &&
|
|---|
| 461 | mode !== "weak"
|
|---|
| 462 | ) {
|
|---|
| 463 | parser.state.module.addWarning(
|
|---|
| 464 | new UnsupportedFeatureWarning(
|
|---|
| 465 | `\`webpackMode\` expected 'lazy', 'lazy-once', 'eager' or 'weak', but received: ${mode}.`,
|
|---|
| 466 | /** @type {DependencyLocation} */ (expr.loc)
|
|---|
| 467 | )
|
|---|
| 468 | );
|
|---|
| 469 | mode = "lazy";
|
|---|
| 470 | }
|
|---|
| 471 |
|
|---|
| 472 | const referencedPropertiesInDestructuring =
|
|---|
| 473 | parser.destructuringAssignmentPropertiesFor(expr);
|
|---|
| 474 | const state = getState(parser);
|
|---|
| 475 | const referencedPropertiesInMember = state.get(expr);
|
|---|
| 476 | const fulfilledNamespaceObj =
|
|---|
| 477 | importThen && getFulfilledCallbackNamespaceObj(importThen);
|
|---|
| 478 | if (
|
|---|
| 479 | referencedPropertiesInDestructuring ||
|
|---|
| 480 | referencedPropertiesInMember ||
|
|---|
| 481 | fulfilledNamespaceObj
|
|---|
| 482 | ) {
|
|---|
| 483 | if (exports) {
|
|---|
| 484 | parser.state.module.addWarning(
|
|---|
| 485 | new UnsupportedFeatureWarning(
|
|---|
| 486 | "You don't need `webpackExports` if the usage of dynamic import is statically analyse-able. You can safely remove the `webpackExports` magic comment.",
|
|---|
| 487 | /** @type {DependencyLocation} */ (expr.loc)
|
|---|
| 488 | )
|
|---|
| 489 | );
|
|---|
| 490 | }
|
|---|
| 491 |
|
|---|
| 492 | if (referencedPropertiesInDestructuring) {
|
|---|
| 493 | /** @type {RawReferencedExports} */
|
|---|
| 494 | const refsInDestructuring = [];
|
|---|
| 495 | traverseDestructuringAssignmentProperties(
|
|---|
| 496 | referencedPropertiesInDestructuring,
|
|---|
| 497 | (stack) => refsInDestructuring.push(stack.map((p) => p.id))
|
|---|
| 498 | );
|
|---|
| 499 |
|
|---|
| 500 | exports = refsInDestructuring;
|
|---|
| 501 | } else if (referencedPropertiesInMember) {
|
|---|
| 502 | exports = referencedPropertiesInMember;
|
|---|
| 503 | } else {
|
|---|
| 504 | /** @type {RawReferencedExports} */
|
|---|
| 505 | const references = [];
|
|---|
| 506 | state.set(expr, references);
|
|---|
| 507 |
|
|---|
| 508 | exports = references;
|
|---|
| 509 | }
|
|---|
| 510 | }
|
|---|
| 511 |
|
|---|
| 512 | if (param.isString()) {
|
|---|
| 513 | const attributes = getImportAttributes(expr);
|
|---|
| 514 |
|
|---|
| 515 | if (mode === "eager") {
|
|---|
| 516 | const dep = new ImportEagerDependency(
|
|---|
| 517 | /** @type {string} */ (param.string),
|
|---|
| 518 | /** @type {Range} */ (expr.range),
|
|---|
| 519 | exports,
|
|---|
| 520 | phase,
|
|---|
| 521 | attributes
|
|---|
| 522 | );
|
|---|
| 523 | parser.state.current.addDependency(dep);
|
|---|
| 524 | } else if (mode === "weak") {
|
|---|
| 525 | const dep = new ImportWeakDependency(
|
|---|
| 526 | /** @type {string} */ (param.string),
|
|---|
| 527 | /** @type {Range} */ (expr.range),
|
|---|
| 528 | exports,
|
|---|
| 529 | phase,
|
|---|
| 530 | attributes
|
|---|
| 531 | );
|
|---|
| 532 | parser.state.current.addDependency(dep);
|
|---|
| 533 | } else {
|
|---|
| 534 | const depBlock = new AsyncDependenciesBlock(
|
|---|
| 535 | {
|
|---|
| 536 | ...groupOptions,
|
|---|
| 537 | name: chunkName
|
|---|
| 538 | },
|
|---|
| 539 | /** @type {DependencyLocation} */ (expr.loc),
|
|---|
| 540 | param.string
|
|---|
| 541 | );
|
|---|
| 542 | const dep = new ImportDependency(
|
|---|
| 543 | /** @type {string} */ (param.string),
|
|---|
| 544 | /** @type {Range} */ (expr.range),
|
|---|
| 545 | exports,
|
|---|
| 546 | phase,
|
|---|
| 547 | attributes
|
|---|
| 548 | );
|
|---|
| 549 | dep.loc = /** @type {DependencyLocation} */ (expr.loc);
|
|---|
| 550 | dep.optional = Boolean(parser.scope.inTry);
|
|---|
| 551 | depBlock.addDependency(dep);
|
|---|
| 552 | parser.state.current.addBlock(depBlock);
|
|---|
| 553 | }
|
|---|
| 554 | } else {
|
|---|
| 555 | if (mode === "weak") {
|
|---|
| 556 | mode = "async-weak";
|
|---|
| 557 | }
|
|---|
| 558 |
|
|---|
| 559 | const dep = ContextDependencyHelpers.create(
|
|---|
| 560 | ImportContextDependency,
|
|---|
| 561 | /** @type {Range} */ (expr.range),
|
|---|
| 562 | param,
|
|---|
| 563 | expr,
|
|---|
| 564 | this.options,
|
|---|
| 565 | {
|
|---|
| 566 | chunkName,
|
|---|
| 567 | groupOptions,
|
|---|
| 568 | include,
|
|---|
| 569 | exclude,
|
|---|
| 570 | mode,
|
|---|
| 571 | namespaceObject:
|
|---|
| 572 | /** @type {BuildMeta} */
|
|---|
| 573 | (parser.state.module.buildMeta).strictHarmonyModule
|
|---|
| 574 | ? "strict"
|
|---|
| 575 | : true,
|
|---|
| 576 | typePrefix: "import()",
|
|---|
| 577 | category: "esm",
|
|---|
| 578 | referencedExports: exports,
|
|---|
| 579 | attributes: getImportAttributes(expr),
|
|---|
| 580 | phase
|
|---|
| 581 | },
|
|---|
| 582 | parser
|
|---|
| 583 | );
|
|---|
| 584 | if (!dep) return;
|
|---|
| 585 | dep.loc = /** @type {DependencyLocation} */ (expr.loc);
|
|---|
| 586 | dep.optional = Boolean(parser.scope.inTry);
|
|---|
| 587 | parser.state.current.addDependency(dep);
|
|---|
| 588 | }
|
|---|
| 589 |
|
|---|
| 590 | if (fulfilledNamespaceObj) {
|
|---|
| 591 | walkImportThenFulfilledCallback(
|
|---|
| 592 | parser,
|
|---|
| 593 | expr,
|
|---|
| 594 | /** @type {ArrowFunctionExpression | FunctionExpression} */
|
|---|
| 595 | (importThen.arguments[0]),
|
|---|
| 596 | fulfilledNamespaceObj
|
|---|
| 597 | );
|
|---|
| 598 | parser.walkExpressions(importThen.arguments.slice(1));
|
|---|
| 599 | } else if (importThen) {
|
|---|
| 600 | parser.walkExpressions(importThen.arguments);
|
|---|
| 601 | }
|
|---|
| 602 |
|
|---|
| 603 | return true;
|
|---|
| 604 | });
|
|---|
| 605 | }
|
|---|
| 606 | }
|
|---|
| 607 |
|
|---|
| 608 | module.exports = ImportParserPlugin;
|
|---|