nodejs module,nodejs node_module
本文带你了解node.js中的module-alias,介绍module-alias的原理,以及module-alias的一个常见问题(坑),希望对你有所帮助!
node.js速度课程简介:进入学习
首先,有必要介绍一下什么是模块别名。这是它的官方网站链接(https://github.com/ilearnio/module-alias,官方网站)。
简单来说,module-alias提供了节点环境下路径别名的功能。一般前端开发者可能熟悉webpack的别名配置,typescript的路径配置等。都提供了军队别名的功能。别名是代码开发过程中的yyds。否则,当你看到这种./././xx路径,你一定会抓狂的。
用webpack打包的项目webpack本身会处理从源代码中路径别名的配置到打包代码的转换过程。但是,如果一个项目只是用typescript编译,虽然typescript在编译过程中可以正常处理路径中路径别名的配置,但是它是不会改变打包后的代码,造成在打包后的代码中仍然存在路径别名配置。看看用typescript编译的代码:
使用严格的;
Object.defineProperty(exports, __esModule ,{ value:true });
要求(。/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的配置内容
路径:{
@/*: [
src/*
]
}你可以看到@符号仍然存在于typescript编译的代码中。但是当代码运行时,比如在node中允许,require不能正常识别路径中的这个符号,导致找不到对应模块时抛出异常。
这也是模块别名清单的目的。
module-alias介绍
从官网来看,使用这个库只需要两步,真的是极简状态。
1.路径别名配置:模块别名支持两种路径别名配置方法。
在package.json中添加attribute _ modulaliases进行配置。
_moduleAliases: {
@: ./src
}通过提供的API接口addAliases、addaliases和addPath添加配置。
moduleAlias.addAliases({
@ :_ _目录名。/src ,
});2.项目启动时,只需导入库:require(module-alias/register)。当然,如果选择使用API,则需要导入相应的函数进行处理。
一般情况下,我们在package.json中的配置路径alias项目的入口使用require(module-alias/register)来使用这个库。
module-alias原理介绍
Module-alias通过覆盖全局对象模块上的method _resolveFilename来更改路径别名。简单来说就是通过拦截native _resolveFilename方法调用来改变路径别名,在获取文件的真实路径后再调用original _resolveFilename方法。
下面是它的源代码,基本分为两部分:路径别名转换native _resolveFilename调用
var oldResolveFilename=Module。_ resolve文件名
模块。_ resolve filename=function(request,parentModule,isMain,options) {
for(var I=modulealianames . length;I-0;) {
var alias=moduleAliasNames[i]
if (isPathMatchesAlias(请求,别名)){
var alias target=module aliases[alias]
//自定义函数处理程序
if(type of module aliases[alias]=== function ){
var from path=parent module . filename
alias target=module aliases[alias](来自路径,请求,别名)
如果(!alias target alias target的类型!==string) {
引发新错误(“[模块别名]要求自定义处理程序函数返回路径。”)
}
}
request=nodepath . join(alias target,request.substr(alias.length))
//只使用第一个匹配
破裂
}
}
return oldresolvefilename . call(this,request,parentModule,isMain,options)
}
module-alias踩坑
一般我们会在节点项目中使用module-alias库,因为节点项目通常是从typescript转换成js代码的,但往往不会打包,因为节点项目中不需要打包,有些多余。这就是模块别名需要发挥的时候。
但是,这个项目有点不寻常。我们在项目中使用了多层代码组织。最外层有一个全局的package.json,内层有自己的package.json,简单来说我们用了monorepo的代码组织,问题也就是由此而来。
一开始我还真没觉得是多级项目组织的问题。官网解释了一会儿模块-别名/注册的用法:
但当时我真的没有注意到这个指令,不然我也不会踩这个坑。下一次,我应该会仔细阅读说明,但这么长的说明,我可能不会看得这么仔细。毕竟,这么简单的使用方式,似乎并不会造成什么问题。
module-alias/register流程
既然踩了坑,就要知道踩坑的原因,避免反复踩。您可以在module-alias中了解有关init方法实现的更多信息。为了节省篇幅,省略了一些细节。
函数初始化(选项){
//省略部分内容。
var candidatePackagePaths
if (options.base) {
candidatePackagePaths=[nodepath . resolve(options . base . replace(/\/package \json$/, ))]
}否则{
//可能有99%的机会找到项目根目录
//在node_modules目录之上,
//或者package.json在节点进程的当前工作目录中(当
//运行包管理器脚本,例如` yarn start`/`npm run start `)
//重点看这里!
candidatePackagePaths=[nodepath . join(_ _ dirname,./.),process.cwd()]
}
var npmPackage,base
for(candidatePackagePaths中的变量I){
尝试{
base=candidatePackagePaths[i]
NPM package=require(nodepath . join(base, package.json ))
破裂
} catch (e) { //noop }
}
//省略部分内容。
var aliases=npmPackage。_moduleAliases {}
for(别名中的变量别名){
if(别名[别名][0]!==/) {
别名[alias]=nodePath.join(base,aliases[alias])
}
}
//省略部分内容。
}可以看看重要的部分。如果我们不给出基本参数,模块别名将从././目录和当前目录,以及./.目录高于当前目录,这里的优先级设置似乎和正常的优先级逻辑有点差别,一般都会让当前目录的优先级比较高才比较符合正常逻辑,所以会导致加载当前目录下的package.json文件,导致找不到路径别名配置。
解决办法
通过API注册路径别名,或者手动调用init方法,传入base参数并指定package.json文件。
似乎只有踩过坑才会有更深的体会。
更多关于node的信息,请访问:nodejs教程!这是为了了解node.js中module-alias的更多细节,请关注我们的其他相关文章!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。