抓住2019年的尾巴,迎接2020年的到来~
给自己的2019年画上一个完美的句号。
引言
webpack
对于现在的前端开发的你来说,不算陌生,你或许没有真正去了解过它是如何使用的,但你的项目中确实使用过它,因为你项目的打包编译都跟他息息相关~
前阵子刚好在研究webpack
以及其源码相关的知识,如果你跟我一样,好奇webpack
又是怎么工作的?那些奇奇怪怪的配置都是什么东西?分别代表什么意思?
那你不妨花几分钟阅读一下,跟我一起学习回顾一下如何从0到1去了解webpack
的知识, 配置你项目需要的webpack
~
pass
:本文以 webpack4
为例~
什么是webpack?
什么是 webpack
?
官方文档 是这么说:
webpack
是一个现代 JavaScript
应用程序的静态模块打包器(module bundler)
。当 webpack
处理应用程序时,它会递归地构建一个依赖关系图(dependency graph)
,其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle
。
其实,它就是一个模块化打包工具,它所做的事情就是分析你的项目结构,找到JavaScript
模块并对其进行代码转换(scss
转换为css
、Typescript
转换为 Javscript
),文件优化(压缩JavaScript
、CSS
、HTM
L、图片等),模块合并 (把模块分类合并成一个文件)等一系列的操作,最终打包为合适的格式在让你的项目可以在浏览器中运行~
盗用官网的一张图,其主要工作原理就如下图所示~
核心概念
在真正上手 webpack
之前,我们需要对其几个 核心概念 有所了解
-
Entry
:入口路径,webpack
执行构建的第一步的输入文件。 -
Module
:模块,在webpack
里一切皆模块,一个模块对应着一个文件,webpack
会从配置的Entry
开始递归找出所有依赖的模块。 -
Chunk
:代码块,一个Chunk
由多个模块组合而成,用于代码合并与分割。 -
Loader
:模块转换器,用于把模块原内容按照需求转换成新内容,例如scss
到css
的转换等,构建模块的第一步就是使用loader来加载并处理模块内容 -
Plugin
:扩展插件,webpack
的重要组成部分,其webpack
源码的很多核心功能也都是插件实现的,由于webpack
提供了在不同的生命周期内提供了很多不同的hooks
钩子函数,插件的工作原理就是在webpack
构建流程中的不同的(hooks
)时机注入扩展逻辑来改变构建结果或做个性化操作。 -
Output
:输出结果,在webpack
经过一系列处理后最终代码后输出配置。
整个流程串起来大概就是:
webpack
启动后会从Entry
里配置的Module
开始递归解析 Entry
依赖的所有 Module
。 每找到一个 Module
,就会根据配置的Loader
去找出对应的转换规则,对 Module
进行转换后,再解析出当前 Module
依赖的 Module
。
这些模块会以 Entry
为单位进行分组,一个 Entry
和其所有依赖的 Module
被分到一个组也就是一个Chunk
。最后 webpack
会把所有 Chunk
转换成文件输出,在这整个流程中 webpack
会在不同的生命周期内执行配置的 Plugin
里定义的逻辑。
了解了上面的一些概念和流程之后,接下来,我们一步步来配置,打包我们的项目~
初始化项目
创建文件夹
首先,我们创建一个你喜欢的文件夹,并通过 npm init -y
来初始化项目配置,并在其目录下创建一个我们源代码的目录src
和一个打包后的文件输入目录dist
。
创建入口文件 index.js
然后我们在 src
目录下创建一个 index.js
文件,作为我们的打包入口文件,并写上我们熟悉的 console.log('hello world');
作为打包内容。
安装webpack
webpack4
之后将 webpack
和 cli
分成了两个包,我们需要通过 npm install webpack webpack-cli -D
安装我们所需的 webpack
依赖。
ok~ 准备就绪!
遗憾的是,你还是不能直接进行打包,因为我们的 webpack
是在项目下安装的,所以不能直接运行,想要正确运行webpakc
我们可以有下面2种方式:
- 使用
npx
命令,可以直接运行node_modules/.bin
目录下的命令 - 通过配置
package.json
中的scripts
脚本命令进行执行
为了贴近我们的项目,这里我们选择第二种方式
配置package.json
脚本
我们打开package.json
文件,并在 scripts
中配置下面的代码:
"dev" : "webpack --mode development",
"build" : "webpack --mode production",
dev
表示开发模式,build
是生产模式,不同在于 dev
会有很多方便我们开发调试的功能,比如代码不压缩混淆,有开发服务器之类的,我们学习阶段采用 dev
即可~
创建配置文件
这时候,我们已经可以通过 npm run dev
命令打包我们的代码,并在dist
目录下看到我们打包后的 main.js
文件了~
你可能很诧异的蹦出一句:
因为到此,你发现自己什么都还没配置,咋就可以打包了!!
这是因为 webapck4
为了简化我们开发人员繁琐的配置工作,在内部写好了一套配置,惊不惊喜,意不意外!!
那我这肯定不能答应了,不然不就打我脸了么!
要想加载自己的配置,我们需要在我们的项目根目录下创建 webpack.config.js
文件,并创建我们的基础配置。
//path
const path = require('path');
//配置信息
module.exports = {
//入口文件
entry : './src/index.js' ,
//出口文件
output : {
//打包后路径,只能写绝对路径
path : path.resolve(__dirname,'dist'),
//打包后文件名
filename : '[name].[hash].js'
},
//模块转换规则
module : {
},
//插件
plugins : [
],
//开发服务器
devServer : {
}
}
我们注意到 output
中的 filename
中有一个 [name]
,[hash]
,其中name
是 entry
的名字,默认是 main
,hash
是打包根据内容后计算出的一个 hash
值,保证文件的唯一性,可以通过[hash:8]
表示取其前8位。
现在运行 npm run dev
在 dist
目录下就会打包出类似 main.47bfc309d4ba9b75d346.js
的文件。
这里,我们为了方便,先将其改成 main.js
创建index.html
文件
为了方便我们在浏览器测试,我们在我们的 dist
目录创建一个 index.html
,并引入我们编译好的main.js
文件,如下:
//index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>webpack</title>
</head>
<body>
<div id="app">webpack</div>
<script src="main.js"></script>
</body>
</html>
我们在 index.js
文件下加上这么一句话:
document.querySelector('#app').style.color='red';
测试一下打包后的文件好不好使。
运行 npm run dev
,打开我们的 index.html
预览,不出意外的话,结果应该和我一样,页面的 webpack
文字变红,控制台输出 hello world
;
至此,我们才将我们的项目基础配置搞定~
加载css
如果我们现在想加入 css
文件,优化我的样式,首先在 src
目录下创建 stylesheets
目录,并添加 index.css
文件,我们就先以 body { background : #f2f2f2; }
为例,之后在 index.js
中通过 import './stylesheets/index.css'
的方式导入样式文件。
如果现在我们直接进行打包肯定会报错,因为 css
文件并不是 js
模块,webpack
在打包的时候没法直接处理,需要借助转换工具,这转换工具就是 Loader
。
- 什么是
Loader
?
Loader
就是文件转换器,通过使用不同的Loader
,webpack
就可以把不同的文件都转成js
文件,比如CSS
、ES6/7
、JSX
等,它通常有下面几个配置项:
test
:匹配处理文件的扩展名的正则表达式use
:loader
名称,就是你要使用模块的名称include/exclude
:手动指定必须处理的文件夹或屏蔽不需要处理的文件夹query
:为loaders
提供额外的设置选项
接下来,我们来使用 style-loader
,css-loader
来处理我们的 css
文件。
执行 npm install style-loader css-loader -D
进行安装 loader
在 webpack.config.js
中的module
下面添加解析规则:
module : {
rules : [{
test : /\.css$/,
use : ['style-loader','css-loader']
}]
},
通常来说,loader
有下面三种书写方式,上面是通过 use
方式,还有两种方式分别是 直接使用 loader
和使用 use + loader
:
//直接使用loader
module: {
rules: [{
test: /\.css/,
loader:['style-loader','css-loader']
}]
}
//use + loader 的方式
module: {
rules: [{
test: /\.css/,
include: path.resolve(__dirname,'src'),
exclude: /node_modules/,
use: [{
loader: 'style-loader',
options: {
insert:'top'
}
},'css-loader']
}]
}
要注意的是配置多个 loader
是 有顺序 的,webpack
会安装配置的 loader
顺序 从右向左 执行的,配置的时候要格外注意!
拿我们上面的 style-loader
和 css-loader
来说,两个loader
配置的顺序不可调换,因为 css-loader
是解析处理css
里的url
路径,并将css
文件转换成一个模块,style-loader
是 将css
文件变成style
标签插入到head
中的。
现在我们 npm run dev
试试,打包没有报错,预览 index.html
也成功生效,很赞!
配置开发服务器
到此你有没有发现,我们在平时的开发过程中,怎么没有遇到说让我每次通过预览dist
下的 index.html
来看我们打包效果的,这是由于我们平时的开发中会在自己本地起一个服务器,来帮我们做这件事。
现在,我们也来试试~
- 通过
npm i webpack-dev-server –D
安装我们的开发服务器依赖 - 修改我们的启动脚本,将原来的
package.json
中的dev
脚本修改为webpack-dev-server --open
,其中--open
是自动打开浏览器的意思
此时,直接运行 npm run dev
是看不到我们预期的效果的,因为我们还没有对我们的服务器进行配置。
我们在 webpack.config.js
的 devServer
下添加如下配置:
devServer : {
contentBase : path.resolve(__dirname,'dist'),
host : 'localhost' ,
port : 8000 ,
compress : true
}
contentBase
配置开发服务运行时的文件根目录,也就是静态资源访问地址host
开发服务器监听的主机地址port
开发服务器监听的端口,默认是 8080compress
开发服务器是否启动gzip
等压缩
ok,运行 npm run dev
,是不是效果非常棒!
要注意的是,webpack dev server
产生的打包文件是在 内存中!,是 内存中!,硬盘是访问不到的,怎么验证这一点呢?
很简单,你可以删除掉你dist
目录下的 main.js
,重新运行 npm run dev
,你可以看到 dist
目录下并没有 main.js
,但你访问 localhost:8000
确实能正确访问,并且访问 http://localhost:8000/main.js
也能看到打包后的源码,证明它产生的打包文件确实是在你的 内存中。
注意,我们这里打包出来的只有一个 main.js
文件和一个index.css
文件,index.html
文件是我们手动添加进去的,不是打包产生的,如果删掉 index.html
是无法正确访问页面的,内存里可没有 index.html
文件。
我们可以在终端看到以下这些内容:
这些都是我们在启动开发服务器的时候 webpack
给我们的页面注入的 websocket
连接,你可以在你的页面调试器的 network
中的 ws
里看到,
其重要作用就是,监控你文件的变化,可以帮助你重新刷新页面,让你看到更改后的效果,你可以修改一下 index.js
文件试试~
自动生产HTML文件
我们之前是在 dist
目录下写好了 index.html
文件,并在里面通过 script
标签引入我们打包后的内容,即 main.js
~
还记得我们之前打包后的 filename
中可以加入一个 hash
值也区别不同的文件,如果 hash
值发生变化了,我们的 index.html
岂不是找不到资源了?所以我们希望自动能产出HTML
文件,并在里面引入产出后的资源,这样就不必为上面的问题担心了。
我们删除掉 dist
目录下的 index.html
文件,并在 src
目录下创建一个 index.html
文件,我们称它为模板,以它为模板产生 html
文件。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<title>webpack</title>
</head>
<body>
<div id="app">webpack</div>
</body>
</html>
这时,我们需要接触到第一个插件 html-webpack-plugin
!
之前也说了,插件在 webpack
中有很重要的作用,在 webpack
的构建流程中,plugin
用于处理更多其他的一些构建任务,模块代码转换的工作由 loader
来处理,除此之外的其他任何工作都可以交由 plugin
来完成。
- 首先我们需要通过
npm install html-webpack-plugin -D
去安装它。 - 然后在
webpack.config.js
中plugins
下去配置它(需要先通过require
引入)
//自动产出HTML模版
new HtmlWebpackPlugin({
template: './src/index.html',
filename: 'index.html',
hash: true,
minify: {
removeAttributeQuotes: true,
removeComments: true
}
})
其中 template
是指定模板文件,filename
是指定产出后的文件名,hash
是为了避免缓存,可以在产出的资源后面添加hash
值,minify
是 压缩相关的配置,minify.removeAttributeQuotes
是为了去掉属性的双引号,minify.removeComments
是为了压缩文件,删除模板中的注释。
此时,我们运行 npm run dev
访问 localhost:8000
发现已经可以正常访问了,但是 dist
目录下却没有任何东西,因为我们之前提到了,开发服务器打包的文件是写入内存中的,不是硬盘里。
为了方便我们看效果,我们在 package.json
中的 scripts
中在增加一行 "dev-build": "webpack --mode development"
用来打包我们开发环境的代码。
运行 npm run dev-build
脚本,完成之后可以发现 dist
目录已经打包出来了 index.html
文件 和 main.[hash].js
文件,打开 index.html
文件可以发现标签的双引号已经没去掉了,并且引入的脚本也自动加上了 ?[hash]
值。
<!DOCTYPE html>
<html lang=en>
<head>
<meta charset=UTF-8>
<meta name=viewport content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no">
<title>Title</title>
</head>
<body>
<div id=app>webpack</div>
<script type=text/javascript src=main.e6570abab6c2814d1608.js?e6570abab6c2814d1608></script></body>
</html>
预览 index.html
文件,一切也都正常。
pass
:webpack4
以后,如果你看到终端输入有下面这么怪异的一行,
而正巧你又是一个 强迫症患者,在 webpack.config.js
中添加 stats: { children: false }
即可。
支持图片
前端项目中肯定少不了图片资源,如果我们直接在 css
或者 js
文件中引入图片资源去打包,那么肯定是通不过了,因为 webpack
无法识别图片资源,因为图片也不是一个有效的模块。
此时,我们需要引入这个两个 loader
去解决它, file-loader url-loader
,file-loader
解决CSS
等文件中的引入图片路径问题,url-loader
当图片小于limit
的时候会把图片base64
编码,大于limit
参数的时候还是使用file-loader
进行拷贝
- 通过
npm install file-loader url-loader -D
下载依赖 - 在
src
目录下创建一个images
文件夹,存放几张你喜欢的图片 - 在
index.js
和index.css
中引入图片,并将其插入到页面中去(我这里以本地的avatar.jpg
和scene.jpg
为例)
//index.js
import Avatar from './images/avatar.jpg'
let img = new Image();
img.src = Avatar;
document.body.appendChild(img);
//index.css
body{
background-color: #f2f2f2;
background-image: url("../images/scene.jpg");
background-repeat: no-repeat;
}
- 在
webpack.config.js
中的module
下面添加如下配置
{
test:/\.(png|jpg|gif|svg|bmp)$/,
use:{
loader: 'url-loader',
options: {
limit: 10 * 1024,
outputPath: 'images/'
}
}
}
options
中的 limit
就是图片的限制,这里我指定的是 10kb
,小于 10kb
的图片会以 base64
编码输出,outputPath
指定了拷贝文件输出目录,默认是dist
目录下。
现在我们 npm run dev-build
走一波~
也不报错,运行 index.html
文件,也很正常!
编译less 和 sass
现在开发过程中,为了简化我们书写 css
的过程,我们一般项目中引入了 less
和 sass
这样的预加载器~
同样的你不处理之前 webpack
是不认识 less
和 sass
文件的,毕竟它不是一个 js
模块,我们通过需要借助 less-loader
和 sass-loader
来处理这些文件~
- 通过运行
npm install less less-loader -D
npm install node-sass sass-loader -D
分别安装loader
- 在
webpack.config.js
中添加loader
解析规则
{
test: /\.less/,
use: ['style-loader', 'css-loader', 'less-loader']
}, {
test: /\.scss/,
use: ['style-loader', 'css-loader', 'sass-loader']
}
这样,你就可以放心在你的项目里引入 css
预处理了~
分离css
因为CSS
的下载和js
可以并行,当一个HTML
文件很大的时候,那么页面加载肯定会非常慢,那么我们希望可以把CSS
单独提取出来加载,为每个包含 CSS
的 JS
文件创建一个 CSS
文件,按需加载。
我们需要 mini-css-extract-plugin
这么一个插件
- 通过
npm install mini-css-extract-plugin -D
安装模块依赖 - 在
webpack.config.js
中plugins
下去配置一下
new MiniCssExtractPlugin({
filename: 'css/[name].[hash].css',
chunkFilename: "css/[id].css"
})
除此之外,我们的还需要做一个操作就是将我们之前处理css
的 style-loader
改写成下面这种形式:
{
test: /\.css$/,
use: [{
loader: MiniCssExtractPlugin.loader
}, 'css-loader']
},{
test: /\.less/,
use: [{
loader: MiniCssExtractPlugin.loader
}, 'css-loader', 'less-loader']
}, {
test: /\.scss/,
use: [{
loader: MiniCssExtractPlugin.loader
}, 'css-loader', 'sass-loader']
}
趁热打铁,赶紧来试试,npm run dev-build
进行打包~
预览 index.html
页面,打开控制台network
可以发现下载文件的时候多出了一个 main.css
文件,并且我们 html
的 head
头,已经换成了 link
方式,并且你的 dist
目录下会多出一个 css
的文件夹,里面存放打包后的 css
文件。
tips
: 如果你在外部的css
文件中文件中引入图片,而图片放在了images
目录下,那么打包上线后的图片会出现 404
的情况,你可以查看打包后的 css
文件,就可以反向是路径的问题,需要配置一下 publicPath
即可~
{
loader: MiniCssExtractPlugin.loader,
options: {
publicPath: '/'
}
}
注意,这个一般是在 服务器 上会出现,本地打包后没有起服务也是看不到的。
处理CSS3属性前缀
我们在书写 css
的时候,为了浏览器的兼容性,有时候我们必须加入-webkit
,-ms
,-o
,-moz
这些浏览器前缀,但我们又不想去书写这些繁琐的东西,这时候可以交给我们 postcss
来处理~
postcss
的主要功能只有两个:
- 第一个就是前面提到的把
CSS
解析成JavaScript
可以操作的 抽象语法树结构(Abstract Syntax Tree,AST)
- 第二个就是调用插件来处理
AST
并得到结果
我们首先通过 npm install postcss-loader autoprefixer -D
来安装依赖
想要这个 postcss
正常工作,我们需要配置两个东西
- 在根目录下创建
postcss.config.js
配置文件,表示使用autoprefixer
来进行补全
module.exports={
plugins:[require('autoprefixer')]
}
- 在
webpack.config.js
中修改并添加对css
处理的loader
{
test: /\.css$/,
use: [{
loader: MiniCssExtractPlugin.loader
}, 'css-loader', 'postcss-loader'],
include: path.join(__dirname, './src'),
exclude: /node_modules/
}
这里我在我的 index.css
中添加了如下测试代码:
//index.css
::placeholder {
color: orange;
}
并在我的 index.js
中创建了一个 input
控件:
//index.js
let input = document.createElement('input');
document.body.appendChild(input);
运行 npm run dev-build
打包,预览 index.html
,打开调试工具的的 sources
板块,查看 main.css
, 发现对应的前缀已添加,并且我页面的 input
已经变成了 orange
~
转义ES6/ES7
虽然 es6
和 es7
的代码我们已经或多或少都在项目中,但是大部分浏览器对于 es6
和 es7
代码的支持度并不高,很大部分的浏览器还是只能解析 es5
的代码,为了让我们能正常使用 es6
、es7
的代码,我们需要借助 webpack
对其进行转义,转成 es5
代码。
我们需要借助 babel
这个工具,它是一个编译JavaScript
的平台,可以把ES6/ES7
的代码转义为ES5
代码。
- 通过
npm install babel-loader @babel/core @babel/preset-env -D
安装依赖 - 在
webpack.config.js
中添加babel-loader
,因为babel-loader
只是告诉了webpack
怎么处理ES6
,ES7
代码,但它并不会将ES6
,ES7
代码翻译成向后兼容版本的代码,因此需要指定一个preset
,它包含了代码转换的规则
{
test: /\.js$/,
loader : 'babel-loader' ,
exclude:'/node_modules/'
}
- 在我们的项目根目录创建一个
.babelrc
的文件来配置,用来配置我们的babel
相关
{
"presets": [
[
"@babel/preset-env",
{
"targets": {
"browsers": [
"> 1%",
"last 2 versions"
]
},
"debug":true //调试使用
}
]
]
}
- 我们在
index.js
文件中添加以下代码测试一下,并打包测试一下:
const test = (n)=> {
return new Promise(function (resolve) {
setTimeout(()=>{
resolve([1,2,3,4].map(v=>v * v ))
},n*1000)
}).then(res=>{
console.log(res);
})
}
console.log(test)
查看打包后的文件,发现转换的不够彻底,只能针对语法进行了转换,对于 Promise
、map
这些高级用法并没有被转换,这肯定是不行的,我们还要想办法把这些新的特性,兼容到低版本的浏览器里。
我们还需要 babel
提供的另一个工具—— polyfill
,
npm install @babel/polyfill -D
安装它- 在我们的入口文件
index.js
最顶部添加import '@babel/polyfill'
- 运行
npm run dev-build
编译打包,虽然控制台好想没啥变化,但是我们的打包的文件main.js
发生了很大变化,很明显的一点,体积大了好几十倍
这是由于为了兼容低版本浏览器,polyfill
里面添加了很多辅助代码来帮助实现比如 Promise
和 map
这些新特性,默认情况下会被添加到每一个需要它的文件中,并且会全局注入,造成全局污染,如果我们在开发框架之类的,可能会发生冲突。
我们加了 debug
可以在终端看到,确实是加入了不少插件:
为了解决这个问题,我们引入 @babel/runtime
这个模块,来避免重复导入的问题
如果是写第三方库或者框架
- 运行
npm install @babel/runtime @babel/plugin-transform-runtime -D
安装模块依赖 - 配置
@babel/runtime
,并修改一下preset-env
的配置,加上useBuiltIns: 'usage'
,表示会根据业务需求自动转换需要转换的新语法
{
"presets": [
[
"@babel/preset-env",
{
"useBuiltIns": "usage",
"targets": {
"browsers": [
"> 1%",
"last 2 versions"
]
},
"debug":true //调试使用
}
]
],
"plugins": [
[
"@babel/plugin-transform-runtime",
{
"corejs": false,
"helpers": true,
"regenerator": true,
"useESModules": true
}
]
]
}
- 配置完成,ok,我们再来运行
npm run dev-build
打包一次试试
终端日志可以看到注入的辅助代码大幅度较少,文件的大小也大幅度减少,赞!
拷贝静态文件
我们有些项目中的文件,不是 js
,也不是 css
, 图片之类的,比如 README.md
这些静态资源,我也希望能打包到我的项目里,怎么办呢?
其实就是文件的拷贝操作,我们只需要将这些文件拷贝到目标目录下即可,我们可以利用 copy-webpack-plugin
这个插件
- 运行
npm run copy-webpack-plugin -D
安装插件 - 在项目目录下创建一个
static/README.md
的测试文件 - 修改
webpack.config.js
, 将插件添加到配置里去
new CopyWebpackPlugin({
from: path.resolve(__dirname,'src/static'),
to:path.resolve(__dirname,'dist/static')
})
from
是静态资源目录源地址,to
是要拷贝文件的目标地址,so easy~
npm run dev-build
打包运行!
可以发现我们的 dist
目录已经将 src/static
的文件拷贝到了 dist/static
中
打包前清空
我们修改了文件之后,每次打包都会在 dist
目录下产生一个新的 main.[hash].js
, 随着我们打包次数的增加,dist
目录下会生产出一堆的 main.[hash].js
,不出意外,你的dist
目录应该已经有不少了~
为了保证我们每次看到的都是最新的打包资源,而不受之前打包文件的干扰,这里我们需要引入另一个插件—— clean-webpack-plugin
- 通过
npm install clean-webpack-plugin -D
下载插件 - 在
webpack.config.js
中plugins
下去配置它
plugins:[
new CleanWebpackPlugin()
]
pass
:该插件引入方式是稍微有点不同,通过以下这种方式引入:
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
现在,每次打包前都会先清空 dist
目录下的文件,然后才产出打包后的文件,这样看起来就清晰多了!
服务器代理
我们在开发时,有时候希望在同域名下发送 API
请求 ,那么代理某些 URL
会很有用,代理 API
的配置对于 webpack
来说,配置就非常简单了,只需要在 proxy
中添加代理规则即可
proxy : {
"/api/test": {
target: 'http://lohost:3000/',
secure: false,
changeOrigin: true,
pathRewrite: {
'^/api/test': '/test'
}
}
上面这行配置,就可以将 /api/test
开头的接口地址,会被代理到 http://localhost:3000/test
下,如果是https
接口,需要配置 secure
这个参数 为 true
,如果接口跨域,需要配置changeOrigin
这个参数为 true
压缩JS和CSS
我们现在打包出来的文件无论是 js
和 css
都是源文件,我们希望在打包的时候压缩我们的代码,一来是为了安全,二来是可以减少我们打包文件的体积。
我们选择使用terser-webpack-plugin
来压缩js
文件,替换掉之前的 uglifyjs-webpack-plugin
,解决uglifyjs
不支持es6
语法问题,使用 optimize-css-assets-webpack-plugin
来压缩 css
文件
- 运行
npm install terser-webpack-plugin optimize-css-assets-webpack-plugin -D
安装插件 - 在
webpack.config.js
中引入并配置插件
new TerserPlugin({
parallel: true,
cache: true
}),
new OptimizeCSSAssetsPlugin({
assetNameRegExp:/\.css$/g,
cssProcessor:require('cssnano')
})
TerserPlugin
中的 parallel
代表开启多进程,cache
代表设置缓存,OptimizeCSSAssetsPlugin
中加载了一个 cssnano
的东西, cssnano
是PostCSS
的CSS
优化和分解插件,会自动采用格式很好的CSS
,并通过许多优化,以确保最终的生产环境尽可能小。
现在我们在继续打包一次!
查看我们打包后的文件,可以发现 js
和 css
文件都没打包成了一行,搞定!
结语
ok~ 看到这里,想必你对 webpack
已经有了一个比较完善的认识,对常见的一些配置打包的 loader
或者 plugin
都有一定的了解了,总结会发现,套路基本都差不多,需要什么 loader
和 plugin
只要去对应去查找即可~
emmm
,其实 webpack
的功能非常强大,配置也是相当的多样化,这里只是列举了一些比较常见的功能,对你来说也只是一个抛砖引玉的作用,它的内部实现也是相当的复杂,想要真正弄懂 webpack
,还是需要多下一番苦功夫的~
对了,2019年还有几个小时就结束了~
2020年,加油~