webpack有什么作用?
Webpack 是一个前端资源加载/打包工具,只需要相对简单的配置就可以提供前端工程化需要的各种功能,并且如果有需要它还可以被整合到其他比如 Grunt / Gulp 的工作流。
它可以将各种js,css,图片等静态资源打包到一起,统一管理起来。如下图
webpack版本
目前webpack主要有v1.x和v2.x两个版本,如果之前使用的webpack版本是1.x,想要升级到2.x,可以参考官方的升级指南。本文主要介绍2.X版本的使用。
webpack与其它模块打包工具的区别
如果想看webpack
和其它打包工具,如: jrburke/requirejs
, substack/node-browserify
, jspm/jspm-cli
, rollup/rollup
, brunch/brunch
的对比信息,可以参看官方给的对比表。
安装webpack
首先,并不建议全局安装webpack,因为这样会限制你在其它项目中使用不同版本的webpack。所以建议webpack随项目安装,在项目根目录下,执行下面的命令( 关于npm的使用,可以参考我之前写的npm使用入门)
$ npm install webpack --save-dev
验证安装是否成功
$ node_modules/.bin/webpack -version
2.2.1
创建第一个打包
现在我们通过一个简短的例子,来介绍下webpack的使用流程。
首先,安装好webpack
$ mkdir webpack-demo && cd webpack-demo
$ npm init -y
$ npm install --save-dev webpack
然后创建一个app
目录并在里面创建一个index.js
文件。app/index.js
文件的内容如下
app/index.js
function component () {
var element = document.createElement('div');
/* lodash is required for the next line to work */
element.innerHTML = _.join(['Hello','webpack'], ' ');
return element;
}
document.body.appendChild(component());
index.js
的功能很加单,就是在页面body
标签下添加一个Hello webpack
的字符串。
为了使用上面的index.js
文件,还需要在与app
同级目录下创建一个index.html
文件。
index.html
webpack 2 demo
安装lodash
依赖
$ npm install --save lodash
用浏览器打开index.html
文件,可以看到如下浏览器输出"Hello Webpack"。
我们来看看现在上面的做法有哪些问题:
首先在上面的index.html
文件里,通过script标签指定了依赖lodash
关系。但是在index.html
文件里面看不到它哪里依赖了lodash
。
index.js
在它运行之前依赖lodash
,但是在index.js
文件里面并没有明确的指出它依赖lodash
,只是在脚本里看到使用了个全局变量_
。
通过这种方式来管理javascript容易出现下面的问题:
- 如果依赖缺失或者引入的顺序不对, 会导致整个应用无法正常工作。
- 如果一个依赖引入了但是又没有使用到,浏览器在运行项目时又会白白去下载他们,然而却不会被使用到。
问题既然出现了,那么我们看看使用webpack如何来解决上面的问题。
首先,安装lodash
依赖(前面如果已经做过,这步可以跳过)
$ npm install --save lodash
然后引入lodash
,修改app/index.js
。在最顶部添加上import _ from lodash;
。现在的app/index.js
内容如下:
app/index.js
import _ from 'lodash';
function component() {
var element = document.createElement('div');
element.innerHTML = _.join(["Hello", "World"], ' ');
return element;
}
document.body.appendChild(component());
同时修改index.html
,去掉依赖声明, 并且将引用
app/index.js
修改了dist/bundle.js
。
index.html
webpack 2 demo
现在app/index.js
明确得指明了依赖lodash
, 并且变量_
也不会造成全局变量污染。
用这种方式声明依赖,webpack在最终打包的时候,首先会利用这些声明构建依赖关系图,确保引入依赖顺序的正确性,同时也会删除掉那些声明了但却没有使用到的依赖信息。
现在我们可以使用webpack
命令在进行打包
$ ./node_modules/.bin/webpack app/index.js dist/bundle.js
Hash: fabaab5724cd666116a7
Version: webpack 2.2.1
Time: 490ms
Asset Size Chunks Chunk Names
bundle.js 544 kB 0 [emitted] [big] main
[0] ./~/lodash/lodash.js 540 kB {0} [built]
[1] (webpack)/buildin/global.js 509 bytes {0} [built]
[2] (webpack)/buildin/module.js 517 bytes {0} [built]
[3] ./app/index.js 216 bytes {0} [built]
在dist/bundle.js
文件里,生成了最终的打包信息。
用浏览器打开index.html
, 可以看到输出效果。
使用ES6(ES2015)和webpack
你可能已经注意到,在app/index.js
文件里面,我们引用了ES6的语法import _ from 'lodash'
。尽管这个语法现在还并不被直接被浏览器所支持, 但是我们的代码仍然能被浏览器执行,这是因为webpack对import/export
这些语句做了兼容处理,可以在生成的dist/bundle.js
里看到对于兼容的处理。
但是,需要注意的是。除了improt/export
之外,其它使用到的ES6的语法,webpack是不支持的,需要使用Babel或Bublé做语法转换。
使用配置文件
如果有更复杂的配置信息,我们可以使用配置文件来使用webpack打包代码。只需要创建一个webpack.config.js
配置文件来执行上面的命令。
webpack.config.js
var path = require('path');
module.exports = {
entry: './app/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist')
}
};
首先删除前面生成的dist/bundle.js
文件,避免影响判断后面使用配置文件是否成功。再执行下面的命令
$ ./node_modules/.bin/webpack --config webpack.config.js
Hash: fabaab5724cd666116a7
Version: webpack 2.2.1
Time: 425ms
Asset Size Chunks Chunk Names
bundle.js 544 kB 0 [emitted] [big] main
[0] ./~/lodash/lodash.js 540 kB {0} [built]
[1] (webpack)/buildin/global.js 509 bytes {0} [built]
[2] (webpack)/buildin/module.js 517 bytes {0} [built]
[3] ./app/index.js 216 bytes {0} [built]
小贴士:
如果使用默认的webpack.config.js
文件名,webpack会自动去使用它,可以省去参数--config webpack.config.js
。
配置文件使用非常灵活,可以把加载规则,配置插件等其它增加我们打包功能的指令全部放在里面。
使用webpack和npm
我们也可以把webpack和npm结合起来,将命令添加到package.json
文件里面,以后所有的命令就由npm来统一管理。操作非常简单,只需要修改package.json
文件,添加如下内容即可。
{
...
"scripts": {
"build": "webpack"
},
...
}
因为npm命令启动的时候会自动从项目目录下加载环境变量,所以,不需要指定webpack命令的绝对路径,npm会自动找到它并把它调用起来。
直接运行命令npm run build
即可。
$ npm run build
> [email protected] build /private/tmp/webpack-demo
> webpack
Hash: fabaab5724cd666116a7
Version: webpack 2.2.1
Time: 447ms
Asset Size Chunks Chunk Names
bundle.js 544 kB 0 [emitted] [big] main
[0] ./~/lodash/lodash.js 540 kB {0} [built]
[1] (webpack)/buildin/global.js 509 bytes {0} [built]
[2] (webpack)/buildin/module.js 517 bytes {0} [built]
[3] ./app/index.js 216 bytes {0} [built]
本来完整的命令是./node_modules/.bin/webpack --config webpack.config.js
,由于前面提到过使用默认配置文件名时,配置文件名参数可以省略,即相当于执行./node_modules/.bin/webpack
,然后因为和npm结合,./node_modules/.bin/webpack
的绝对路径信息也可以省略掉,成了webpack
命令,跟我们在package.json
里添加的一样。
{
...
"scripts": {
"build": "webpack"
},
...
}
结尾
通过上面的例子,我们已经掌握了一些基本的打包技巧,为了更加全面的使用webpack,可以继续深入了解
- 一些基本术语
- 关于webpack的配置信息
- 一些底层的API信息
另外附上一个自己看到的觉得不错的教程:
webpack入坑之旅