本笔记是基于jspang的webpack教程

webpack.config.js

1
2
3
4
5
6
7
8
9
10
11
12
module.exports= {
//入口文件的配置项
entry: {},
//出口文件的配置项
output: {},
//模块:例如解读CSS,图片如何转换,压缩
module: {},
//插件,用于生产模版和各项功能
plugins: [],
//配置webpack开发服务功能
devServer: {}
}

webpack Options

1
2
3
4
5
6
7
8
--config filename //webpack执行某个配置文件
--colors //彩色字
--progress //进度
--display-modules //打包的模块
--display-reasons //打包的原因
--watch //webpack监听文件有修改后自动重新打包
--port 8888 //设置启动端口
--open //启动后自动打开浏览器

Using source maps

1
2
3
4
module.exports = {
devtool: 'inline-source-map',
//开发环境正确指出哪行出错
}
  • source-map:在一个单独文件中产生一个完整且功能完全的文件。这个文件具有最好的source map,但是它会减慢打包速度;
  • cheap-module-source-map:在一个单独的文件中产生一个不带列映射的map,不带列映射提高了打包速度,但是也使得浏览器开发者工具只能对应到具体的行,不能对应到具体的列(符号),会对调试造成不便。
  • eval-source-map:使用eval打包源文件模块,在同一个文件中生产干净的完整版的sourcemap,但是对打包后输出的JS文件的执行具有性能和安全的隐患。在开发阶段这是一个非常好的选项,在生产阶段则一定要不开启这个选项。
  • cheap-module-eval-source-map:这是在打包文件时最快的生产source map的方法,生产的 Source map 会和打包后的JavaScript文件同行显示,没有影射列,和eval-source-map选项具有相似的缺点。

四种打包模式,有上到下打包速度越来越快,不过同时也具有越来越多的负面作用,较快的打包速度的后果就是对执行和调试有一定的影响。

个人意见是,如果大型项目可以使用source-map,如果是中小型项目使用eval-source-map就完全可以应对,需要强调说明的是,source map只适用于开发阶段,上线前记得修改这些调试设置。

module

Loader

  • test:用于匹配处理文件的扩展名的表达式,这个选项是必须进行配置的;
  • use:loader名称,就是你要使用模块的名称,这个选项也必须进行配置,否则报错;
  • include/exclude:手动添加必须处理的文件(文件夹)或屏蔽不需要处理的文件(文件夹)(可选);
  • query:为loaders提供额外的设置选项(可选)。

Loader 的三种写法

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
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
}
]
}
module: {
rules: [
{
test: /\.css$/,
loader: ['style-loader', 'css-loader']
}
]
}
module: {
rules: [
{
test: /\.css$/,
use: [{
loader: 'style-loader'
}, {
loader: 'css-loader'
}]
}
]
}

CSS文件打包

1
2
3
4
5
6
7
8
9
10
yarn add css-loader --dev
yarn add style-loader --dev
// Less
yarn add less --dev
yarn add less-loader --dev
// Sass
yarn add node-sass --dev
yarn add sass-loader --dev
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
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
}, { // less文件配置
test: /\.less$/,
use: [{
loader: "style-loader" // creates style nodes from JS strings
}, {
loader: "css-loader" // translates CSS into CommonJS
, {
loader: "less-loader" // compiles Less to CSS
}]
}, { // scss文件配置
test: /\.scss$/,
use: [{
loader: "style-loader" // creates style nodes from JS strings
}, {
loader: "css-loader" // translates CSS into CommonJS
}, {
loader: "sass-loader" // compiles Sass to CSS
}]
}
]
}

CSS分离

1
yarn add extract-text-webpack-plugin --dev
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
const extractTextPlugin = require("extract-text-webpack-plugin");
module: {
rules: [
{
test: /\.css$/,
use: extractTextPlugin.extract({
fallback: "style-loader",
use: "css-loader"
})
}, {
test: /\.less$/,
use: extractTextPlugin.extract({
use: [{
loader: "css-loader"
}, {
loader: "less-loader"
}],
// use style-loader in development
fallback: "style-loader"
})
}, {
test: /\.scss$/,
use: extractTextPlugin.extract({
use: [{
loader: "css-loader"
}, {
loader: "sass-loader"
}],
// use style-loader in development
fallback: "style-loader"
})
}
]
},
plugins: [
// 参数为打包后的路径
new extractTextPlugin('/css/index.css')
]
  • 有些简单的交互页面中,你的JavasScript页面代码会非常少,而大部分代码都在CSS中,这时候项目组长会要求把CSS单独提取出来,方便以后更改。
  • webpack官方其实并不建议这样作,他们认为CSS就应该打包到JavasScript当中以减少http的请求数。

图片写入CSS

1
2
yarn add url-loader --dev
yarn add file-loader --dev
1
2
3
4
5
6
7
8
9
10
11
12
modul: [
{
test: /\.(png|jpg|gif)$/,
use: [{
loader: 'url-loader',
options: {
limit: 50000,
outputPath: 'images/'
}
}
}
]

params

  • test:/.(png|jpg|gif)/是匹配图片文件后缀名称。
  • use:是指定使用的loader和loader的配置参数。
  • limit:是把小于500000B的文件打成Base64的格式,写入JS。
  • outputPath: 将打包后的图片放到images目录下

limit参数详解:

  • 文件大小小于limit参数,url-loader将会把文件转为DataURL(Base64格式);

  • 文件大小大于limit,url-loader会调用file-loader进行处理,参数也会直接传给file-loader。

file-loader与url-loader作用

  • file-loader:解决引用路径的问题,拿background样式用url引入背景图来说,我们都知道,webpack最终会将各个模块打包成一个文件,因此我们样式中的url路径是相对入口html页面的,而不是相对于原始css文件所在的路径的。这就会导致图片引入失败。这个问题是用file-loader解决的,file-loader可以解析项目中的url引入(不仅限于css),根据我们的配置,将图片拷贝到相应的路径,再根据我们的配置,修改打包后文件引用路径,使之指向正确的文件。

  • url-loader:如果图片较多,会发很多http请求,会降低页面性能。这个问题可以通过url-loader解决。url-loader会将引入的图片编码,生成dataURl。相当于把图片数据翻译成一串字符。再把这串字符打包到文件中,最终只需要引入这个文件就能访问图片了。当然,如果图片较大,编码会消耗性能。因此url-loader提供了一个limit参数,小于limit字节的文件会被转为DataURl,大于limit的还会使用file-loader进行copy。

HTML中的图片

1
yarn add html-withimg-loader --dev
1
2
3
4
5
6
7
8
module: {
rules: [
{
test: /\.(htm|html)$/i,
use:['html-withimg-loader']
}
]
}

处理HTML中img标签src的路径

plugins

压缩js代码

1
2
3
4
5
const uglify = require('uglifyjs-webpack-plugin')
plugins: [
new uglyfy()
]

打包HTML文件

1
yarn add html-webpack-plugin
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const HtmlWebpackPlugin = require('html-webpack-plugin')
plugins: [
new HtmlWebpackPlugin({
hash: true,
minify: {
removeAttributeQuotes: true
},
template: './src/index.html',
title: 'Output Management', //页面title
filename: 'admin.html', //html的文件名
filename: 'html/admin.html',//打包至html文件夹下
inject: true | 'head' | 'body' | false //<scrip></scrip>标签插入的位置
})
]
  • minify:是对html文件进行压缩,removeAttrubuteQuotes是却掉属性的双引号。
  • hash:为了开发中js有缓存效果,所以加入hash,这样可以有效避免缓存JS。
  • template:是要打包的html模版路径和文件名称。

静态资源集中输出

1
yarn add copy-webpack-plugin --dev
1
2
3
4
5
6
7
8
9
10
const CopyWebpackPlugin = require('copy-webpack-plugin')
plugins: [
new CopyWebpackPlugin([
{
from: __dirname + '/src/images',
to: './public'
}
])
]
  • from:要打包的静态资源目录地址,这里的__dirname是指项目目录下,是node的一种语法,可以直接定位到本机的项目目录中。
  • to:要打包到的文件夹路径,跟随output配置中的目录。所以不需要再自己加__dirname。
  • 将项目中的静态文件直接打包到dist目录中。

Cleaning up the /dist folder

1
yarn clean-webpack-plugin --dev
1
2
3
4
5
const CleanWbpackPlugin = require('clean-webpack-plugin')
plugins: [
new CleanWbpackPlugin(['dist']), //打包时清空dist目录
]

devServer(热更新)

1
yarn add webpack-dev-server --dev
1
2
3
4
5
6
7
8
9
10
devServer:{
//设置基本目录结构
contentBase:path.resolve(__dirname,'dist'),
//服务器的IP地址,可以使用IP也可以使用localhost
host:'localhost',
//服务端压缩是否开启
compress:true,
//配置服务端口号
port:1717
}

自动处理CSS属性前缀

安装

1
yarn add postcss-loader autoprefixer --dev

postcss.config.js

1
2
3
4
5
module.exports = {
plugins: [
require('autoprefixer')
]
}
  • postCSS推荐在项目根目录(和webpack.config.js同级),建立一个postcss.config.js文件。

编写loader

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

提取CSS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
module: {
rules: [
{
test: /\.css$/,
use: extractTextPlugin.extract({
fallback: 'style-loader',
use: [
{ loader: 'css-loader', options: { importLoaders: 1 }},
'posstcss-loader'
]
})
}
]
}

给webpack增加babel支持

安装

1
yarn add babel-core babel-loader babel-preset-es2015 babel-preset-react --dev

webpack配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
module: {
rules: [
{
test: /\.(js|jsx)$/,
use: {
loader: 'babel-loader',
options: {
presets: [
'es2015', 'react'
]
}
},
exclude: /node_modules/
}
]
}

.babelrc配置

.babelrc

1
2
3
{
"presets": ["react", "es2015"]
}

  • 虽然babel可以在webpack.config.js中配置,但babel具有非常多的配置选项,如果写在webpack.config.js中会非常雍长不可阅读

webpack.config.js里的loader配置

1
2
3
4
5
6
7
8
9
10
11
module: {
rules: [
{
test: /\.(js|jsx)/,
use: {
loader: 'babel-loader'
},
exclude: /node_modules/
}
]
}

babel-preset-env

1
yarn add babel-preset-env

.babelrc

1
2
3
{
"presets": ["react", "env"]
}

  • 现在官方推荐使用babel-preset-env