构建系列之 webpack 窥探下
Webpack 实线
安装
全局安装 webpack
进入项目目录,生成 package.json 文件
安装 webpack 依赖
编译打包
新建 index.html
新建入口文件 main.js
编译 main.js 并打包到 test.js
新建模块 module.js,并修改 main.js
css 文件处理
loader 是 webpack 中一个非常核心的概念,前面提到 loader 是主要用来做文件转化的。虽然 js 代码我们可以用 webpack 处理并且 webpack 会自动处理 js 之间相关的依赖。但是在开发中我们不仅仅有基本的 js 代码处理,我们也需要加载 css、图片,也包括一些高级的将 ES6 转成 ES5 代码,将 TypeScript 转成 ES5 代码,将 scss、less 转成 css,将.jsx、.vue 文件转成 js 文件等等。对于 webpack 本身的能力来说,对于这些转化是不支持的,所以就需要给 webpack 扩展对应的 loader。
loader 使用过程:
步骤一:通过 npm 安装需要使用的 loader
步骤二:在 webpack.config.js 中的 modules 关键字下进行配置
大部分 loader 我们都可以在 webpack 的官网中找到,并且学习对应的用法。
引入 css loader
去掉 loader 前缀
在 main.js 中引入 style.css
引入 less loader
需要安装对应的 loader。注意:我们这里还安装了 less,因为 webpack 会使用 less 对 less 文件进行编译。其次,修改对应的配置文件,添加一个 rules 选项,用于处理.less 文件
ES6 语法处理
在没有引入 babel 等能力的时候,webpack 打包后的 js 文件的 ES6 语法并没有转成 ES5,那么就意味着可能一些对 ES6 还不支持的浏览器没有办法很好的运行我们的代码。在 webpack 中,通过 babel-loader 的方式来接入 babel 的能力,babel 配置文件与单独使用 babel 时相同。
在 webpack 中使用 babel 时建议开启 babel 的缓存能力,即 cacheDiretory,统计显示,在大型项目中,构建速度可以提升近 1 倍,webpack 的配置文件示例如下:
监听
webpack 扩展
webpack 基于其强大的扩展能力,可以让开发者更轻松的定制化实现需求。如果你在社区找不到你的应用场景的解决方案,那就需要自己动手了写 loader 或者 plugin 了。
webpack loader,以 comment-require-loader 为例:
loader 的入口需要导出一个函数,这个函数要干的事情就是转换一个文件的内容。函数接收的参数 content 是一个文件在转换前的字符串形式内容,需要返回一个新的字符串形式内容作为转换后的结果,所有通过模块化导入的文件都会经过 loader。从这里可以看出 loader 只能处理一个个单独的文件而不能处理代码块。
webpack plugin 的两个核心概念:
compiler:从 webpack 启动到退出只存在一个 Compiler,compiler 存放着 webpack 的配置。
compilation:由于 webpack 的监听文件变化自动编译机制,compilation 代表一次编译。
Compiler 和 Compilation 都会分发一系列事件。webpack 生命周期里有非常多的事件,开发者可以根据对应的事件节点定制自己的功能。
以 end-webpack-plugin 为例:
常见的 loader
babel-loader:把 es6 转成 es5;
css-loader:加载 css,支持模块化,压缩,文件导入等特性;
style-loader:把 css 代码注入到 js 中,通过 dom 操作去加载 css;
eslint-loader:通过 Eslint 检查 js 代码;
image-loader:加载并且压缩图片;
file-loader:文件输出到一个文件夹中,在代码中通过相对 url 去引用输出的文件;
url-loader:和 file-loader 类似,文件很小的时候可以 base64 方式把文件内容注入到代码中。
source-map-loader:加载额外的 source map 文件,方便调试。
常见的 plugin
uglifyjs-webpack-plugin:通过 UglifyJS 去压缩 js 代码;
commons-chunk-plugin:提取公共代码;
define-plugin:定义环境变量。
loader 和 plugin 的不同
作用不同:
loader 让 webpack 有加载和解析非 js 的能力;
plugin 可以扩展 webpack 功能,在 webpack 运行周期中会分发很多事件,plugin 可以监听这些事件,并调用 webpack 提供的相应的 api 丰富现有的能力。
用法不同:
loader 在 module.rule 中配置。类型为数组,每一项都是 Object;
plugin 是单独配置的,类型为数组,每一项都是 plugin 实例,参数通过构造函数传入。
总结
在前端卷的无法自拔的情形下,各大脚手架或构建工具层出不穷,最近的 Turbopack 更是宣扬自己比 webpack 快 700 倍,虽说真实场景和数据可信度暂且不论,就形与势来说我们不能仅专注一个构建工具的使用,更不能只停留在表层不深入研究其原理。但不管是老旧项目难以更新换代脱离 webpack 的束缚,还是 webpack 本身的不断进化,我们总之是可以看到 webpack 的架构扩展、插件化等优秀理念的,所以我们要时刻保持着敬畏之心,毕竟技术的推陈出新也是踩在巨人的肩膀上完成的,技术没有银弹,我们需要根据自己的场景选择适用于当下及未来一段时间内的可控变化权衡后所选用的技术。微信首发构建系列之webpack窥探下,欢迎关注微信公众号。
版权声明: 本文为 InfoQ 作者【江湖修行】的原创文章。
原文链接:【http://xie.infoq.cn/article/5bbfbf982c51576cc57200cf1】。
本文遵守【CC-BY 4.0】协议,转载请保留原文出处及本版权声明。
评论