本文带大家了解一下node.js里的module-alias,介绍一下module-alias基本原理、module-alias的一个疑难问题(坑),希望能帮助到大家!
最先必须介绍一下module-alias
是啥,这儿有之官方网站连接(官网网址 https://github.com/ilearnio/module-alias)。
通俗点说,module-alias
带来了在node
条件下的途径别称作用。一般前端工程师可能会有点了解webpack
的alias
配备、typescript
的paths
配备等,这都是带来了陆军作战别称的功效。途径别称在编码开发过程中是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插口
addAlias
、addAliases
、addPath
,提升配备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-alias/register步骤
即然踩雷了,就必须要了解一下踩雷的主要原因,防止不断踩雷才行。能够深入分析下module-alias
中init
方式的完成。为了节约篇数,省略了一部分小细节
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其他类似文章!