作为准备从事前端开发工作的你,如果还不会使用Webpack对项目打包,是时候补课了!
敲黑板: 咳咳,下面在零配置的情况下,给同学们讲清楚怎么使用Webpack对项目进行打包。
第一步 初始化项目
首先,先在你电脑上的某个目录下创建项目,我暂且在我本地创建一个叫 myapp 的文件夹,打开命令提示符,进入文件夹执行:
#初始化
npm init -y
执行上面命令,会自动按照默认的配置信息在 myapp 这个文件夹下创建一个 package.json 的配置文件。
然后安装 webpack 和 webpack-cli 到开发环境,执行下面命令:
cnpm i webpack webpack-cli -D
安装成功后,打开 package.json 配置文件,会看到多了一项 devDependencies 的配置项:
{
//...
"devDependencies": {
"webpack": "^4.42.1",
"webpack-cli": "^3.3.11"
}
}
到此,项目初始化就完成了!
第二步 创建目录
这里只是演示 webpack 打包的流程,所以不搞那么复杂。我们现在 myapp 文件夹下创建一个 src 的目录,并且在 src 目录下创建三个 .js 的文件,结构如下:
|__ src
|—— hello.js
|—— world.js
|__ index.js
效果如下图:
hello.js 文件内容:
module.exports = 'hello';
world.js 文件内容:
module.exports = 'world';
index.js 文件内容:
const hello = require('./hello');
const world = require('./world');
console.log(`${hello} ${world}`);
第三步 使用webpack对项目打包
1、优化打包命令
上面代码写完之后,我们就可以执行 webpack 命令进行打包了,为了方便后面的打包命令执行,我们需要在 package.json 文件中配置一个 scripts 的运行脚本字段:
"scripts": {
"build": "webpack"
}
PS:配置完"scripts"后,在控制台运行
npm run build就相当于执行了webpack命令。
添加完成后,直接在 myapp 目录下执行 npm run build ,就可以执行打包了,执行效果如下:
执行成功后,会在 myapp 项目目录下自动创建 dist 目录,用于存放打包后的文件。
并且在 dist 目录下生成了 main.js 文件,该文件就是生成的打包文件。我们可以运行该文件,在 myapp 项目根目录下执行:
node dist/main
执行结果:
如果显示 hello world 就证明我们已经实现了对项目的打包操作。
此时,index.js 文件就被打包到了 dis 文件夹下了。但是在控制台的运行结果里有一个警告:
这是提示我们默认使用了 production mode,即生产环境,打开 dist/main.js 文件,里面的代码都是被压缩的,这就说明是生产环境打包。
只需要在 scripts 运行脚本里加两项配置就可以解决这个警告问题了:
"scripts": {
"dev": "webpack --mode development",
"build": "webpack --mode production"
}
配置好后,在运行 npm run dev 命令,打包结果如下:
现在再打开 dist/main.js 文件,就没有出现代码压缩的情况了,而且控制台中也不再报 warning 警告了。
PS: webpack 的打包环境有两种,分别是 production 和 development ,分别对应的是生产环境和开发环境,生产环境就是项目已经部署上线,开始正式对外提供服务了,所以会出现代码压缩的情况。 如果是在开发阶段,我们选择开发环境打包就可以了,即使用 development 。
2、修改打包输出目录
在上面打包的过程中,大家发现 webpack 自动对 src 目录下的文件进行了打包,这是因为 webpack 默认的入口是 src/index.js ,默认的出口是 dist/main.js。
如果要修改 webpack 的默认输出目录,需要用到 webpack 命令的 --output ,下面在 scripts 运行脚本里做修改:
"scripts": {
"dev": "webpack --mode development --output ./output/main.js",
"build": "webpack --mode production --output ./output/main.js"
}
这时再执行 npm run dev 命令,就会将打包文件输出到 'output/main.js' 路径下了。
扩展:使用Babel转换ES6语法
之前的代码中使用了 CommonJS 的 module.exports 语法规范导出的变量,现在我们再尝试使用ES6中的 Module 的 export default 语法实现打包的过程。因为ES6语法在普通的浏览器中是不支持的,会出现报错,所以要使用加载器的方式对项目进行打包。
那么问题来了,我们为什么要在使用ES6的语法重构代码,再次进行打包呢?
这是因为目前很多的组件化开发框架,比如React、Vue等,都是使用的ES6语法,所以为了能够顺利的将这些项目进行打包,我们必须得学习使用Babel的方式转换ES6语法。
在 src 把之前的代码重新做一次修改,内容如下:
// hello.js
export default 'hello';
// world.js
export default 'world';
// index.js
import hello from './hello';
import world from './world';
console.log(`${hello} ${world}`);
这时我们如果直接执行打包命令的话,虽然可以打包成功,但是在一些老点的浏览器或者是移动端浏览器中会报错,这就需要使用Babel来转换ES6语法了。
讲到这,先给大家复习两个概念:
- Babel 是JavaScript的一个编译器,能够将ES6+语法转换为ES5语法,保证浏览器的兼容性。
- Loader 是webpack的一个重要概念,通过Loader可以做一些跟文件自身属性相关的操作,如果这里做的ES6语法转换,用到的是
babel-loader,这个Loader依赖@babel/core和@babel/preset-env。
先执行安装命令:
cnpm i @babel/core babel-loader @babel/preset-env -D
然后在项目的根目录下创建一个babel的配置文件 .babelrc,内容如下:
{
"presets": ["@babel/preset-env"]
}
PS:如果是window系统,直接新建文件,文件名输入 .babelrc 是创建不了的,我们需要将文件名设置为 .babelrc. 后面多加一个点就可以了。
有了 babel-loader,可以使用 webpack 命令的--module-bind来指定对应的文件需要经过怎样的 Loader 处理,所以继续修改 npm scripts:
"scripts": {
"build": "webpack --mode production --module-bind js=babel-loader",
"dev": "webpack --mode development --module-bind js=babel-loader"
}
添加完毕,执行 npm run build,看下 dist/main.js 的文件,就是转换后的 ES5 语法的打包结果了。
最后,给大家介绍几个 webpack-cli 的小技巧:
- 当项目逐渐变大或者使用生产环境打包的时候,Webpack 的编译时间会变长,可以通过参数让编译的输出内容带有进度和颜色: webpack --progress --colors;
- Webpack 的配置比较复杂,很容出现错误,如果出问题,会打印一些简单的错误信息,我们还可以通过参数 --display-error-details 来打印错误详情:webpack --display-error-details; 3.如果不想每次修改模块后都重新编译,那么可以启动监听模式,开启监听模式后,没有变化的模块会在编译后缓存到内存中,而不会每次都被重新编译,所以监听模式的整体速度是很快的:webpack --watch;
- webpack-cli 支持两个快捷选项:-d 和 -p ,分别代表一些常用的开发环境和生产环境的打包。
另外,webpack-cli 命令的选项比较多,详细可以通过 webpack-cli 的文档进行查阅,这里总结我们日常用的最多的几个选项(options):
- –config:指定一个 Webpack 配置文件的路径;
- –mode:指定打包环境的mode,取值为development和production,分别对应着开发环境和生产环境;
- –json:输mode出 Webpack 打包的结果,可以使用webpack --json > stats.json方式将打包结果输出到指定的文件;
- –progress:显示 Webpack 打包进度;
- –watch, -w:watch 模式打包,监控文件变化之后重新开始打包;
- –color, --colors/–no-color, --no-colors:控制台输出的内容是否开启颜色;
- –hot:开启 Hot Module Replacement模式,后面会详细介绍;
- –profile:会详细的输出每个环节的用时(时间),方便排查打包速度瓶颈。