manlili blog

webpack四大核心概念

基本上每个项目都配置有一个 webpack.config.js ,它的作用如同常规的 gulpfile.js/Gruntfile.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
var webpack = require('webpack');
var commonsPlugin = new webpack.optimize.CommonsChunkPlugin('common.js');
module.exports = {
//插件项
plugins: [commonsPlugin],
//页面入口文件配置
entry: {
index : './src/js/page/index.js'
},
//入口文件输出配置
output: {
path: 'dist/js/page',
filename: '[name].js'
},
module: {
//加载器配置
rules: [
{test: /\.css$/, use: 'css-loader'},
{ test: /\.css$/, use: 'style-loader!css-loader' },
{ test: /\.js$/, use: 'jsx-loader?harmony' },
{ test: /\.scss$/, use: 'style!css!sass?sourceMap'},
{ test: /\.(png|jpg)$/, use: 'url-loader?limit=8192'}
]
},
//其它解决方案配置
resolve: {
root: 'E:/github/flux-example/src', //绝对路径
extensions: ['', '.js', '.json', '.scss'],
alias: {
AppStore : 'js/stores/AppStores.js',
ActionType : 'js/actions/ActionType.js',
AppAction : 'js/actions/AppAction.js'
}
}
};

下面来详细介绍一下webpack的四大核心概念

入口entry

entry的字符串或者数组写法

语法:

1
用法:entry: string|Array<string>

举个例子,我们需要在webpack.config.js引入一个入口

1
2
3
4
5
6
const config = {
entry: {
main: 'file.js'
}
};
module.exports = config;

由于上面是entry 属性的单个入口语法,可以简写为:

1
2
3
4
5
const config = {
entry: 'file.js'
};
module.exports = config;

但是我们经常遇见将两个不相干的文件打包成一个文件,这样就需要写成数组方式,举个例子:

1
2
3
4
5
const config = {
entry: ['file.js', 'index.js']
};
module.exports = config;

entry 对象写法

语法:

1
用法:entry: {[entryChunkName: string]: string|Array<string>}

举个例子,我们需要在webpack.config.js引入多个入口(多页面应用),就需要采用对象的方法

1
2
3
4
5
6
7
const config = {
entry: {
app: './src/app.js',
vendors: './src/vendors.js'
}
};
module.exports = config;

上面需要注意的是entry使用了对象的方式,输出的output需要采用动态命名的方法,这个后面介绍到output会详细说明

打包输出output

需要注意的是output使用的绝对路径,webpack1.0可以不用担心,但是webpack2.0需要对路径引进path进行处理一下

用法

1
2
3
4
5
6
7
8
9
10
var path = require("path"); //webpack升级到2.0以后,路径需要引用这个模块
const config = {
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, './dist/js'), //打包后文件放在本地,并且在生成的html引入本地路径js,css等比如
publicPath: "http://cdn.example.com/assets/" //打包后文件放在本地,但是当本地文件被推到生产服务器,比如地址是http://cdn.example.com/assets/,这个时候文件需要引进http://cdn.example.com/assets/打包后文件的名字,publicPath就是将打包后的文件在本地直接引进线上的文件
}
};
module.exports = config;

下面来介绍下output的主要参数

output.filename

指定硬盘每个输出文件的名称。在这里你不能指定为绝对路径!output.path 选项规定了文件被写入硬盘的位置。filename 仅用于命名每个文件。
单个入口你可以写成:

1
2
3
4
5
6
7
8
9
10
var path = require("path"); //webpack升级到2.0以后,路径需要引用这个模块
const config = {
entry: 'file.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, './dist/js')
}
};
module.exports = config;

多个入口的话:
你应该使用以下的替换方式来确保每个文件名都不重复。

1
2
3
[name] 被 chunk 的 name 替换。
[hash] 被 compilation 生命周期的 hash 替换。
[chunkhash] 被 chunk 的 hash 替换。

举个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
var path = require("path"); //webpack升级到2.0以后,路径需要引用这个模块
const config = {
entry: {
a: 'file.js',
b: 'test.js'
}
output: {
filename: '[name]-[hash].js',
path: path.resolve(__dirname, './dist/js')
}
};
module.exports = config;

output.path(必选)

导出目录为绝对路径,需要注意的是output使用的绝对路径,webpack1.0可以不用担心,但是webpack2.0需要对路径引进path进行处理一下
举个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
var path = require("path"); //webpack升级到2.0以后,路径需要引用这个模块
const config = {
entry: {
a: 'file.js',
b: 'test.js'
}
output: {
filename: '[name]-[hash].js',
path: path.resolve(__dirname, './dist/js')
}
};
module.exports = config;

其他参数详见output.options

加载器Loaders

loader 是对应用程序中资源文件进行转换。它们是(运行在 Node.js 中的)函数,可以将资源文件作为参数的来源,然后返回新的资源文件,说成大白话就是将本地文件翻译成浏览器识别的文件。

webpack中有三种方式引用loaders

(1) require方式
举个例子:

1
require('style-loader!css-loader?modules!./styles.css');

上面!是区分多个loaders的标志,?是loaders带的处理参数,类似于web的query。

(2) webpack CLI
也就是直接在gitBash里面执行打包代码的时候直接带上
举个例子:

1
webpack --module-bind jade-loader --module-bind 'css=style-loader!css-loader'

上面这句话是将.jade后缀的文件用jade-loader处理,将.css后缀的文件用style-loader和css-loader处理。

(3)直接在webpack.config.js配置(这个常用)
举个例子:

1
2
3
4
5
6
7
8
module.exports = {
module: {
rules: [
{test: /\.css$/, use: 'css-loader'},
{test: /\.ts$/, use: 'ts-loader'}
]
}
};

上面的意思是将所有以.css后缀结尾的文件用css-loader处理,将所有以.ts后缀结尾的文件用ts-loader处理
如果我们绑定多个loaders,配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
module.exports = {
module: {
rules: [
{test: /\.css$/, use: 'css-loader'},
{
test: /\.ts$/,
use: [
{ loader: 'style-loader'},
{ loader: 'css-loader'}
]
}
]
}
};

如果给loaders配置参数,配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
module.exports = {
module: {
rules: [
{test: /\.css$/, use: 'css-loader'},
{
test: /\.ts$/,
use: [
{ loader: 'style-loader'},
{
loader: 'css-loader',
options: {
modules: true
}
}
]
}
]
}
};

插件Plugins

插件是 webpack 的支柱功能。在你使用 webpack 配置时,webpack 自身也构建于同样的插件系统上,插件目的在于解决 loader 无法实现的其他事。

用法:

由于 plugin 可以携带参数/选项,你必须在 wepback 配置中,向 plugins 属性传入 new 实例。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var path = require("path"); //webpack升级到2.0以后,路径需要引用这个模块
var htmlWebpackPlugin = require('html-webpack-plugin'); //采用CMD的方式引进html-webpack-plugin插件
module.exports = {
entry: {
mian: './src/script/main.js',
test: './src/script/test.js'
},
output: {
path: path.resolve(__dirname, './dist/js'),
filename: '[name]-[hash].js' //区分文件有[name], [hash], [chunkhash]
},
plugins: [ //注意这里是数组的方式
new htmlWebpackPlugin()
]
}

关于plugin的寻找,可以去npm官网上找你需要的插件,上面有配套的参数说明

请我喝杯果汁吧!