给webpack提了一个pr之后......(一)

简介: 给webpack提了一个pr之后......

前言

我不是标题党啊,是真的给webpack提了一个pr,提交之后,脑子里就是一句话:“纸上学来终觉浅,绝知此事要躬行”。

欲知来龙去脉,听我娓娓道来。

fccc5e6126e3392ed975ea7b5e44467.png

pr 如下,github.com/webpack/web…,目前还是unreviewed状态。

1686898822214.jpg

阅读此文章你将会了解以下知识点,

  • webstrom 调试webpack源码过程
  • webpack优化->deterministic 属性作用
  • 如何提给开源仓库pr
  • 如何修改commit 信息
  • 如何合并commit 信息
  • EasyCLA开源协议签署遇到的问题

看到 = 学会,如果对屏幕前的大帅比大漂亮有帮助的话,点个赞什么的就太好了!

1686898837971.jpg

背景

那是一个周五的晚上,11.左右,大部分人都准备休息了,我正在做山月的linux训练营,赶巧,山月在webpack训练营里,圈出一处webpack的源码,8行左右吧。说到,此处有优化空间,可以提pr。

1686898852935.jpg

盯着这段代码,我看了半天,没有上下文,一脸懵圈。大部分人,没有看过源码,直接看肯定看不出毛病,我也是这部分人的一部分。


后来找了一个做前端的朋友一起看,寻取帮助,他刚刚团建完到家,毫无学习状态。


我知道有些路注定要一个人走,自己调试webpack源码吧。

调试

我是用的工具是webstorm。

首先我在node_modules中webpack目录下,全局搜索,迅速定位到图示函数。

不得不说,webstorm 的搜索功能真是嘎嘎强!

定位到文件,lib/ids/DeterministicModuleIdsPlugin.js下,看代码不一定知道是什么逻辑,不过看名字却很清楚了,是处理DeterministicModuleIds的一个插件函数。

先简单说说Deterministic

deterministic

正巧,最近刚刚在webpack 训练营学习了Deterministic

正好复习一遍。

这是一个webpack 优化项

optimization: {
    moduleIds: 'deterministic',
    chunkIds: 'deterministic'
}

在生产环境下,二者将被 webpack 默认配置为 deterministic。

这说明这个配置项非常nice,webpack 已经帮我们用了,那聪明的你肯定要问了,它是干什么的呢?

告知 webpack 当选择moduleId 和chunkId时需要使用哪种算法

deterministic在不同的编译中不变的短数字 id(最少三位)。有益于长期缓存。

翻译翻译就是=>

生成确认的id,这样可以有效避免由于模块引入的顺序改变而导致的产物大面积更改的问题,每个module/chunk都有自己确定的 id。

举例说明

比如在某项目某文件中,引入A模块,第一行import(A)过了一段时间,需要引入B,新的模块,一般来说我们会放在模块引入最下面,但是有个菜鸟,他在第一行增加import(B),import(A)就放在了第2行,并提交构建。

那么新增B,导致A,以及以前原有模块(我叫它们A+),引入顺序都发生了变化,导致模块id发生变化,进而导致文件打包出来的文件名发生变化。

聪明的你,肯定要问了,这有问题吗。其实没啥大问题!不会有任何异常。


但是有没有更好的解决方案,有!


deterministic 这个配置项就可以帮助我们,无论新增或者减少模块,把原有的模块对应的moduleId 和chunkId 每次打包出来都一样。

这样我们就可以有效的利用浏览器缓存了。


当然了,不做也可以,大不了新增模块,所有chunk都发现了变化,打开页面慢一点而已。


1686898927514.jpg


现在其实也已经可以不关心了,因为webpack已经是默认配置了。

我只是大概说了下deterministic的作用,关于deterministic的原理,等后面有余力了,再整一篇。

开始调试

说了这么多,就是为了铺垫,现在我们开始调试。

在webpack训练营的demo中,有这么一个例子,正好用到了deterministic。

javascript


//build.js
const path = require('path')
const webpack = require('webpack')
const normalConfig = {
  entry: './index.js',
  mode: 'none',
  output: {
    filename: '[name].[id].[contenthash].js',
    chunkFilename: '[name].[id].[contenthash].chunk.js',
    path: path.resolve(__dirname, 'dist/normal'),
  },
  optimization: {
    runtimeChunk: {
      name: entrypoint => `runtime-${entrypoint.name}`,
    },
    chunkIds: 'deterministic',
    moduleIds: 'deterministic'
  }
}
f1().run((err, stat) => {
  console.log(JSON.stringify(stat.toJson(), null, 2))
})

我使用的开发工具是webstorm,调试代码特别的方便。

在f1函数处,点击一下打上断点。

1686898960801.jpg

进入到node_modules的webpack/lib/ids/DeterministicModuleIdsPlugin.js

打上断点

1686898972320.jpg

右键build.js,选择调试build.js,打开webpack 调试界面,代码此时已经运行到我们的我们设置的第一个断点处

1686898984526.jpg

1686898993315.jpg

点击 >>| 按钮,直接运行到下一个断点处,可以看到圈出来的代码,usedIds 是一个set,用来存放moduleId

原代码逻辑是,先获取了原usedIds的长度size,插入新的id,如果发现size没变,说明id 重复了,如果size变了,则说明id 没有重复。

1686899007567.jpg

其实就是想判断usedIs中有没有id,没有必要绕这么一大圈用size来判断,可以直接用has来判断id 在不在usedIds中。时间复杂度一样,还不用额外声明变量。

所以对上述代码进行改写

改写前

(module, id) => {
    const size = usedIds.size;
    usedIds.add(`${id}`);
        if (size === usedIds.size) {
            conflicts++;
            return false;
        }               
    chunkGraph.setModuleId(module, id);    
    return true;
},

改写后

(module, id) => {
    if (usedIds.has(`${id}`) {
        conflicts++;
        return false;
    }
    usedIds.add(`${id}`);
    chunkGraph.setModuleId(module, id);
    return true;
},


相关文章
|
Shell 开发工具 git
给webpack提了一个pr之后......(二)
给webpack提了一个pr之后......
78 0
|
5月前
|
JavaScript 前端开发
webpack成长指北第9章---webpack如何对icon字体进行打包
webpack成长指北第9章---webpack如何对icon字体进行打包
107 1
|
5月前
|
前端开发 JavaScript
webpack成长指北第7章---webpack的css\less\scss样式打包
webpack成长指北第7章---webpack的css\less\scss样式打包
85 0
|
5月前
|
前端开发 JavaScript
webpack成长指北第8章---webpack的CSS Modules打包
webpack成长指北第8章---webpack的CSS Modules打包
55 0
|
23天前
|
JavaScript
webpack打包TS
webpack打包TS
|
7天前
|
JavaScript 测试技术 Windows
vue配置webpack生产环境.env.production、测试环境.env.development(配置不同环境的打包访问地址)
本文介绍了如何使用vue-cli和webpack为Vue项目配置不同的生产和测试环境,包括修改`package.json`脚本、使用`cross-env`处理环境变量、创建不同环境的`.env`文件,并在`webpack.prod.conf.js`中使用`DefinePlugin`来应用这些环境变量。
23 2
vue配置webpack生产环境.env.production、测试环境.env.development(配置不同环境的打包访问地址)
|
8天前
|
缓存
webpack 打包多页面应用
webpack 打包多页面应用
|
19天前
webpack 打包多页面应用
webpack 打包多页面应用
|
1月前
|
前端开发 开发者
在前端开发中,webpack 作为一个强大的模块打包工具,为我们提供了丰富的功能和扩展性
【9月更文挑战第1天】在前端开发中,Webpack 作为强大的模块打包工具,提供了丰富的功能和扩展性。本文重点介绍 DefinePlugin 插件,详细探讨其原理、功能及实际应用。DefinePlugin 可在编译过程中动态定义全局变量,适用于环境变量配置、动态加载资源、接口地址配置等场景,有助于提升代码质量和开发效率。通过具体配置示例和注意事项,帮助开发者更好地利用此插件优化项目。
65 13
|
6天前
|
JavaScript 前端开发
手写一个简易bundler打包工具带你了解Webpack原理
该文章通过手写一个简易的打包工具bundler,帮助读者理解Webpack的工作原理,包括模块解析、依赖关系构建、转换源代码以及生成最终输出文件的整个流程。
下一篇
无影云桌面