解析前端构建工具webpack

  • 白小霁
  • 20 Minutes
  • April 10, 2017

前言

真快呀,过年的时候才对webpack 1的了点感性认识,就做了两个关于Vue的项目,之后就出了webpack 2,怕来不及记录,所以写这篇文章来记录一下Webpack 2。

Webpack概述

webpack is a module bundler for modern JavaScript applications.

上述是来自官方文档的定义,说白了就是webpack = module bundler(加载器),对于webpack来说,所有的文件都是模块,只是处理的方式不一样罢了。

说道学习webpack的难易程度:

It is incredibly configurable, but to get started you only need to understand Four Core Concepts: entry, output, loaders, and plugins.
官网说:「很容易的,只要理解了entry、output、loaders、plugins这四个核心概念,你就入门了!」

所以要好好学英语呀,当然还有一些cli/nodeJS的知识。

webpack配置文件

要想使用webpack,其根目录下会有一个webpack.config.js的文件,大概是这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
// webpack.config.js
var webpack = require("webpack");
var DefinePlugin = require('webpack/lib/DefinePlugin');
module.exports = {
context:process.cwd(),
watch: true,
entry: './index.js',
devtool: 'source-map',
output: {
path: path.resolve(process.cwd(),'dist/'),
filename: '[name].js'
},
resolve: {
alias:{ jquery: process.cwd()+'/src/lib/jquery.js', }
},
plugins: [
new webpack.ProvidePlugin({
$: 'jquery',
_: 'underscore',
React: 'react'
}),
new DefinePlugin({
'process.env': {
'NODE_ENV': JSON.stringify('development')
}
})
],
module: {
loaders: [{
test: /\.js[x]?$/,
exclude: /node_modules/,
loader: 'babel-loader'
}, {
test: /\.less$/,
loaders:['style-loader', 'css-loader','less-loader']
}, {
test: /\.(png|jpg|gif|woff|woff2|ttf|eot|svg|swf)$/,
loader: "file-loader?name=[name]_[sha512:hash:base64:7].[ext]"
}, {
test: /\.html/,
loader: "html-loader?" + JSON.stringify({minimize: false })
} ]
}
};

这个简单的webpack配置文件,基本可以处理大多数的前端业务场景了。

解读webpack配置文件

讲解内容还是以一个Github项目为主:地址

四个核心概念

1. entry

entry就是整个模块的读取入口,根据webpack 2的文档,对entry值有了更多的拓展

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
let base ='./index.js'
//let base = {
// index:'./index.js',
// index1:'./index1.js'
//};
// webpack2 提供了多种配置方案 https://webpack.js.org/configuration/entry-context/#entry
// const dynamic_entry = ()=>base;
// const dynamic_entry_promise=()=>{
// return new Promise((resolve,reject)=>{
// resolve(base)
// })
// }
module.exports = {
entry:base,
output: {
filename: '_[name].js'
}
};

2. output

output这个对象的设置告诉webpack怎样的放置导出的文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
//文档 https://webpack.js.org/configuration/output/
const path =require('path');
let base = {
index:'./index.js',
index1:'./index1.js'
};
module.exports = {
entry:base,
output: {
// 设置导出模块 使用绝对路径
path: path.resolve(__dirname, 'dist'),
// 使用 on-demand-loading 或者加载其余的资源如:图片、文件等
// 起了服务器,设置关于导出文件目录 公共的路径(URL)
publicPath: "/output/dist/",
// 设置包规范格式(写一些模块给别人用,设置过后会根据所给类型打包源码 也有amd cmd的规范)
libraryTarget:'umd',
// 给自己的库起的名字,跟amd规范里difine的中的第一个参数一样
library: "MyLibrary",
// 除entry以外的那些需要加载的文件命名
// chunkhash => webpack对每一个文件编译产生的hash
chunkFilename:'[chunkhash]_[name].js',
// hash值的设置
hashDigestLength:3,
// 导出文件名
// hash ==> webpack编译过程产生的hash值
filename: '[hash]_[name].js'
}
};

3. modules/loaders

对每一个不同文件的处理方式的设定

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//webpack 1的写法
module: {
loaders: [{
test: /\.js[x]?$/,
exclude: /node_modules/,
loader: 'babel-loader'
}]
}
// webpack 2的写法
module:{
rules:[
{
// 是Rule.resource.test的简写
// 作用就是检测condition是否匹配这个resource query
// 是就使用loader编译,反之不用,仅仅是预处理
test: /\.jsx?$/,
// rule.use是数组形式和rule.loaders是它的别名
use:[{
loader: "babel-loader",
}]
},
]
}

4. plugins

plugin是Webpack构建过程中的个性化的处理设置。其中有一些自带的插件。参考文档

1
2
3
4
5
6
7
8
plugins: [
// 自带的压缩代码的插件
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false
}
})
]

这一部分,不知如何讲好,找了一些文档来辅助,辅助文档

以上是核心的四个概念和部分常用配置参数的讲解。

5. resolve

These options change how modules are resolved.
resolve.alias的作用就是对module模块提供别名,和require里的path参数有相似的作用。(可以将一些需要多次引用的模块改成一些东西)

1
2
3
4
5
resolve:{
alias:{
jquery :path.resolve(__dirname,'/src/lib/jquery.js')
}
}

6. devtool

这个是大招了,可以让我们在浏览器的调试工具调试的是否是源码。
如果想要显示源码,就用devtool:source-map

1
2
3
4
5
6
7
8
9
10
11
module.exports = {
// https://webpack.js.org/configuration/devtool/#devtool
devtool:'source-map',
// https://webpack.js.org/configuration/target/#target
target:"web",
entry:"./index.js",
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].js'
},
};