从0到1教你学习并配置webpack

抓住2019年的尾巴,迎接2020年的到来~javascript

给本身的2019年画上一个完美的句号。css

引言

webpack 对于如今的前端开发的你来讲,不算陌生,你或许没有真正去了解过它是如何使用的,但你的项目中确实使用过它,由于你项目的打包编译都跟他息息相关~html

前阵子恰好在研究webpack以及其源码相关的知识,若是你跟我同样,好奇webpack又是怎么工做的?那些奇奇怪怪的配置都是什么东西?分别表明什么意思?前端

那你不妨花几分钟阅读一下,跟我一块儿学习回顾一下如何从0到1去了解webpack的知识, 配置你项目须要的webpack~java

pass:本文以 webpack4 为例~node

什么是webpack?

什么是 webpackwebpack

官方文档 是这么说:es6

webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序须要的每一个模块,而后将全部这些模块打包成一个或多个 bundleweb

其实,它就是一个模块化打包工具,它所作的事情就是分析你的项目结构,找到JavaScript模块并对其进行代码转换(scss 转换为cssTypescript 转换为 Javscript),文件优化(压缩JavaScriptCSSHTML、图片等),模块合并 (把模块分类合并成一个文件)等一系列的操做,最终打包为合适的格式在让你的项目能够在浏览器中运行~正则表达式

盗用官网的一张图,其主要工做原理就以下图所示~

核心概念

在真正上手 webpack 以前,咱们须要对其几个 核心概念 有所了解

  • Entry:入口路径,webpack执行构建的第一步的输入文件。

  • Module:模块,在 webpack 里一切皆模块,一个模块对应着一个文件,webpack 会从配置的 Entry 开始递归找出全部依赖的模块。

  • Chunk:代码块,一个 Chunk 由多个模块组合而成,用于代码合并与分割。

  • Loader:模块转换器,用于把模块原内容按照需求转换成新内容,例如scsscss的转换等,构建模块的第一步就是使用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 以后将 webpackcli 分红了两个包,咱们须要经过 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],其中nameentry 的名字,默认是 mainhash 是打包根据内容后计算出的一个 hash值,保证文件的惟一性,能够经过[hash:8] 表示取其前8位。

如今运行 npm run devdist 目录下就会打包出相似 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 就是文件转换器,经过使用不一样的Loaderwebpack就能够把不一样的文件都转成js文件,好比CSSES6/7JSX等,它一般有下面几个配置项:

  • test:匹配处理文件的扩展名的正则表达式
  • useloader名称,就是你要使用模块的名称
  • include/exclude:手动指定必须处理的文件夹或屏蔽不须要处理的文件夹
  • query:为loaders提供额外的设置选项

接下来,咱们来使用 style-loadercss-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-loadercss-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.jsdevServer 下添加以下配置:

devServer : {
    contentBase : path.resolve(__dirname,'dist'),
    host : 'localhost' ,
    port : 8000 ,
    compress : true
}
复制代码
  • contentBase 配置开发服务运行时的文件根目录,也就是静态资源访问地址
  • host 开发服务器监听的主机地址
  • port 开发服务器监听的端口,默认是 8080
  • compress 开发服务器是否启动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.jsplugins 下去配置它(须要先经过 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 文件,一切也都正常。

passwebpack4之后,若是你看到终端输入有下面这么怪异的一行,

而正巧你又是一个 强迫症患者,在 webpack.config.js 中添加 stats: { children: false } 便可。

支持图片

前端项目中确定少不了图片资源,若是咱们直接在 css 或者 js 文件中引入图片资源去打包,那么确定是通不过了,由于 webpack 没法识别图片资源,由于图片也不是一个有效的模块。

此时,咱们须要引入这个两个 loader 去解决它, file-loader url-loaderfile-loader 解决CSS等文件中的引入图片路径问题,url-loader 当图片小于limit的时候会把图片base64编码,大于limit参数的时候仍是使用file-loader 进行拷贝

  • 经过 npm install file-loader url-loader -D 下载依赖
  • src目录下建立一个 images 文件夹,存放几张你喜欢的图片
  • index.jsindex.css 中引入图片,并将其插入到页面中去(我这里以本地的 avatar.jpgscene.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 的过程,咱们通常项目中引入了 lesssass 这样的预加载器~

一样的你不处理以前 webpack 是不认识 lesssass 文件的,毕竟它不是一个 js 模块,咱们经过须要借助 less-loadersass-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单独提取出来加载,为每一个包含 CSSJS 文件建立一个 CSS 文件,按需加载。

咱们须要 mini-css-extract-plugin 这么一个插件

  • 经过 npm install mini-css-extract-plugin -D 安装模块依赖
  • webpack.config.jsplugins 下去配置一下
new MiniCssExtractPlugin({
    filename: 'css/[name].[hash].css',
    chunkFilename: "css/[id].css"
})
复制代码

除此以外,咱们的还须要作一个操做就是将咱们以前处理cssstyle-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 文件,而且咱们 htmlhead 头,已经换成了 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

虽然 es6es7 的代码咱们已经或多或少都在项目中,可是大部分浏览器对于 es6es7 代码的支持度并不高,很大部分的浏览器仍是只能解析 es5 的代码,为了让咱们能正常使用 es6es7的代码,咱们须要借助 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 怎么处理 ES6ES7 代码,但它并不会将 ES6ES7 代码翻译成向后兼容版本的代码,所以须要指定一个 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)
复制代码

查看打包后的文件,发现转换的不够完全,只能针对语法进行了转换,对于 Promisemap 这些高级用法并无被转换,这确定是不行的,咱们还要想办法把这些新的特性,兼容到低版本的浏览器里。

咱们还须要 babel 提供的另外一个工具—— polyfill

  • npm install @babel/polyfill -D 安装它
  • 在咱们的入口文件 index.js 最顶部添加 import '@babel/polyfill'
  • 运行 npm run dev-build 编译打包,虽然控制台好想没啥变化,可是咱们的打包的文件 main.js 发生了很大变化,很明显的一点,体积大了好几十倍

这是因为为了兼容低版本浏览器,polyfill 里面添加了不少辅助代码来帮助实现好比 Promisemap 这些新特性,默认状况下会被添加到每个须要它的文件中,而且会全局注入,形成全局污染,若是咱们在开发框架之类的,可能会发生冲突。

咱们加了 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.jsplugins 下去配置它
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

咱们如今打包出来的文件不管是 jscss 都是源文件,咱们但愿在打包的时候压缩咱们的代码,一来是为了安全,二来是能够减小咱们打包文件的体积。

咱们选择使用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 的东西, cssnanoPostCSSCSS优化和分解插件,会自动采用格式很好的CSS,并经过许多优化,以确保最终的生产环境尽量小。

如今咱们在继续打包一次!

查看咱们打包后的文件,能够发现 jscss 文件都没打包成了一行,搞定!

结语

ok~ 看到这里,想必你对 webpack 已经有了一个比较完善的认识,对常见的一些配置打包的 loader 或者 plugin 都有必定的了解了,总结会发现,套路基本都差很少,须要什么 loaderplugin 只要去对应去查找便可~

emmm,其实 webpack 的功能很是强大,配置也是至关的多样化,这里只是列举了一些比较常见的功能,对你来讲也只是一个抛砖引玉的做用,它的内部实现也是至关的复杂,想要真正弄懂 webpack ,仍是须要多下一番苦功夫的~

对了,2019年还有几个小时就结束了~

2020年,加油~

相关文章
相关标签/搜索