nodejs module,nodejs node_module

  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的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: