module

lxf2023-03-18 18:20:01

本文带大家了解一下node.js里的module-alias,介绍一下module-alias基本原理、module-alias的一个疑难问题(坑),希望能帮助到大家!

module

最先必须介绍一下module-alias是啥,这儿有之官方网站连接(官网网址 https://github.com/ilearnio/module-alias)。

通俗点说,module-alias带来了在node条件下的途径别称作用。一般前端工程师可能会有点了解webpackalias配备、typescriptpaths配备等,这都是带来了陆军作战别称的功效。途径别称在编码开发过程中是yyds,否则你看到这样的../../../../xx途径时,是一定会伤脑的。

应用webpack装包项目webpack自身会解决源码中途径别称配置到装包后代码的转换过程,可是如果仅仅应用typescript开展编译程序项目,尽管typescript在编译过程中能正常解决paths中途径别称配置,可是并始终不变装包后编码,导致在装包后编码中依然存在途径别称配备,看一个通过typescript编译程序后编码:

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
require("./module-alias-register");
var commands_1 = require("@/commands");
var package_json_1 = require("../package.json");
(0, commands_1.run)(package_json_1.version);

欢迎来到tsconfig.json配置具体内容

"paths": {
  "@/*": [
    "src/*"
  ]
}

能够看见在通过typescript编译程序后编码中,依然存在@标记,然而当程序执行的过程当中,例如可在node中,require根本无法正常的鉴别途径中的这一标记,造成找不着相对应控制模块而抛出异常。

那也是module-alias这一库存在的目的。

module-alias详细介绍

从网站上看,这一库操作方法只需二步,确实已是简约状态。

1、途径别称配备:module-alias适用二种途径别称配备方法

  • package.json中加入_moduleAliases特性开展配备

    "_moduleAliases": {
        "@": "./src"
    }
  • 根据所提供的API插口addAliasaddAliasesaddPath,提升配备

    moduleAlias.addAliases({
      '@'  : __dirname   './src',
    });

2、在项目开工时最先导进该库:require(module-alias/register)就可以,自然选择用API方法的必须导进相对应的函数公式予以处理

一般我们都是使用package.json中配备途径别称 新项目入口require(module-alias/register)来使用这种库。

module-alias基本原理详细介绍

module-alias根据覆写了全局对象Module里的方式_resolveFilename来实践路径别称的转换,简单的说就是根据阻拦原生的_resolveFilename方法调用,开展途径别称的转换,当掌握到文档的实际途径后,再启用原声带的_resolveFilename方式。

下边则是源码,大部分分为两部分:途径别称变换 原生态_resolveFilename启用

var oldResolveFilename = Module._resolveFilename
Module._resolveFilename = function (request, parentModule, isMain, options) {
  for (var i = moduleAliasNames.length; i-- > 0;) {
    var alias = moduleAliasNames[i]
    if (isPathMatchesAlias(request, alias)) {
      var aliasTarget = moduleAliases[alias]
      // Custom function handler
      if (typeof moduleAliases[alias] === 'function') {
        var fromPath = parentModule.filename
        aliasTarget = moduleAliases[alias](fromPath, request, alias)
        if (!aliasTarget || typeof aliasTarget !== 'string') {
          throw new Error('[module-alias] Expecting custom handler function to return path.')
        }
      }
      request = nodePath.join(aliasTarget, request.substr(alias.length))
      // Only use the first match
      break
    }
  }

  return oldResolveFilename.call(this, request, parentModule, isMain, options)
}

看似简单身后,往往会踩雷

module-alias踩雷

一般我们将在node工程中应用module-alias库,由于node新项目一般是从typescript转化成js编码,但很多时候并不能开展装包解决,由于node工程中一般也的确不用装包,显得有些多余。这个时候就需要module-alias上场了。

可是这样的项目有点儿不一般,大家在工程中用了双层编码组织模式,外层有全局性package.json, 里层包有着自己的package.json, 简单的说是用了monorepo的代码组织模式,难题其实就是由此而来

module-alias不能正常分析在package.json中配备的路线别称

一开始的确想不到是双层新项目组织模式问题,官方网站对module-alias/register应用有一段表明:

module

但当时确实是没有注意到这方面表明,要不然怎么踩这一坑惨了,下一次看使用说明书一定要仔细了,但是这么长的使用说明书,很有可能也是不会看得那么细心。。。终究看上去那么容易的操作方法,仿佛或许是不容易出了什么难题吧

module-alias/register步骤

即然踩雷了,就必须要了解一下踩雷的主要原因,防止不断踩雷才行。能够深入分析下module-aliasinit方式的完成。为了节约篇数,省略了一部分小细节

function init (options) {
  // 省略了一些内容
  var candidatePackagePaths
  if (options.base) {
    candidatePackagePaths = [nodePath.resolve(options.base.replace(/\/package\.json$/, ''))]
  } else {
    // There is probably 99% chance that the project root directory in located
    // above the node_modules directory,
    // Or that package.json is in the node process' current working directory (when
    // running a package manager script, e.g. `yarn start` / `npm run start`)
    // 关键看看吧!!!
    candidatePackagePaths = [nodePath.join(__dirname, '../..'), process.cwd()]
  }
  var npmPackage, base
  for (var i in candidatePackagePaths) {
    try {
      base = candidatePackagePaths[i]
      npmPackage = require(nodePath.join(base, 'package.json'))
      break
    } catch (e) { // noop }
  }
  // 省略了一些内容
  var aliases = npmPackage._moduleAliases || {}
  for (var alias in aliases) {
    if (aliases[alias][0] !== '/') {
      aliases[alias] = nodePath.join(base, aliases[alias])
    }
  }
  // 省略了一些内容
}

能够看重点一部分,假如我们并没有给base主要参数,module-alias默认设置是从../../文件目录和文件列表下搜寻package.json文档,并且../..目录下的package.json文件信息优先比文件列表中的优先还高,这儿的优先设定好像和正常优先逻辑性有点儿区别,一般都会让文件列表的优先较为高才比较接近正常的逻辑性,因此也会导致载入的并不是文件列表中的package.json文档,而造成找不到路径别称配备而出差错。

有关这一点好像有许多人踩雷了,也有人说了issues,可是好像临时并没人回复。

解决方案

根据API方法申请注册途径别称,或是手动式启用init方式,传到base主要参数,特定package.json文档.

好像只有踩雷了,才能全面的了解

大量node基本知识,请访问:nodejs 实例教程!!

以上就是关于全面了解node.js里的module-alias(分享一些防坑方式)的具体内容,大量欢迎关注AdminJS其他类似文章!