Fork me on GitHub

细说webpack4.x

文章概述

本篇文章细说webpack4.x。

webpack 4.x

webpack打包工具

打包思想

根据一个入口js文件,通过依赖关系查找需要用到的所有资源,进行打包。

作用

  1. 打包(将多个文件打包成一个js文件,减少服务器压力);
  2. 转化(通过loader将less,sass,ts文件转化成浏览器可以识别的文件);
  3. 优化(单页应用复杂度越来越高,webpack可以对项目进行优化);

webpack结构

  1. 入口:entry
  2. 出口:output
  3. 转化器:loaders
  4. 插件:plugins
  5. 开发服务器:devServer
  6. 模式:mode(分为开发模式和生产模式);

webpack所需环境

  1. 安装node;
  2. 安装yarn;

使用方式

webpack简单打包

  1. 初始化config.json文件;
  2. 安装webpack支持库;
  3. 打包指定的js文件;
初始化config.json

执行如下命令,默认配置一路enter即可:

1
$ npm init
安装webpack

webpack4.x将webpack-cli工具分离出来,所以需要安装webpack和webpack-cli两个库,执行如下命令:

current version: webpack 4.16.1 webpack-cli 3.0.8

1
$ npm install --save-dev webpack webpack-cli
webpack打包指定js文件
  1. 创建dist目录作为打包目录,目录内创建index.html,引用bundle.js文件,此文件就是打包后的js文件;
  2. 创建index.js,根据选择器向index.html中输入hello world;
  3. 通过webpack命令将index.js文件打包到dist目录下,在powshell下执行如下命令:
1
$ node_modules/.bin/webpack src/index.js --output dist/bundle.js
  1. 将打包命令配置到package.json脚本:
1
2
3
4
5
{
"scripts": {
"build-webpack-js-file": "node_modules/.bin/webpack src/index.js --output dist/bundle.js",
}
}
  1. 这种手动打包单个js文件的方式,最终生成bundle.js和main.js文件,main.js是webpack自动生成的,这是因为没有配置webpack.config.js标准打包方法的原因,目前属于多余文件,可以不用管;

webpack配置文件打包

webpack.config.js

简介

webpack.config.js是webpack的配置文件;

配置文件构成

webpack.config.js是webpack的配置文件,结构如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
const path = require('path');

module.exports={
//入口配置: 字符串 表示入口js文件名,json key可以自定义 值即入口js文件路径;
entry: {
enter: './src/index.js'
},
//出口配置
output: {
//path:打包输出的路径地址,必须是绝对路径
path: path.resolve(__dirname, 'dist'),
//打包输出js的文件名
filename: "bundle.js"
},
//插件
plugins: [],
//转换规则
module: {
rules: [],
},
//开发服务器
devServer: {}
};
配置打包执行脚本

config.json中配置webpack打包执行脚本(带执行进度):

1
2
3
4
5
6
7
8
9
10
11
{
"scripts": {
//普通打包,webpack4会有警告,消除警告使用mode模式打包,有优化作用;
"build-webpack": "node_modules/.bin/webpack --progress",
//普通打包:配置文件名称自定义
"build-webpack-alias-config-js": "webpack --config webpack.config.js",
//webpack4 mode打包模式:开发模式和生产模式
"build-webpack-mode-dev": "node_modules/.bin/webpack --mode development --progress",
"build-webpack-mode-prod": "node_modules/.bin/webpack --mode production --progress"
}
}

出口-入口

entry

entry作为webpack打包的入口,可以接受如下值:

  • string:字符串表示的路径文件;
  • json对象:key可以自定义,值为入口js文件路径;
  • 数组:可以配置多入口,数组内js文件按顺序执行打包,

output

output表示出口配置,可配置属性如下:

  • path:打包输出的路径地址,必须是绝对路径;
1
2
//必须使用绝对路径的形式;
path: path.resolve(__dirname, './dist'),
  • filename:出口打包js结果文件名;
1
2
3
4
//指定确切的文件名:
filename: "bundle.js"
//动态指定输出的文件名,多用做多出口:
filename: "[name].bundle.js"

出入口配置

单入口单出口

可以使用字符路径、数组、json对象配置单入口,单入口写法:

1
2
3
4
5
6
7
8
9
10
//写法一:string
entry: './src/index.js',

//写法二:json
entry: {
enter: './src/index.js'
},

//写法三:array
entry: ['./src/index.js'],

1
2
3
4
5
//单出口配置
output: {
path: path.resolve(__dirname, './dist'),
filename: "bundle.js"
},
多入口单出口

数组的方式配置多入口,配置方式如下:

1
2
//数组的方式配置多入口
entry: ['./src/index.js','./src/index2.js'],

1
2
3
4
5
//单出口配置
output: {
path: path.resolve(__dirname, './dist'),
filename: "bundle.js"
},
多入口多出口

使用json对象配置入口,需要同时动态配置出口文件名;

1
2
3
4
5
6
7
8
9
10
11
12
//多入口
entry: {
index: './src/index.js',
index2: './src/index2.js'
},

//多出口动态文件名
output: {
path: path.resolve(__dirname, './dist'),
//多出口打包文件名动态配置输出文件名
filename: "[name].bundle.js"
},

插件

开发服务器插件

webpack-dev-server插件,用于配置开发服务器,在devServer配置项中配置.

下载

current version: 3.1.4

1
$ yarn add webpack-dev-server -D
配置服务
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
const webpack= require('webpack');

module.exports = {
plugins: [
//添加支持热更新的插件,配合devServer使用
new webpack.HotModuleReplacementPlugin(),
],
//开发服务器
devServer: {
//设置服务器访问的基本目录
contentBase: path.resolve(__dirname, 'dist'),
//服务器的ip地址,localhost:
host: 'localhost',
//服务器端口号:
port: 8888,
//启动服务后自动打开页面,此时不需要在config.json脚本中使用--open:
//可在打包脚本最后加' --open'启动服务后在浏览器中打开
open: true,
//开启热更新,需要配置webpack自带的热更新插件
hot: true
}
}
配置执行脚本

config.json中添加执行启动访问本地服务的执行脚本:

1
2
3
4
5
6
7
8
{
"scripts": {
//--open表示服务启动后在浏览器中打开;
"start-dev-server-open": "node_modules/.bin/webpack-dev-server --mode development --progress --open",
//devServer中如果配置open=true,则启动服务后也直接在浏览器中打开;
"start-dev-server": "node_modules/.bin/webpack-dev-server --mode development --progress"
},
}

热更新插件

webpack自带HotModuleReplacementPlugin插件来支持热更新,及时更新修改的地方;

使用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
const webpack = require('webpack');

module.exports = {
plugins: [
//添加支持热更新的插件,配合devServer使用
new webpack.HotModuleReplacementPlugin(),
],
//开发服务器
devServer: {
//...
//开启热更新,需要配置webpack自带的热更新插件
hot: true
}
}

静态资源文件输出插件

有一些静态文件,如excel、word文档等需要原样打包输出,可以使用copy-webpack-plugin插件。

安装
1
$ yarn add copy-webpack-plugin -D
使用

webpack.config.js中使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//静态资源文件原样拷贝输出插件
const CopyWebpackPlugin = require('copy-webpack-plugin');

module.exports={
plugin:[
//静态资源输出:即将一些文档等静态资源原样打包
new CopyWebpackPlugin([{
//文件源
from: path.resolve(__dirname, 'src/assets'),
//目标文件夹
to: './assets'
}]),
]
}

ProvidePlugin(优雅使用第三方库)

ProvidePlugin是webpack自带的插件,用于向全局提供一个入口,来使用第三方工具包,不同于import导入的方式使用第三方库,ProvidePlugin配置的第三方库只有在真正使用时才会被打包;

使用

例如:使用jquery库的方式,在安装jquery后只需配置如下插件,即可在js文件中直接使用第三方库,而无需import:

1
2
3
4
5
6
7
8
9
module.exports={
plugins: [
//优雅的使用第三方库(推荐:用到的时候才会打包)
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery'
}),
]
}

purify-css(消除冗余样式)

???按此配置后,js文件中的样式都会清除

去除没用到的css需要用到purifycss-webpack插件,而这个插件又依赖于purify-css。使用glob工具包配合处理符合条件的路径文件;

注意:purify-css只能消除分离出来的css文件中的冗余代码,所以需要与分离css插件一起使用。

安装
1
$ npm i -D purifycss-webpack purify-css glob
使用
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
//这里以mini-css-extract-plugin来分离css
const MiniCssExtractPlugin = require("mini-css-extract-plugin"); //分离css插件(官方推荐)
const PurifyCSSPlugin = require('purifycss-webpack'); //消除css冗余代码的插件
const glob = require('glob'); //glob用来扫描匹配文件路径

const publicPath = '../';
moudle.exports={
plugins: [
//分离css到单独css文件的插件(官方推荐)
new MiniCssExtractPlugin({
filename: 'css/[name].css',
}),
//消除冗余css样式
new PurifyCSSPlugin({
//glob.sync来进行同步读取匹配的文件路径
paths: glob.sync(path.join(__dirname, 'src/*.html')),
}),
],
module: {
rules: [
{
test: /\.(sa|sc|c)ss$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
publicPath: publicPath,
}
},
'css-loader',
'sass-loader',
]
},
]
}
}

clean-webpack-plugin

clean-webpack-plugin的作用是每次编译钱清除原来的编译文件;

安装

current version: 0.1.19

1
2
3
4
//yarn
$ yarn add clean-webpack-plugin -D
//npm
$ npm i clean-webpack-plugin --D
使用
1
2
3
4
5
6
moudle.exports={
plugins: [
//一般直接填入需要清除的目录即可
new CleanWebpackPlugin(['dist']),
]
};

uglifyjs-webpack-plugin(过时)

uglifyjs-webpack-plugin用来优化js的插件,主要用在js压缩,webpack4.x版本使用’—mode production’编译打包来替代

安装

current version: 1.2.7

1
$ npm i -D uglifyjs-webpack-plugin
使用

直接引入,并配置到插件即可;

1
2
3
4
5
6
7
8
9
//js压缩插件(使用--mode production代替)
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');

moudle.exports={
plugins: [
//压缩js(使用--mode production代替)
new UglifyJsPlugin(),
]
};

html-webpack-plugin

html-webpack-plugin是html文件处理插件

作用
  • 为html文件引入外部资源,如script、link,每次编译后,会为引入的资源的地方为文件名动态添加hash,防止引用缓存的外部文件问题;
  • 可以为入口js文件生成html,比如单页面可以生成一个html文件入口,配置N个html-webpack-plugin可以生成N个页面;
使用步骤

current version: 3.2.0

  1. 安装:
1
$ npm i html-webpack-plugin -D
  1. webpack.config.js中配置:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//引入
const HtmlWebpackPlugin=require('html-webpack-plugin');
//插件配置
module.exprots{
plugins: [
// new HtmlWebpackPlugin(),
new HtmlWebpackPlugin({
//生成的html在资源文件引用处添加序列码,防止引用缓存;
hash: true,
//生成html文件指定标题,需要在模板html的title标签使用<%= htmlWebpackPlugin.options.title%>取标题;
title: 'hello webpack',
//为入口js文件生成的html文件模板:
template: './src/index.html'
}),
],
}
  1. 此时打包,就会根据入口js文件,动态生成html文件;

    如果需要多入口生成多个html文件,参照配置chunks属性;

可配置属性
总览
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
45
46
47
48
49
50
const HtmlWebpackPlugin=require('html-webpack-plugin');

moudle.exports {
entry: {
index: './src/index.js',
index2: './src/index2.js'
},
output: {
path: path.resolve(__dirname, './dist'),
filename: "[name].bundle.js"
},
//插件
plugins: [
// new HtmlWebpackPlugin(),
new HtmlWebpackPlugin({
//生成的html在资源文件引用处添加序列码,防止引用缓存;
hash: true,
//-------------------------------
//生成html文件指定标题,需要在模板html的title标签使用<%= htmlWebpackPlugin.options.title%>取标题;
// title: 'hello webpack',
//-------------------------------
//为入口js文件生成的html文件模板:
template: './src/index.html',
//-------------------------------
//指定根据入口js生成html的文件名
// filename: 'app.html',
//-------------------------------
//inject用于配置打包的js引入的位置,即script标签的位置,默认body底部;
//true 默认值,script标签位于html文件的 body 底部;
//body script标签位于html文件的 body 底部;
//head script标签位于html文件的 head中;
//false 不插入生成的js文件,这个几乎不会用到的;
// inject: 'head',
//-------------------------------
//favicon: 为网页添加标签logo
// favicon: './src/resources/logo.jpg',
//-------------------------------
//html压缩配置
// minify:{
// //移除属性的引号
// removeAttributeQuotes: true,
// //移除空白符
// collapseWhitespace: true
// }
//-------------------------------
//配置哪些js文件打包后需要被引用;
//chunks:['index']
}),
],
}
template

为入口js文件生成的html文件模板:

1
template: './src/index.html'
filename

打包js入口文件,生成的html文件的名称;

1
filename: 'app.html',
title

生成html文件指定标题,需要在模板html的title标签使用<%= htmlWebpackPlugin.options.title%>取标题;

1
title: 'hello webpack',
hash

设置为true,生成的html在资源文件引用处添加序列码,防止引用缓存;

1
hash: true,
inject

inject用来标识script标签应该放在html的哪里,有四个值:true body head false;

  • true 默认值,script标签位于html文件的 body 底部;
  • body script标签位于html文件的 body 底部;
  • head script标签位于html文件的 head中;
  • false 不插入生成的js文件,这个几乎不会用到的;
favicon

给你生成的html文件添加标签栏图标 ,值是一个路径:

1
favicon: './src/resources/logo.jpg'
cache

默认是true的,表示内容变化的时候才生成一个新的文件。

chunks

当使用json对象配置多入口时,chunks接受一个数组,数组内是入口的key,表示html模板需要引用的js入口文件,不配置时默认是全部引用;

案例:根据多入口生成多个html文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
entry: {
index: path.resolve(__dirname, './src/index.js'),
devor: path.resolve(__dirname, './src/devor.js'),
main: path.resolve(__dirname, './src/main.js')
}

plugins: [
new httpWebpackPlugin({
filename: 'index.html',
template: './src/index.html',
chunks: ['index','main']
}),
new httpWebpackPlugin({
filename: 'app.html',
template: './src/index.html',
chunks: ['devor','main']
})
]
minify

html压缩配置,详细请参考官方文档

1
2
3
4
5
6
minify:{
//移除属性的引号
removeAttributeQuotes: true,
//移除空白符
collapseWhitespace: true
}

loader

webpack通过在模块中配置loader来处理各种类型的文件;

babel-loader

babel-loader用来对js进行转码成es5

安装
1
2
//babel转码工具包:
$ npm install --save-dev babel-loader babel-core babel-preset-env
配置babel配置文件[推荐]

.babelrc作为babel的配置文件,简单配置如下:

1
2
3
4
{
//预设转码规则数组,按顺序从后到前查找对应api进行转码;
"presets": ["env"]
}
配置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
module.exports={
module: {
//转换规则
rules: [
//处理js文件
{
test: /\.(js)$/,
//排除node_modules里的js文件
exclude: /(node_modules)/,
use: ['babel-loader']
},
//可以直接在webpack.config.js文件内部配置babel
//{
// test: /\.(js|jsx)$/,
// exclude: /(node_modules)/,
// use: {
// loader: 'babel-loader',
// options: {
// presets: ['env', 'react']
// }
// }
//},
]
}
react转码
安装react支持包
1
$ npm install --save react react-dom babel-preset-react
babel配置支持react转码

.babelrc作为babel的配置文件,简单配置如下:

1
2
3
4
{
//预设转码规则数组,按顺序从后到前查找对应api进行转码;
"presets": ["env","react"]
}
配置loader
1
2
3
4
5
6
7
8
9
10
11
12
13
module.exports={
module: {
//转换规则
rules: [
//处理js文件
{
test: /\.(js|jsx)$/,
//排除node_modules里的js文件
exclude: /(node_modules)/,
use: ['babel-loader']
},
]
}

url-loader

处理外部资源的引用,如图片,url-loader依赖于file-loader。

安装

current version: file-loader 1.1.11 url-loader 1.0.1

1
$ npm install --save-dev url-loader file-loader
使用

1> webpack.config.js配置文件中配置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
moudle.exports={
module: {
rules: [
//处理图片资源
{
test: /\.(png|jpg|gif)$/,
use: [
{
loader: 'url-loader',
options: {
//打包到资源文件的文件大小阀值,低于阀值图片文件以base64引用,不会分离出来
limit: 8192,
//打包后存放(输出)的目录
outputPath: 'resources/images',
//打包后图片文件的存放目录+文件全称
// name: 'resource/[name].[ext]'
name: '[name].[ext]'
}
}
]
}
]
}
}

2> js文件中使用文件资源:

1
2
//直接引用图片资源
import img from './image.png'
1
2
3
4
5
//css中引用
body{
background: url("./resources/bear.jpg") no-repeat;
color: #fff;
}

css-loader

处理css样式,依赖于style-loader

安装

current version: css-loader 1.0.0 style-loader 0.21.0

1
$ npm install --save-dev css-loader style-loader
直接配置css-loader

1> webpack.config.js配置文件中配置loader:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
moudle.exports={
module: {
rules: [
{
//匹配规则,即匹配哪些文件;
test: /\.css$/,
//直接使用css-loader,css样式会打包在js文件里
//方式一:直接用use关键字,值为loader数组,数组内的loader按照依赖顺序进行加载,style-loader必须放在最前面;
use: ['style-loader', 'css-loader'],
//方式二:直接用loader关键字,值为loader数组,style-loader必须放在最前面;
// loader: ['style-loader', 'css-loader'],
//方式三:数组接收json对象,可对loader进行单独配置;
// use: [
// {loader:'style-loader'},
// {loader:'css-loader'},
// {loader:'sass-loader'}
// ]
},
]
}
}

2> js文件中引用css样式:

1
import './index.css';
分离css

分离css,一般都会讲css样式进行分离,分离为独立的css文件,做法有两种,使用extract-text-webpack-plugin或mini-css-webpack-plugin(推荐).

extract-text-webpack-plugin(过时)

current version: 4.0.0-beta.0

1> 安装:

1
2
//webpack4,需要next版本
$ npm install --save-dev extract-text-webpack-plugin@next

2> 使用:

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
const ExtractTextWebpackPlugin = require('extract-text-webpack-plugin'); //分离css插件

const publicPath = '../';
moudle.exports={
plugins: [
//分离css到单独css文件的插件
new ExtractTextWebpackPlugin('css/[name].css'),
],
module: {
rules: [
{
test: /\.css$/,
//配合插件分离出css到单独的css文件
use: ExtractTextWebpackPlugin.extract({
//依赖回调
fallback: "style-loader",
//使用的loader
use: "css-loader",
//css引用外部资源的根目录
publicPath: publicPath,
}),
},
]
}
}
mini-css-webpack-plugin

1> 安装:

current version: 0.4.1

1
$ npm install --save-dev mini-css-extract-plugin

2> 使用:

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
const MiniCssExtractPlugin = require("mini-css-extract-plugin"); //分离css插件(官方推荐)

const publicPath = '../';

moudle.exports={
plugins: [
//分离css到单独css文件的插件(官方推荐)
new MiniCssExtractPlugin({
filename: 'css/[name].css',
})
],
module: {
rules: [
{
test: /\.css$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
publicPath: publicPath,
}
},
'css-loader'
]
},
]
}
}

sass-loader

sass-loader用来将.sass或.scss文件转成.css文件的,同css-loader使用方式类似。

安装

sass-loader依赖于node-sass,需要同时安装,node-sass需要翻墙;

current version: ndoe-sass 4.9.2 sass-loader 7.0.3

1
$ npm install sass-loader node-sass webpack --save-dev
直接使用
1
2
3
4
5
6
7
8
9
10
moudle.exports={
module: {
rules: [
{
test: /\.(sa|sc|c)ss$/,
use: ['style-loader','css-loader','sass-loader'],
},
]
}
}
分离css
extract-text-webpack-plugin
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
const ExtractTextWebpackPlugin = require('extract-text-webpack-plugin'); //分离css插件

const publicPath = '../';
moudle.exports={
plugins: [
//分离css到单独css文件的插件
new ExtractTextWebpackPlugin('css/[name].css'),
],
module: {
rules: [
{
test: /\.(sa|sc|c)ss$/,
//配合插件分离出css到单独的css文件
use: ExtractTextWebpackPlugin.extract({
//依赖回调
fallback: "style-loader",
//使用的loader
use: ['css-loader','sass-loader'],
//css引用外部资源的根目录
publicPath: publicPath,
}),
},
]
}
}
mini-css-webpack-plugin
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
const MiniCssExtractPlugin = require("mini-css-extract-plugin"); //分离css插件(官方推荐)

const publicPath = '../';

moudle.exports={
plugins: [
//分离css到单独css文件的插件(官方推荐)
new MiniCssExtractPlugin({
filename: 'css/[name].css',
})
],
module: {
rules: [
{
test: /\.(sa|sc|c)ss$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
publicPath: publicPath,
}
},
'css-loader',
'sass-loader'
]
},
]
}
}

postcss-loader(兼容性前缀)

css3新增了一些属性,但是针对不同内核的浏览器,需要加不同的前缀才会有效, 如webkit等内核的浏览器,需要加-webkit-才会起作用,这里主要使用postcss-loader工具包里的autoprefixer插件,可以在打包时自动添加相关属性的前缀;

安装

current version: postcss-loader 2.1.6 autoprefixer 9.0.1

1
$ npm i -D postcss-loader autoprefixer
使用

1> 新建postcss配置文件: postcss.config.js:

1
2
3
4
5
module.exports = {
plugins: [
require('autoprefixer')
]
};

2> webpack.config.js中配置postcss-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
//这里以mini-css-extract-plugin来分离css
const MiniCssExtractPlugin = require("mini-css-extract-plugin"); //分离css插件(官方推荐)

const publicPath = '../';
moudle.exports={
plugins: [
//分离css到单独css文件的插件(官方推荐)
new MiniCssExtractPlugin({
filename: 'css/[name].css',
})
],
module: {
rules: [
{
test: /\.(sa|sc|c)ss$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
publicPath: publicPath,
}
},
'css-loader',
'sass-loader',
'postcss-loader'
]
},
]
}
}

optimization(优化配置)

optimization配置项用于在webpack配置文件中优化webpack配置,同时它替代了CommonsChunkPlugin(提取公共模块)插件的功能。

配置示例(带注释)

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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
module.exports={
//webpack4优化配置
optimization: {
//[runtimeChunk]
//可以配置成true,single或者对象,用自动计算当前构建的一些基础chunk信息,类似之前版本中的manifest信息获取方式。
//用来提取entry chunk中的runtime部分函数,形成一个单独的文件,这部分文件不经常变换,方便做缓存。
runtimeChunk: {
//运行时模块名
name: 'manifest'
},
//分离第三方库、公共代码,打包到单独文件
splitChunks: {
//chunks表示操作代码块的范围,有三个可选值:initial(初始块)、async(按需加载块)、all(全部块),默认为all;
chunks: "async",
//压缩前的最小模块大小,默认为0(小于30kb的模块不值得再单独发送一次请求);
minSize: 30000,
//最小被引用次数,默认为1;
minChunks: 1,
//最大的按需(异步)加载次数,默认为1;
maxAsyncRequests: 5,
//最大的初始化加载次数,默认为1;
maxInitialRequests: 3,
//拆分出来块的名字(Chunk Names),默认由块名和hash值自动生成;
name: true,
//打包的分组(分类打包)
cacheGroups: {
//默认分组设置:可以设为false,则不使用默认缓存(default:false)
default: {
minChunks: 2,
//缓存的优先级
priority: -20,
//表示可以使用已经存在的块,即如果满足条件的块已经存在就使用已有的,不再创建一个新的块;
reuseExistingChunk: true,
},
//打包node_modules工具包内的代码
vendor: {
//正则匹配目录
test: /[\\/]node_modules[\\/]/,
//打包后的js包名称
name: 'vendor',
chunks: 'initial',
reuseExistingChunk: false,
priority: -10,
//强制执行
// enforce: true
},
//打包公共的文件
commons: {
//匹配需要打包的目录:src/commons目录下的js文件:
test: /[\\/]src[\\/]commons[\\/]/,
name: "commons",
chunks: "all",
minSize: 0,
priority: 1
},
}
}
}
}

eslint代码检查配置

ESLint是js中目前比较流行的插件化的静态代码检测工具.

非必须

安装

1
2
3
4
5
6
7
8
9
10
$ yarn add eslint 
$ yarn add eslint-loader
$ yarn add babel-eslint
$ yarn add eslint-config-airbnb
//eslint报错格式
$ yarn add eslint-friendly-formatter
//依赖的插件
$ yarn add eslint-plugin-import
$ yarn add eslint-plugin-jsx-a11y
$ yarn add eslint-plugin-react

配置loader

webpack.config.js文件配置支持的loader:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
module.exports ={
//转换规则
rules: [
//eslint:js代码检测工具
{
test: /\.(js|jsx)$/,
loader: "eslint-loader",
//编译前检查
enforce: "pre",
//指定检查的目录
include: [path.resolve(__dirname, './src')],
exclude: /node_modules/,
//这里的配置项参数将会被传递到eslint的CLIEngine
options: {
//指定错误报告的格式规范
formatter: require('eslint-friendly-formatter')
}
},
]
}

添加eslint配置文件

loader中配置了eslint后,还需要配置.eslintrc.js为eslint的配置文件,程序默认会加载它。

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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
module.exports = {
//限定配置文件的使用范围:作用根目录
root: true,

//指定eslint的解析器
parser: 'babel-eslint', //通过babel-eslint来检测ES6代码

//设置解析器选项
parserOptions: {
//按照模块的方式解析
sourceType: 'module'
},

//引用第三方的插件
plugins: [
"react"
],

//声明在代码中的自定义全局变量
// globals:{},

//指定代码运行的宿主环境
env: {
//表示可以使用浏览器的方法
browser: true,
node: true,
jquery: true,
},

//指定eslint规范:此处使用第三方airbnb规则; !!!
//extends: 'airbnb',

//启用额外的规则或覆盖默认的规则
/* 语法格式:key: array
* array的第一个值是错误级别,如下:
* > "off" or 0 - 关闭规则
* > "warn" or 1 - 将规则视为一个警告(不会影响退出码)
* > "error" or 2 - 将规则视为一个错误 (退出码为1)
*/
rules: {
//强制使用一致的缩进
// "indent": ["error", 2],
//强制使用一致的反勾号、双引号或单引号
// "quotes": ["error", "double"],
//要求或禁止使用分号代替
// "semi": ["error", "always"],
//禁用console
// "no-console": "error",

//[es6规则]
//要求箭头函数的参数使用圆括号
// "arrow-parens": 0

//强制使用Windows风格换行符;
"linebreak-style": ["error", "windows"],
//在花括号中允许空格??? import{}还需要有空格
// "object-curly-spacing": ["error", "always", {"arraysInObjects": false, "objectsInObjects": false}]
}
};

执行检查

webpack按照上述配置好了eslint-loader,基本可以正常编译,如果打开了extends规则,就需要按照提示更改错误。

调试

webpack4.x

webpack4.x devServer的—mode production启动模式,可以直接在浏览器直观看到与项目编译前目录结构一样的源码,方便我们进行调试。

1
2
3
4
//config.json文件的执行脚本配置如下:
"scripts": {
"start-dev-server": "node_modules/.bin/webpack-dev-server --mode development"
}

webpack3.x

webpack3.x需要在webpack.config.js文件中配置devtool为source-map即可在浏览器中查看与项目编译前目录结构一项的源码。

注意:source-map开启调试时尽量关闭压缩,上线时要关闭source-map。

1
2
3
module.exports = {
devtool: "source-map",
}
坚持原创技术分享,您的支持将鼓励我继续创作!