webpack笔记(webpack5)
webpack4
- 安装需要装三个,看之前教程都是装一个,导致直接webpack有问题
- npm install webpack --save-dev
- npm install webpack-cli --save-dev
- npm install webpack-dev-server
- 运行可以用Npx webpack xxx --mode none|development|production.或者配置script,dev—>npm run dev
- 安装 & js 打包
npm install webpack --save-dev
npm install webpack-cli
npm install webpack-dev-server
npm install @vue/cli -g
npm install @vue/cli-init -g
npm init
手动创建npm项目package.json
npm init -y
自动创建- 创建webpack.config.js
- 安装淘宝npm(cnpm):
npm install -g cnpm --registry=https://registry.npm.taobao.org npm
- webpack 打包文件 -o 输出文件
- 或者配置webpack.config.js文件放在根目录,然后用命令
webpack --mode development
或者npm run dev
- 最关键的路径要对,一个是webpack.config.js,另一个是package.json路径要对,都得在项目根目录下,否则就会报错,因为上面两个指令也是先从局部找,然后全局
- 3版本就是去掉mode
const path=require('path')
module.exports = {
entry:'./src/main.js',//入口
output:{
path:path.resolve(__dirname,'./dist'),//绝对路径
filename:'bundle.js'
},
mode: 'development' // 生产环境 production:项目 none:没有
}
//package.json
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "webpack --mode development",
"build": "webpack --mode production"
},
module.exports = {
mode: 'none|development|production', // 生产环境
//none好像是会一行,dev...完整代码格式,pro...会压缩
}
* 使用:npx webpack xxx 或者webpack
* 打包(5.0以上):```webpack ./src/main.js -o ./dist/bundle --mode=development```
* 打包(3.0以上):```webpack ./src/main.js ./dist/bundle```
* 一个项目的只能有一个Package.json,而且Name属性不与其他npm包重名
- css打包
- 安装:npm install --save-dev css-loader ts-loader
- css-loader只负责加载
- ts-loader
- sass-loader
- postcss-loader
- style-loader负责将样式添加到DOM里
- 3.0 use:[‘style-loader’,‘css-loader’],使用多个loader从右向左
- 直接import路径即可
- less:
npm install less less-loader --save-dev
- rules是个数组,可以追加规则,比如css,less等
module: {
rules: [
{
test: /\.css$/,
use: [
// [style-loader](/loaders/style-loader)
{
loader: 'style-loader',
},
// [css-loader](/loaders/css-loader)
{
loader: 'css-loader',
options: {
modules: true
}
}
//似乎不可以与下方的loader重复,可以追加,毕竟rules是个数组
]
},
{
test: /\.less$/i,
use:[
{
loader:'style-loader'
},
{
loader:'css-loader'
},
{
loader:'less-loader'
}
]
}
]
}
- 图片资源打包
- url-loader:
npm install url-loader --save-dev
- 如果在html中应用的话,就不用单独import图片资源了
- 需要装file-loader
- 图片大小小于limit用base64编码
- 图片大小大于limit用fileloader
- 每次打包后图片都回到dist,为了保证图片文件路径正确,在output加入publicPath:‘地址’,就是所有url都回到这里,图片会生成一个32位的hash值,防止重复,但是我们需要给他命名规范
name:'img/[name].[hash:8].[exit]'
得在rule下的url-loader加入- [文件名称],不加[],就是文件夹
- [ext]扩展名
- 配置写Option里
- 在webpack5中file-loder和url-loader已经被弃用
- 如果想要继续使用url-loader和file-loader时,可以通过将模块类型设置为’javascript/auto’
- 第二个问题:url-loader默认采用ES模块语法,即import './'的形式,如果想使用commonjs规范的话 则需要在option中配置esModule:false
- webpack5最新通过添加 4 种新模块类型来替换所有这些加载器loader:
- asset/resource发出一个单独的文件并导出 URL。以前可以通过使用file-loader.
- asset/inline导出资产的数据 URI。以前可以通过使用url-loader.
- asset/source导出资产的源代码。以前可以通过使用raw-loader.
- asset自动在导出数据 URI 和发出单独的文件之间进行选择。以前可以通过使用url-loader资产大小限制来实现。
- url-loader:
test: /\.(png|jpg|gif|jpeg)$/i,
type: 'asset/inline'
output:{
path:path.resolve(__dirname,'./dist'),//绝对路径
filename:'bundle.js',
publicPath:'dist/',//涉及到url都会到这里
},
module.exports = {
module: {
rules: [
{
test: /\.(png|jpg|gif)$/i,
use: [
{
loader: 'url-loader',
options: {
limit: 8192,
},
},
],
},
],
},
};
- ES6转ES5
- babel-loader:
npm install -D babel-loader @babel/core @babel/preset-env webpack
- babel-loader:
- 配置vue
- runtime-only:不可以有template,运行效率高,源代码量更少
- runtime-compiler:可以有template
import Vue from 'vue';
调用vue,但是直接打包,会出现runtime-only问题- 所以使用alias别名
resolve:{
//别名
alias:{
'vue$':'vue/dist/vue.esm.js'
}
},
* 如果出现 [Vue warn]: Cannot find element,这和解析顺序有关,可以使用插件HtmlWebpackPlugin或者把<script>放到vue挂载后面
* SPA(simple page web 单页面应用,多的页面用router):SPA 和组件化密不可分,组件化让SPA成为可能,SPA促使组件化编程的落地
* el和template关系打包时
//依赖vue
import Vue from 'vue';
const app=new Vue({
el:"#app",
template:`
<div>
<text>{{msg}}</text>
<button @click="btnClick()"></button>
</div>
`,//替换原来index.html里的<div id="app"></div>
data:{
msg:"Hello World"
},
methods:{
btnClick(){
alert("this is a alert!")
}
}
})
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<!-- <script src="../vuejs/vue.js"></script> -->
<script src='dist/bundle.js'></script>
<!-- <link rel="stylesheet" type="text/css" href="src/css/normal.css" />
--> </head>
<body>
<div id="app"></div>
<script src='dist/bundle.js'></script>
</body>
</html>
* 抽取组件
* 方法1
* 安装vue-loader:npm install -D vue-loader vue-template-compiler
* 配置webpack.config.js,查看文档即可 [vue-loder](https://vue-loader.vuejs.org/zh/)
* 建立vue文件下,建立xxx.vue,然后写入内容,最后在main.js import xxx from 'vue/xxx.xue',然后在components调用
* 可能还要在resovle里配置extensions:['.js','.css','.vue','.less']
* 组件要用root标签,比如div
// webpack.config.js
const { VueLoaderPlugin } = require('vue-loader')
module.exports = {
module: {
rules: [
// ... 其它规则
{
test: /\.vue$/,
loader: 'vue-loader'
}
]
},
plugins: [
// 请确保引入这个插件!4.0以上版本好像
new VueLoaderPlugin()
]
}
//1.配置vue-loader在webpack.config.js
//npm install -D vue-loader vue-template-compiler
//配置webpack.config.js
/*
// webpack.config.js
const { VueLoaderPlugin } = require('vue-loader')
module.exports = {
module: {
rules: [
// ... 其它规则
{
test: /\.vue$/,
loader: 'vue-loader'
}
]
},
plugins: [
// 请确保引入这个插件!
new VueLoaderPlugin()
]
}
*/
//2.配置vue文件
//test.vue
<template>
<div>
<text>{{msg}}</text>
<button @click="f()">按钮</button>
</div>
</template>
<script>
export default {
name:"test",
data() {
return {
msg:"Hello World!"
}
},
methods: {
f(){
console.log("hhh");
alert("hhhh!");
}
}
}
</script>
<style>
</style>
//webpack.config.js
resolve:{
extensions:['.js','.css','.vue','.less'],
//别名
alias:{
'vue$':'vue/dist/vue.esm.js'
}
},
//main.js
//依赖vue
import Vue from 'vue';
import test from './vue/test.vue';//采用.vue文件封装组件
//抽取组件,也可以外部导入,import app from xxx.js xxx.jsexport即可
//终极解决方法是用.vue文件
//方法一
const app=new Vue({
el:"#app",
template:`<test/>`,
components:{
test
}
})
* 方法2
//依赖vue
import Vue from 'vue';
import test from 'vue/test.vue';//采用.vue文件封装组件
//抽取组件,也可以外部导入,import app from xxx.js xxx.jsexport即可
//终极解决方法是用.vue文件
//方法二用组件抽离,自定义或者外部引入
const tem={
template:`
<div>
<text>{{msg}}</text>
<button @click="btnClick()"></button>
</div>
`,
data(){
return {
msg:"Hello World"
}
},
methods:{
btnClick(){
alert("this is a alert!")
}
}
}
//抽取组件,因为组件那边已经有了data,methods等,那么其他的注册的时候就不需要了,直接components里注册
const app=new Vue({
el:"#app",
template:`<tem/>`,
components:{
tem
}
})
* 方法3
//依赖vue
import Vue from 'vue';
import test from 'vue/test.vue';//采用.vue文件封装组件
//抽取组件,也可以外部导入,import app from xxx.js xxx.jsexport即可
//终极解决方法是用.vue文件
//方法二用组件抽离,自定义或者外部引入
const app=new Vue({
el:"#app",
template:`
<div>
<text>{{msg}}</text>
<button @click="btnClick()"></button>
</div>
`,//替换原来index.html里的<div id="app"></div>
data:{
msg:"Hello World"
},
methods:{
btnClick(){
alert("this is a alert!")
}
}
})
* Plugin
* plugin是插件,对现有框架扩充
* 与loader区别在于
* loader用于转换某些类型的模块,他是一个转换器
* plugin是插件,是对webpack本身扩展,是一个扩展器
* 过程
* 通过npm 安装
* 在webpack.config.js中的plugins中配置插件
//给文件加入版权头
const webpack=require('webpack');
new webpack.BannerPlugin('最终版权归admin所有')
/*
打包html的plugin,自动生成script标签,生成Index.html
安装:npm install html-webpack-plugin --save-dev
结果:空白,所以此时可以将原来的publicPath去掉,以及原本Index.html的script标签去掉,然后给插件传个模板,模板为index.html
new htmlWebpackPlugin({
template:'index.html'
})
output:{
path:path.resolve(__dirname,'./dist'),//绝对路径
filename:'bundle.js',
// publicPath:'dist/',//涉及到url都会到这里,但是用了插件后就可以不用了
assetModuleFilename: 'img/[name][hash][ext][query]' //自定义输出文件名
},
*/
/*
js压缩插件
安装:npm install uglifyjs-webpack-plugin@1.1.1 --save-dev
最后调用即可
*/
* 搭建本地服务器
* 特点
* 不会产生dist文件,将打包结果暂时存在内存中,内部的http-sever访问这些文件并读取数据,发送给浏览器
* 减少磁盘的读取,提高构建效率
* webpack-dev-server是webpack官方提供的一个小型Express服务器。使用它可以为webpack打包生成的资源文件提供web服务
* 命令:npm install webpack-dev-server --save-dev
* 结构
* contentBase\static:为哪一个文件夹提供本地服务,默认是根文件夹,可以填写./dist
* port:端口号
* inline:页面实时更新
* historyApiFallback:在SPA页面,依赖HTML5的Hitstory模式
* 运行
* node_modules/.bin/webpack-dev-server
* webpack-dev-server
* npm run dev 但是script里的dev改成:webpack-dev-server 或者 webpack server --mode development
* webpack与webpack-dev-server区别
* webpack
* 一个模块打包器,根据entry指示webpack应该使用哪个模块,来作为构建其内部依赖图的开始。
* 进入入口起点后,webpack 会找出有哪些模块和库是入口起点(直接和间接)依赖的。
* 每个依赖项随即被处理,最后输出到output字段指定的文件中
* 这里如果修改了文件内容,那需要手动执行npm start来执行打包,webpack不会实时更新修改。
* webpack-dev-server
* webpack-dev-server:一个服务器插件,相当于webpack+apache
* 启动一个web服务并实时更新修改
* 启动webpack-dev-server后,在目标文件夹中是看不到编译后的文件的
* 实时编译后的文件都保存到了内存当中。
* 如果不指定PublicPath,那么直接访问localhost:8080即可
* 指定为dist,则应访问localhost:8080/dist
* 区别
* webpack不会实时更新修改,就只是一个打包工具,webpack-dev-server会实时自动更新修改
* webpack打包输出路径,output字段为path,webpack-dev-server打包输出路径,output字段为publicPath(此值为空时默认是项目根目录)
* webpack打包输出的文件,是真的存在于物理地址path中,而webpack-dev-server打包输出的文件,是保存在内存中的,在项目目录中是找不到的。
* webpack-dev-server较webpack的优势
尽管webpack提供了命令webpack --watch来动态监听文件的改变并实时打包,但
* 文件多了打包速度会很慢,
* 且这样的打包的方式不能做到hot replace,即每次webpack编译之后,你还需要手动刷新浏览器。
* webpack-dev-server克服了webpack的以上两个问题,webpack-dev-server主要是启动了一个服务器。它的作用主要是用来服务资源文件(默认在当前目录下,可通过content-base指定)。此外这个Http服务器和client使用了websocket通讯协议,原始文件作出改动后,webpack-dev-server会实时的编译,但是最后的编译的文件并没有输出到目标文件夹,而是保存在内存中。
* 注意
* webpack与webpack-dev-server版本兼容性问题
* webpack分离
* 有些配置开发和生产时不完全用到,所以需要一个抽离,然后在指定路径
* 合并:webpack-merge
* 语法 const webpackMerge=require('webpack-merge');
* module.exports=webpackMerge(base,{})
* 然后在指定路径 dev:webpack --mode development --config ./build/dev.config.js,但是要注意入口和出口文件路径要对
* 端口号问题,已经定义过的端口号,需要重新定义,大概率问题时存在内存中的问题
* 修改output路径 path:path.resolve(__dirname,'../dist'),//绝对路径
npm
- npm i & npm install & -S & -save &
- i是install缩写无区别
- 用npm i安装的模块无法用npm uninstall删除,用npm uninstall i才卸载掉
- npm i会帮助检测与当前node版本最匹配的npm包版本号,并匹配出来相互依赖的npm包应该提升的版本号
- 部分npm包在当前node版本下无法使用,必须使用建议版本
- 安装报错时intall肯定会出现npm-debug.log 文件,npm i不一定
- npm i -S等同于 npm i -save 在运行命令的目录中下载指定的包到node_modules, 如果package.json存在的话, 同时写入到package.json的dependencies字段
- npm i -D等同于npm i --save-dev, 在运行命令的目录中下载指定的包到node_modules, 如果package.json存在的话, 同时写入到package.json的devDependencies字段
- -S (–save) 安装包信息将加入到dependencies(生产阶段的依赖,也就是项目运行时的依赖,就是程序上线后仍然需要依赖)
- -D(–save-dev) 安装包信息将加入到devDependencies(开发阶段的依赖,就是我们在开发过程中需要的依赖,只在开发阶段起作业的)
文档
1、webpack是什么
webpack 是前端的一个项目构建工具,它是基于Node.js开发出来的一个前端工具。WebPack可以看做是模块打包机(bundler),通过分析项目结构,找到JavaScript模块以及其它的一些浏览器不能直接运行的拓展语言(Scss,TypeScript等),并将其打包为合适的格式以供浏览器使用。
2、为什么要使用webpack
2.1、js和css依赖问题(作用域问题)
JavaScript和CSS的依赖问题。开发过程中,JavaScript和CSS的在页面中的顺序问题,经常会造成CSS没起作用,JavaScript的某个变量和方法找不到。
比如之前 Grunt 和 Glup 有的就是利用立即调用的函数表达式(IIFE)来实现作用域问题,但是这种会造成存在无用代码,文件体积过大等问题。
2.2、实现模块的开发和加载(模块化开发)
在没有各个 webpack 搭建的脚手架(create-react-app、vue-cli 等等)之前,我们通过在 HTML5 文件里引入一个个 Javascript 文件来进行开发,这就可能导致并行请求数量过多、存在重复代码(或者可能发生2.1那样的问题)等问题。
而通过 webpack,我们可以使用import、require 来进行模块化开发。
在 webpack 中一切皆模块,js、css、图片、字体都是模块,而且支持静态解析、按需打包、动态加载、代码分离等功能,帮助我们优化代码,提升性能。
import { Hello } from './hello.js'
import './assets/style.css'
import MyImage './assets/img.jpg'
2.2、性能优化
一般浏览器请求的文件越多越耗时,请求的文件越大越耗时,尤其是为了前端项目的代码更清晰,结构更合理,我们采用了MVC,MVVM等很多架构分解出了很多JS文件,无疑又拖慢了网页的速度。为了解决这个问题,一般会采用以下两个方案:
文件合并:浏览器需要下载多个JS文件,而浏览器是有并发限制,也就是同时并发只能下载几个文件。当需要加载的文件非常多,网页的性能可想而知,所以我们需要合并多个文件以减少文件的数量。
文件压缩:我们知道文件越大,下载越慢,而针对JavaScript和CSS,里面的空格,换行这些都是为了让我们读代码时更容易阅读,但是对机器来说,这些对它没有影响。
2.3、提升效率
提高开发效率。主要体现在:
2.3.1、 Vendor前缀
在CSS3使用越来越多的时候,我们都知道一些CSS3的新特性,在不同的浏览器中,CSS有不同的前缀,如果我们手工添加将会很繁琐,而如果使用构建工具,很多构建工具可以自动给我添加CSS的Vendor前缀。关于vendor前缀的学习
2.3.2、新语法
Javascript、CSS 的语法规范在不断更新,但是浏览器的兼容性却不能同步的更新,开发者可以通过 webpack 预处理器进行编译,自由的使用 JS、CSS 等语言的新语法。
webpack 使用 loader 对文件进行预处理。
你可以构建包括 JavaScript 在内的任何静态资源,如 Less、Sass、ES6、TypeScript。通过预处理器将 TypeScript 编译成 JavaScript、SCSS 编译成 CSS、ES6 编译成 ES5 等。
开发者还可以使用 Node.js 轻松编写自己的 loader。常用预处理器:
babel-loader:使用 Babel 加载 ES2015+ 代码并将其转换为 ES5;
less-loader:加载并编译 LESS 文件;
sass-loader:加载并编译 SASS/SCSS 文件;
postcss-loader:使用 PostCSS 加载并转换 CSS/SSS 文件。
2.3.3、 单元测试
JavaScript的单元测试在使用MVC或者MVVM的框架后,变得越来越容易,而单元测试是质量保证的一个很重要的手段,所以在提交之前,使用构建工具自动跑一遍我们的单元测试是非常有必要的,能进一步检测你的项目的健壮性和容错能力。关于MVVM的学习
2.3.4、 代码分析
我们写的JavaScript很多时候会有一些潜在的bug, 比如忘了添加分号,某个变量没有等等,使用一些JavaScript的代码分析工具,可以很好的帮我们检查一些常见的问题。
3、Webpack、Grunt、Gulp
Gulp/Grunt是基于task任务的一种能够优化前端的开发流程的工具,而WebPack是一种模块化的解决方案,是基于整个项目进行构建的。
Gulp/Grunt在一个配置文件中,指明对某些文件进行类似编译,组合,压缩等任务的具体步骤,工具之后可以自动替你完成这些任务。
Gulp/Grunt强调的是前端开发的工作流程,我们可以通过配置一系列的task(Gulp中的gulp.task()方法配置),定义task处理的事务(例如文件压缩合并、雪碧图、启动server、sass/less预编译、版本控制等)然后定义执行顺序,来让gulp执行这些task,从而构建项目的整个前端开发流程。核心是 task runner。
而webpack把你的项目当做一个整体,通过一个给定的主文件(如:index.js),Webpack将从这个文件开始找到你的项目的所有依赖文件,使用loaders处理它们,最后打包为一个(或多个)浏览器可识别的JavaScript文件。
它可以将许多松散的模块按照依赖和规则打包成符合生产环境部署的前端资源。还可以将按需加载的模块进行代码分隔,等到实际需要的时候再异步加载。通过 loader的转换,任何形式的资源都可以视作模块,比如 CommonJs 模块、AMD 模块、ES6 模块、CSS、图片、JSON、Coffeescript、Less 等
如图:
所以, Gulp和Webpack的侧重点是不同的,我们可以总结为一句话:
Gulp侧重于开发整个过程的控制管理
Webpack更侧重于模块打包
4、webpack配置的基本含义
先附上一小段代码示例:
const path = require('path');
module.exports = {
entry: "./app/entry", // string | object | array
// Webpack打包的入口
output: { // 定义webpack如何输出的选项
path: path.resolve(__dirname, "dist"), // string
// 所有输出文件的目标路径
filename: "[chunkhash].js", // string
// 「入口(entry chunk)」文件命名模版
publicPath: "/assets/", // string
// 构建文件的输出目录
/* 其它高级配置 */
},
module: { // 模块相关配置
rules: [ // 配置模块loaders,解析规则
{
test: /\.jsx?$/, // RegExp | string
include: [ // 和test一样,必须匹配选项
path.resolve(__dirname, "app")
],
exclude: [ // 必不匹配选项(优先级高于test和include)
path.resolve(__dirname, "app/demo-files")
],
loader: "babel-loader", // 模块上下文解析
options: { // loader的可选项
presets: ["es2015"]
},
},
},
resolve: { // 解析模块的可选项
modules: [ // 模块的查找目录
"node_modules",
path.resolve(__dirname, "app")
],
extensions: [".js", ".json", ".jsx", ".css"], // 用到的文件的扩展
alias: { // 模块别名列表
"module": "new-module"
},
},
devtool: "source-map", // enum
// 为浏览器开发者工具添加元数据增强调试
plugins: [ // 附加插件列表
// ...
],
}
当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),那么依赖关系图是什么呢?
依赖图指的就是文件和文件直接的依赖关系,webpack中文文档首页就附上了这张图:
4.1、entry(入口)
入口是指依赖关系图的开始,从入口开始寻找依赖,打包构建。
配置示例如下:
module.exports = {
entry: 'index.js',
};
4.2、output(出口\输出)
输出则是用于配置 webpack 构建打包的出口,如打包的位置,打包的文件名等等。
配置示例如下:
module.exports = {
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'my-first-webpack.bundle.js',
},
};
4.3、loader(资源加载器\资源转换器)
webpack 自带 JavaScript 和 JSON 文件的打包构建能力,无需格外配置。
而其他类型的文件,如 CSS、Less、TypeScript、csv\tsv、xml、woff\woff2\ttf、yaml\toml\json5,则需要安装 loader 来进行处理。
loader 让 webpack 能够去处理其他类型的文件,并将它们转换为有效模块,以供应用程序使用,以及被添加到依赖图中。
module.exports = {
module: {
rules: [
{
test: /.txt$/,
use: 'raw-loader'
},{
test: /\.(csv|tsv)$/,
use:'csv-loader'
},{
test:/\.xml$/,
use:'xml-loader'
},test:/\.(css|less)$/,
// style-loader将css放在header
// use:['style-loader','css-loader','less-loader']
//MiniCssExtractPlugin将css样式抽离
use:[MiniCssExtractPlugin.loader,'css-loader','less-loader']
}
···
],
},
};
4.4、plugin(插件\扩展器)
插件则是用于扩展 webpack 的能力,常见的插件有:
ProgressBarPlugin:编译进度条ProgressBarPlugin—npm地址;
BundleAnalyzerPlugin:打包体积分析BundleAnalyzerPlugin—地址;
MiniCssExtractPlugin:提取 CSS 到独立 bundle 文件MiniCssExtractPlugin—webpack中文文档介绍。
配置示例如下:
const HtmlWebpackPlugin = require('html-webpack-plugin'); // 通过 npm 安装
module.exports = {
plugins: [new HtmlWebpackPlugin({ template: './src/index.html' })],
};
插件丰富,开发者社区同样提供了大量插件,也使得 webpack 的可用功能更加多样。
4.5、mode(模式)
webpack5 提供了模式选择,包括开发模式(development)、生产模式(production)、空模式,并对不同模式做了对应的内置优化。可通过配置模式让项目性能更优。
我们需要根据不同模式进行判断,比如生产模式中我们需要代码压缩,不需要devServer之类,
配置示例如下:
module.exports = {
mode: 'development',
};
4.6、 resolve(解析)
resolve 用于设置模块如何解析,常用配置如下:
alias:配置别名,简化模块引入;
extensions:在引入模块时可不带后缀;
symlinks:用于配置 npm link 是否生效,禁用可提升编译速度;
配置示例如下:
module.exports = {
resolve: {
extensions: ['.js', '.jsx', '.ts', '.tsx', '.json', '.d.ts'],
alias: {
'@': paths.appSrc,
},
symlinks: false,
}
}
4.7、optimization(优化)
optimization 用于自定义 webpack 的内置优化配置,一般用于生产模式提升性能,常用配置项如下:
minimize:是否需要压缩 bundle;
minimizer:配置压缩工具,如 TerserPlugin、OptimizeCSSAssetsPlugin;
splitChunks:拆分 bundle;
runtimeChunk:是否需要将所有生成 chunk 之间共享的运行时文件拆分出来;
配置示例如下:
module.exports = {
optimization: {
minimizer: [
// 在 webpack@5 中,你可以使用 `...` 语法来扩展现有的 minimizer(即 `terser-webpack-plugin`),将下一行取消注释
// `...`,
new CssMinimizerPlugin(),
],
splitChunks: {
// include all types of chunks
chunks: 'all',
// 重复打包问题
cacheGroups:{
vendors:{ //node_modules里的代码
test: /[\\/]node_modules[\\/]/,
chunks: "all",
name: 'vendors', //chunks name
priority: 10, //优先级
enforce: true
}
}
},
},
}
5、webpack中常用术语
5.1、Asset
这个术语主要是用来描述我们通常在web应用或者其他应用中用到的图片、字体文件、音视频,以及其他类型的一些文件。这些资源通常为一个个单独的文件,但在webpack中,我们借助style-loader或者css-loader也能进行适当的管理。
5.2、Bundle
bundle通常是由多个不同的模块产生,它是已经加载完毕和被编译后的源代码的最终版本
5.3、Bundle Splitting:
这是webpack优化代码的一种方法,即将一个单独的应用拆解为多个bundle。
通过将多个bundle中公共引入的模块拆解出来,我们可以减少项目的代码量,从而减小应用的体积,并且通过浏览器缓存,我们可以将代码进一步优化。
5.4、Chunk
这个webpack中专用的术语用于管理webpack内部的打包进程。
bundle由许多chunk组成。
chunk有几种类型,比如说“入口”和“子块”。通常chunk和输出的bundle一一对应,但是,有些是一对多的关系。
5.5、Code Splitting
Code Splitting表示将你的代码拆分成多个bundle或chunk,之后你可以按需加载它们,而不是简单地加载一个单独的文件。
5.6、Configration(配置)
webpack的配置文件是一段非常普通的javascript代码,它会输出一个对象,然后webpack将会基于对象中的每个属性开始运行。
5.7、Dependency Graph(依赖关系图)
Dependency Graph只要一个文件依赖另一个文件才能有所作为,webpack把这个文件定义为依赖项。webpack会从一个入口点开始,通过递归的方式构建出一个依赖关系图,这里面包括每一个被拆分的小模块,每一个asset。
(依赖关系图)
5.8、Entry Point
入口点告诉webpack从哪里开始解析,根据构建出来的依赖关系图,从而知道哪些部分将会输出为bundle
5.9、HMR(热更新)
Hot Module Replacement (HMR) : 即热更新,当项目在运行时发生变更、文件新增、文件删除时,整个项目无需全部全局加载。
5.10、Module
相比于一个完整的项目,项目中分散的一个个功能性模块能够提供一个对于程序员来说更加专注的视角。一个编写良好的模块能够形成一个很清晰的抽象结构,保证之后的维护基于此能够变得规范化和开发具有明确性。
5.11、Output
指定输出编译后代码的位置。
注意:即使指定了多个入口点(entry points),Ouput配置项也只能设置一个。
5.12、Target
Target配置用于指定项目的运行环境(browser、nodejs、electron等),以使webpack编译器以不同的方式进行编译
5.13、TreeShaking
TreeShaking是消除未使用/多余的代码,或更准确地说,是实时代码导入。webpack编译器通过分析代码中使用的import语句、引入的代码块的使用情况来判断哪些依赖部分被使用,以及哪些依赖部分没有被使用需要丢弃掉。