Webpack早已成为前端开发者必备技能之一,本文从webpack的原理、打包流程以及webpack优化进行分析。webpack配置的文章在网上已经数不胜数了,本文就不作阐述啦。有问题的小伙伴欢迎留言指正~

Webpack核心原理:
Webpack把一切都当作模块,当webpack处理应用程序时,根据给定的一个主文件,递归的构建一个关系依赖图。其中包含应用程序需要的每一个模块,然后把这些模块打包成一个或多个包。

bundle、chunk、module是什么
- bundle:是由webpack打包出来的文件
- chunk:代码块,一个chunk由多个模块组成,用于代码的合并与切割
- module:是开发中的单个模块,在webpack的世界中,一切皆模块,要给模块对应一个文件,webpack会从配置的entry中递归开始查找出所有依赖的模块
何为loader和plugin
Loader: Webpack把一切文件都视为模块,但是原生的js只能解析js文件,如果其它文件格式也想打包的话就需要用到loader。所以loader的作用是使webpack拥有了加载和解析非javascript的能力。它也能实现对不同格式的文件处理,比如将scss转换成css、Typescript转换成js。转换这些文件,从而使其能够被添加到依赖图中。
Plugin : 用来扩展webpack的功能,让webpack拥有更多的灵活性。它并不是直接操作单个文件,而是直接对整个构建过程起作用。在Webpack运行的生命周期中会广播出许多事件,Plugin 可以监听这些事件,使用自身丰富的Api控制 webpack 打包流程的每个环节,实现对 webpack 的自定义功能扩展。
区别总结 : loader实现对不同格式文件的处理,转换这些文件,使其可以被添加到依赖图当中。plugin是用来扩展webpack的功能,不是直接操作文件。它由丰富的自定义api和生命周期事件,从而控制webpack打包流程的每个环节。这是loader做不到的。
Webpack的构建流程

- 初始化参数:从配置文件和shell语句中读取与合并参数,得出最终参数。
- 开始编译:用得到的参数初始化compiler对象,加载所有配置的插件,执行对象的Run方法开始编译。
- 确定入口:根据配置中的entry找出所有入口文件。
- 编译模块:从入口文件出发,调用所有配置的loader对模块进行翻译,再找出该模块所依赖的模块,再递归本步骤。直到所有入口依赖文件都经过了本步骤的处理。(此处为深度优先遍历)
- 完成模板编译:使用loader翻译完所有模块后,得到每个模块被翻译后的最终内容,以及它们之间的依赖关系。
- 输出资源:根据入口和模块之间的依赖关系,组装成一个个包含多个模块的chunk,再把每个 Chunk 转换成一个单独的文件加入到输出列表,这步是可以修改输出内容的最后机会。
- 输出完成:在确定好输出内容后,根据配置确定输出的路径和文件名,把文件内容写入到文件系统。
在以上过程中,Webpack 会在特定的时间点广播出特定的事件,插件在监听到感兴趣的事件后会执行特定的逻辑,并且插件可以调用 Webpack 提供的 API 改变 Webpack 的运行结果。
如何用webpack来优化前端性能
- 压缩代码:删除多余代码,注释,简化代码写法等方式。可以利用
webpack的uglifyjsplugin来压缩JS文件, 利用cssnano(css-loader?minimize)来压缩css。 - 利用CDN加速:在构建过程中,把引用的静态资源路径修改为CDN上的对应路径。可以利用webpack的output参数和loader的publicPath参数来修改资源路径
- Tree shaking:将代码中永远不会用到的片段删除掉,可以在启动Webpack的时候追加参数
--optimize--minimize来实现 - Code splitting: 将代码按路由或组件进行分块,这样可以做到按需加载,同时可以充分利用浏览器缓存。
小结:
正确理解webpack背后的原理与基本知识,可以帮助我们更好的使用webpack这一利器。希望看了本文的盆友可以对webpack可以有个更深入的认识,使用起来更加得心应手。