手机版

谈对网络包构建速度优化的一个误区

时间:2021-08-22 来源:互联网 编辑:宝哥软件园 浏览:

问题描述

项目中使用了npm包a。前几天用的还不错。突然,在拉了其他分支代码后,一个Bug出来了。

第一个反应是有人改变了这个包的版本。检查以下项目的package.json和package-lock.json文件,该模块和依赖模块的信息没有变化。node_modules/a中的版本信息也对应于package.json中的版本信息.

我突然失去了线索,只好在node_modules中调试。

TL;灾难恢复;

看最后的总结XD

node_modules的目录结构

项目中node_modules的目录如下:

node _ modulesaindex . js | |. 节点_模块. C | | index.js | |. 眼尖的同学可能会发现,模块c安装在项目本身的node_modules目录和模块a的node_modules目录下,这是为什么呢?

:有两个原因

项目直接依赖模块C,项目不直接依赖模块C,但是项目直接依赖的模块B依赖模块C,与A依赖的模块C版本不兼容。模块C在我们的项目中没有直接引用,所以这是第二种情况。

npm的模块安装机制

本节主要解释为什么项目不直接依赖模块C,而是在项目的node_modules目录中安装C。不感兴趣的同学可以直接跳过。

假设项目依赖模块A和模块B,模块A依赖模块C的1.0.0版本,模块B依赖模块C的2.0.0版本。

npm2

在npm2中,模块是嵌套安装的,c模块分别安装在a和b模块的node_modules目录中。

这种方法虽然简单,但会导致node_modules中出现大量相同的模块。想象一下,如果模块A和模块所依赖的模块C都是1.0.0版本,那么冗余模块就会以这种方式生成。

npm3

到npm3时,npm2中冗余模块的生成得到了改进。当npm安装模块时,它会尝试将模块安装在最外面的node_modules目录中,这样模块就可以尽可能地被重用。

安装模块时,如果外部node_modules目录中没有同名的模块,它将安装在最外面的ndoe_modules目录中。如果外部node_modules目录中已经存在同名模块,并且其版本兼容,则不会安装该模块(使用时将直接使用外部模块)。如果外部node_modules目录中已经存在同名模块,并且其版本不兼容,则安装在父模块node_modules目录中的安装模块如上图所示

引用了错误的模块

我给node _ modules/a/node _ modules/c/index . js添加了一些日志,发现没有执行!

此时,要么日志的位置写得不正确,要么没有介绍这个模块。在确认了webpack配置中的resolve.mainFields属性和模块C的package.json文件信息后,排除了第一种可能.

Tips: resolve.mainFields属性用于告诉webpack如何在引入npm模块时找到它的入口。

这个时候,就有点让人摸不着头脑了。引用模块时,不先从当前目录的node_modules目录查找吗?当需要查找时,可以在下一个更高级别的node_modules目录中尝试。

果然!模块c!在最外面的node_modules中被引用。

webpack查找模块的方式和Node.js不一样吗?还是因为webpack的某些配置导致的?

使用下面的webpack配置进行构建,发现不存在上述问题。

const path=require('path ')模块,exports={ entry: '。/src/index.js ',output : { filename : ' main . js ',path : path . resolve(_ dirname,'。/dist/js ' },};然后,我们只需要找出哪些webpack配置会影响模块检索。查看项目中的webpack配置,只有resolve属性与模块检索相关。

const config={ resolve : { modules :[path.resolve(projectDir,' src ')、path . resolve(PROJECt DiR,' node_modules ')、path.resolve(imtPath,' node_modules '),],//es摇树mainfield s 3360[' js next : main ',' browser ',' main'],alias: {},extensions: [。jsx ','。js'],}}好在配置不多。检查网络包文档后,问题很快被发现:解析时使用了绝对路径。模块以下是原始网络包文档:

告诉webpack在解析模块时应该搜索哪些目录。绝对路径和相对路径都可以使用,但它们之间略有不同。

通过查看当前目录和祖先路径(即。/Node_modules,/node_modules等。),相对路径的搜索方式与节点搜索“node_modules”的方式类似。

使用绝对路径,将只搜索给定的目录。

在上面的webpack配置中,path.resolve (projectdir,' node_modules ')是项目的node _ modules目录。这种配置的原因是我们想优化模块检索的速度,但却导致了如此严重的Bug。

根据webpack文档,正是这个绝对路径导致了Bug。然后只要把这个绝对路径改成node_modules,Bug就解决了。

摘要

当npm安装模块时,它会优先将包安装在node_modules目录的最外层,并将它安装在父模块下的node_modules中,除非有冲突。但是,当webpack配置中的resolve.modules设置为project node_modules目录的绝对路径时,将导致webpack在搜索node_modules目录时只搜索最外层的目录,而忽略具有相同名称的较深的模块。这与默认的“先使用深度模块”的搜索策略相反,这导致在构建中使用了错误的npm包。

以上就是本文的全部内容。希望对大家的学习有帮助,支持我们。

版权声明:谈对网络包构建速度优化的一个误区是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。