WXL
3 天以前 3bd962a6d7f61239c020e2dbbeb7341e5b842dd1
node_modules/enhanced-resolve/lib/AliasPlugin.js
@@ -5,19 +5,17 @@
"use strict";
const forEachBail = require("./forEachBail");
const { PathType, getType } = require("./util/path");
/** @typedef {import("./Resolver")} Resolver */
/** @typedef {import("./Resolver").ResolveRequest} ResolveRequest */
/** @typedef {import("./Resolver").ResolveStepHook} ResolveStepHook */
/** @typedef {string | Array<string> | false} Alias */
/** @typedef {{alias: Alias, name: string, onlyModule?: boolean}} AliasOption */
/** @typedef {string | string[] | false} Alias */
/** @typedef {{ alias: Alias, name: string, onlyModule?: boolean }} AliasOption */
const { aliasResolveHandler } = require("./AliasUtils");
module.exports = class AliasPlugin {
   /**
    * @param {string | ResolveStepHook} source source
    * @param {AliasOption | Array<AliasOption>} options options
    * @param {AliasOption | AliasOption[]} options options
    * @param {string | ResolveStepHook} target target
    */
   constructor(source, options, target) {
@@ -32,143 +30,16 @@
    */
   apply(resolver) {
      const target = resolver.ensureHook(this.target);
      /**
       * @param {string} maybeAbsolutePath path
       * @returns {null|string} absolute path with slash ending
       */
      const getAbsolutePathWithSlashEnding = (maybeAbsolutePath) => {
         const type = getType(maybeAbsolutePath);
         if (type === PathType.AbsolutePosix || type === PathType.AbsoluteWin) {
            return resolver.join(maybeAbsolutePath, "_").slice(0, -1);
         }
         return null;
      };
      /**
       * @param {string} path path
       * @param {string} maybeSubPath sub path
       * @returns {boolean} true, if path is sub path
       */
      const isSubPath = (path, maybeSubPath) => {
         const absolutePath = getAbsolutePathWithSlashEnding(maybeSubPath);
         if (!absolutePath) return false;
         return path.startsWith(absolutePath);
      };
      resolver
         .getHook(this.source)
         .tapAsync("AliasPlugin", (request, resolveContext, callback) => {
            const innerRequest = request.request || request.path;
            if (!innerRequest) return callback();
            forEachBail(
            aliasResolveHandler(
               resolver,
               this.options,
               (item, callback) => {
                  /** @type {boolean} */
                  let shouldStop = false;
                  const matchRequest =
                     innerRequest === item.name ||
                     (!item.onlyModule &&
                        (request.request
                           ? innerRequest.startsWith(`${item.name}/`)
                           : isSubPath(innerRequest, item.name)));
                  const splitName = item.name.split("*");
                  const matchWildcard = !item.onlyModule && splitName.length === 2;
                  if (matchRequest || matchWildcard) {
                     /**
                      * @param {Alias} alias alias
                      * @param {(err?: null|Error, result?: null|ResolveRequest) => void} callback callback
                      * @returns {void}
                      */
                     const resolveWithAlias = (alias, callback) => {
                        if (alias === false) {
                           /** @type {ResolveRequest} */
                           const ignoreObj = {
                              ...request,
                              path: false,
                           };
                           if (typeof resolveContext.yield === "function") {
                              resolveContext.yield(ignoreObj);
                              return callback(null, null);
                           }
                           return callback(null, ignoreObj);
                        }
                        let newRequestStr;
                        const [prefix, suffix] = splitName;
                        if (
                           matchWildcard &&
                           innerRequest.startsWith(prefix) &&
                           innerRequest.endsWith(suffix)
                        ) {
                           const match = innerRequest.slice(
                              prefix.length,
                              innerRequest.length - suffix.length,
                           );
                           newRequestStr = alias.toString().replace("*", match);
                        }
                        if (
                           matchRequest &&
                           innerRequest !== alias &&
                           !innerRequest.startsWith(`${alias}/`)
                        ) {
                           /** @type {string} */
                           const remainingRequest = innerRequest.slice(item.name.length);
                           newRequestStr = alias + remainingRequest;
                        }
                        if (newRequestStr !== undefined) {
                           shouldStop = true;
                           /** @type {ResolveRequest} */
                           const obj = {
                              ...request,
                              request: newRequestStr,
                              fullySpecified: false,
                           };
                           return resolver.doResolve(
                              target,
                              obj,
                              `aliased with mapping '${item.name}': '${alias}' to '${newRequestStr}'`,
                              resolveContext,
                              (err, result) => {
                                 if (err) return callback(err);
                                 if (result) return callback(null, result);
                                 return callback();
                              },
                           );
                        }
                        return callback();
                     };
                     /**
                      * @param {(null | Error)=} err error
                      * @param {(null | ResolveRequest)=} result result
                      * @returns {void}
                      */
                     const stoppingCallback = (err, result) => {
                        if (err) return callback(err);
                        if (result) return callback(null, result);
                        // Don't allow other aliasing or raw request
                        if (shouldStop) return callback(null, null);
                        return callback();
                     };
                     if (Array.isArray(item.alias)) {
                        return forEachBail(
                           item.alias,
                           resolveWithAlias,
                           stoppingCallback,
                        );
                     }
                     return resolveWithAlias(item.alias, stoppingCallback);
                  }
                  return callback();
               },
               target,
               request,
               resolveContext,
               callback,
            );
         });