webpack对模块查找的优化

640?wx_fmt=png

自定义模块指的是非核心模块,也不是路径形式的标识符。它是一种特殊的文件模块,可能是一个文件或者包的形式。这类模块的查找是最费时的,也是所有方式中最慢的一种。


模块路径是Node在定位文件模块的具体文件时制定的查找策略,具体表现为一个路径组成的数组。关于这个路径的生成规则,我们可以手动尝试一番。


创建test.js文件,其内容为 console.log(module.paths); 。将其放到任意一个目录中然后执行 node test.js 。


在Linux下,你可能得到的是这样一个数组输出:

[ '/home/jackson/research/node_modules',	
'/home/jackson/node_modules',	
'/home/node_modules',	
'/node_modules' ]


而在Windows下,也许是这样:

[ 'c:\\nodejs\\node_modules', 'c:\\node_modules' ]


可以看出,模块路径的生成规则如下所示。

1.前文件目录下的node_modules目录。2.父目录下的node_modules目录。3.父目录的父目录下的node_modules目录。4.沿路径向上逐级递归,直到根目录下的node_modules目录。


它的生成方式与JavaScript的原型链或作用域链的查找方式十分类似。在加载的过程中,Node会逐个尝试模块路径中的路径,直到找到目标文件为止。可以看出,当前文件的路径越深,模块查找耗时会越多,这是自定义模块的加载速度是最慢的原因。


webpack可以配置模块的查找路径

  resolve: {	
    modules: [path.resolve(__dirname, 'node_modules')]	
  }

指定只在当前模块的node_modules查找模块


但在文件的定位过程中,还有一些细节需要注意,这主要包括文件扩展名的分析、目录和包的处理。

文件扩展名分析

require() 在分析标识符的过程中,会出现标识符中不包含文件扩展名的情况。CommonJS模块规范也允许在标识符中不包含文件扩展名,这种情况下,Node会按.js.json.node的次序补足扩展名,依次尝试。


webpack配置中可以指定匹配的顺序

// 按照指定的扩展名顺序匹配	
  resolve: {	
    extensions: ['.js', '.css', '.json', '.jsx']	
  }


在尝试的过程中,需要调用 fs 模块同步阻塞式地判断文件是否存在。因为Node是单线程的,所以这里是一个会引起性能问题的地方。小诀窍是:如果是.node.json文件,在传递给 require() 的标识符中带上扩展名,会加快一点速度。另一个诀窍是:同步配合缓存,可以大幅度缓解Node单线程中阻塞式调用的缺陷。

目录分析和包

目录分析和包在分析标识符的过程中, require() 通过分析文件扩展名之后,可能没有查找到对应文件,但却得到一个目录,这在引入自定义模块和逐个模块路径进行查找时经常会出现,此时Node会将目录当做一个包来处理。


在这个过程中,Node对CommonJS包规范进行了一定程度的支持。首先,Node在当前目录下查找package.json(CommonJS包规范定义的包描述文件),通过 JSON.parse()解析出包描述对象,从中取出 main 属性指定的文件名进行定位。如果文件名缺少扩展名,将会进入扩展名分析的步骤。


webpack中可以指定查找字段的顺序

// 先定位package.json的style字段,没有再定位main字段指定的文件	
  resolve: {	
    mainFields: ['style', 'main']	
  },


而如果 main 属性指定的文件名错误,或者压根没有package.json文件,Node会将 index当做默认文件名,然后依次查找index.jsindex.nodeindex.json


webpack可以指定查找的顺序

// 先找文件名是index文件,没有再找main的文件	
  resolve: {	
    mainFiles: ['index', 'main']	
  },


如果在目录分析的过程中没有定位成功任何文件,则自定义模块进入下一个模块路径进行查找。如果模块路径数组都被遍历完毕,依然没有查找到目标文件,则会抛出查找失败的异常。


640?wx_fmt=png
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值