Webpack是目前最流行的代码打包工具,大部分命令行打包工具都有借鉴Webpack的设计思想,三大框架都选用Webpack作为推荐的打包工具,大量开源项目也使用它来进行打包,所以学会如何使用它很有必要。
背景
本篇博文是承接先前的一篇博文webpack入门学习-基础篇的入门到进阶层次的文章。文章的核心还是关于如何配置和使用Webpack。并未涵盖Webpack的大部分高级特性。
目前 Webpack的最新版本为v4.7.0。
不过从4.x.x
版本开始,为了改善大型项目Webpack配置困难的痛点,Webpack开始走部分技术推崇的约定大于配置的路线,而现有的比如Vue
之类项目脚手架的webpack工具,仍然依赖的是3.x.x
的版本。
所以本篇文章使用的webpack版本为3.6.0
。
下载
可以通过如下的方式来下载Webpack作为项目开发依赖:
开发依赖的包的信息,会保存在
package.json
文件的devDependencies
字段里。
1 | # NPM |
查看当前Webpack依赖版本
1 | $ .\node_modules\.bin\webpack -v |
- Webpack Github Repo Webpack Github仓库
- Webpack Official Website Webpack官方网站
使用
Webpack需要通过命令行工具(Shell)来进行使用。
查看webpack命令行参数
可以看到webpack支持的参数十分丰富,具体参数用法可以参考官方文档。
1 | $ .\node_modules\.bim\webpack --help |
打包生成信息
每次打包结束后,命令行就会输出如下信息:
1 | Hash: 91e97ca469d808640ddb # 此次打包文件(main.js)的哈希值 |
每次执行打包命令时,如果文件未发生变化,那么打包文件的哈希值是不变的。
命令行工具使用
简单打包单个文件
1 | $ .\node_modules\.bin\webpack .\src\js\main.js ./dist/bundle.js |
- 执行程序 .\node_modules.bin\webpack 因为是在命令行执行所以需要加上路径
- 入口文件 指定一个入口文件,作为要打包的所有资源的注入点。
- 生成文件 打包生成的最终文件,内部已经实现模块化,可为1个或者多个。
命令行监控文件并打包
此种打包模式可以通过在打包命令后添加--watch
来实现,避免每次修改源文件后都需要手动执行打包命令。
通过此种方式运行命令后,命令行程序不会主动退出,每次修改源码后,命令行会显示新的打包结果相关信息。
1 | $ .\node_modules\.bin\webpack .\src\js\main.js ./dist/bundle.js --watch |
NPM Scripts使用
NPM Scripts是Nodejs为NPM提供的可以运行自定义脚本的一个配置字段。
package.json
关键部分如下:
1 | { |
要在watch
的时候复用build
的命令,可以这样实现npm run build -- --watch
项目中使用
项目中使用推荐通过编写webpack.config.js
的方式与NPM Scripts
结合使用。
Webpack会自动尝试加载项目根目录下的webpack.config.js
文件,并导入其内配置好的所有配置,来执行打包。
当然我们可以通过--config
参数来提供一个别的名字的配置文件。
接下来就记录一下如何进行简单且常用的webpack配置。
配置Webpack
在项目根目录下创建
webapck.config.js
文件。
webpack.config.js
文件需要通过Commonjs规范导出一个JavaScript
对象,这个对象将成为webpack的打包配置。
添加环境变量
通常情况下,我们需要将开发过程的环境分为:
- 开发环境
- 生产环境
- 测试环境
在不同的环境中,我们通常会对代码的打包有不同的需求。比如在开发调试过程中,未压缩过的代码可读性更好(当然现在有sourceMap)。但是我们会希望开发过程中项目打包时间比较快,我们可能并不需要执行部分工作。而且,可能以上3个环境,我们都会有不止一个。所以,我们希望环境是可以配置的。
实际应用中,我们可以通过在执行打包命令的时候以传入环境变量参数的方式来区分环境。
比如,在开发环境中,我们可以将表示环境的参数设置为development
,生产环境设置为production
,测试环境设置为test
。
因为操作系统的原因,我们需要通过不同的方式来传入参数,比如Mac OS
或者Linux
中通过NODE_ENV=env_name
来实现,而在windows中,则需要通过set NODE_ENV=env_name
来实现。
这个差异可以通过cross-env
包来消除。
这个对象主要包括了如下字段:
Entry
文件打包的入口,所有的文件都要直接或间接地在这里产生依赖,才能被webpack程序运行时识别到。
配置示例:
1 | module.exports = { |
上面的配置会被webpack转化成如下的形式:
1 | module.exports = { |
最终生成的文件名[chunkName]为main
通常我们会将entry
配置写为如下的形式:
1 | module.exports = { |
app
用来打包页面的主js文件,它可能会随着产品的迭代经常更改。vendors
用来打包项目依赖,dependencies
字段中一些可能长期不变的文件。
优点:可以方便利用文件的强制缓存,加快页面的加载速度,提升用户体验。
参数为数组格式的,会将多个文件打包到一起。
Output
Output用于告知webpack
打包后生成文件的目录,注意只能指定一个输出配置。
要使用此配置,最少需要配置2个属性。
- 提供一个打包后生成的文件名格式。
- 提供一个文件生成的绝对路径。
使用如下:
1 | const path = require('path'); |
因为要使用绝对路径,所以我们需要引入Node内置的path
包。
在配置filename的时候我们可以使用一些模板语法,如[name]
, [chunkHash]
,[hash]
,分别代表:
- name 指定的输入文件名,打包前的文件名
- hash 本次打包的hash值
- chunkHash 本文件的hash值,使用chunkHash能利用文件打包的缓存。
Devtool
此字段用于配置如何生成sourcemap
文件。
可配置参数有none
,#cheap-module-eval-source-map
等。
DevServer
用于配置webpack-dev-server
插件,常用于开发环境中开启本地开发服务器。
依赖于webpack-dev-server
包,需要另外下载:
1 | $ npm install webpack-dev-server -D |
此字段配置方式如下:
1 | module.exports = { |