Webpack 完整指南
🌈个人主页:前端青山
🔥系列专栏:Webpack篇
🔖人终将被年少不可得之物困其一生
依旧青山,本期给大家带来webpack篇专栏内容:webpack介绍
目录
介绍
一、webpack
1.1、webpack是什么
1.2 webpack五个核心配置
1.2.1 entry入口
1.2.2 output输出
1.2.3mode 模式
1.2.4 loader 加载器(modules)
1.2.5 plugins 插件
1.3 安装webpack
1.4webpack基本使用
1.5 配置访问入口模板文件
1.6 devServer创建
1.7 加载器
1.7.1 加载器概述
1.7.2 打包处理css文件
1.7.3 打包处理scss\less\stylus文件
1.7.4 抽取单个css文件
1.8 图片处理
1.9 复制资源
1.10 js兼容处理
1.11 路径别名与导入后缀省略
1.12 tree-shaking
1.13 externals忽略不打入的包
1.14 搭建React
1.15 搭建Vue2
1.16 搭建vue3
介绍
vue脚手架 vue-cli
底层就是webpack
react脚手架 create-react-app
底层就是webpack
Vite和Webpack都是现代化的前端构建工具,用于打包、转换和优化前端资源。以下是它们的主要差异: 构建速度 Vite相比于Webpack在构建速度方面有优势。它采用了“按需编译”的方式,只编译修改过的文件,而其他未修改的文件则基本可以被复用,避免了不必要的重复构建过程,大大提升了开发体验和构建速度。 开发体验 Vite提供了快速的HMR(Hot Module Replacement)功能,可以使开发者在修改代码后,实时更新页面。相比之下,Webpack的HMR功能需要额外的配置和插件支持。 配置 Vite配置起来相对简单,不需要额外的配置文件,大多数配置可以通过Vite的内置配置完成,比如自定义别名、模块引入方式、热更新等。而Webpack则需要更复杂的配置文件。 生态支持 Webpack的生态非常丰富,有大量的插件和loader可供选择,可以满足各种需求。相比之下,Vite还比较年轻,虽然也有相应的插件可用,但是相对较少。 兼容性 Webpack支持更广泛的浏览器和Node.js版本,而Vite则只支持最新版本的Chrome和Node.js环境。 结论:Vite适用于开发体验优先、性能需求高的项目,包括中大型应用和复杂的组件库;而Webpack则适用于需要更多自定义配置、生态支持更全面的项目,适用于大型应用或定制化项目。
Ø 安装webpack打包工具到本机
Ø 熟知webpack的核心配置
Ø 配置好开发环境devServer
Ø 配置好相关的loader和plugin
一、webpack
官网:webpack
webpack | webpack中文文档 | webpack中文网
1.1、webpack是什么
webpack是一种前端资源构建工具,一个静态模块打包器.在webpack看来,前端的所有资源文件(js/json/css/image/less/sass...)都会作为模块处理。它将根据模块的依赖关系进行静态分析,打包生成对应的静态资源。webpack可以解决当前web开发中所面临的困境,webpack提供了:
Ø 友好的模块化支持
Ø 代码压缩混淆
Ø 处理js/css兼容问题
Ø 性能优化(模块删减)-- tree-shaking(树摆)
注:webpack默认只能针对于js来进行打包处理
目前绝大多数企业中的前端项目,都是基于webpack进行打包构建的(vue/react)。
从 v4.0.0 开始之后,webpack默认可以不用进行任何的配置就可以进行打包工作,然而默认的打包方式不能够满足实际的生产需要,所以还需要进行对应的手动配置。
默认配置文件: webpack.config.js 或 webpackfile.js.
webpack4.0之后,在使用webpack时安装两个包 webpack webpack-cli
1.2 webpack五个核心配置
1.2.1 entry入口
字符串,数组,对象
本项目应该使用哪个模块,来作为构建其内部依赖图的开始(指定打包入口文件)
vue: src/main.js
react: src/index.js
1.2.2 output输出
对象
在哪里输出它所创建的 bundle,以及如何命名这些文件,默认值为 ./dist
vue: dist
react: build
1.2.3mode 模式
字符串
通过选择 development(开发) 或 production(生产) 之中的一个,来设置 mode 参数,你可以启用相应模式下的 webpack 内置的优化
development: 代码不压缩
production: 代码压缩
1.2.4 loader 加载器(modules)
对象,里面写数组
loader让webpack能够去处理那些非js文件(webpack自身只理解js)
1.2.5 plugins 插件
数组
插件则可以用于执行范围更广的任务。插件的范围包括,从打包优化和压缩,一直到重新定义环境中的变量。插件接口功能极其强大,可以用来处理各种各样的任务。
1.3 安装webpack
安装方式2种
Ø 全局安装
cnpm i -g webpack webpack-cli
Ø 局部安装
webpack是运行在node环境中的,Node >= 8.10 和 npm >= 5.6
$ cnpm init -y
$ cnpm i -D webpack webpack-cli
#打包使用的核心代码 webpack
#打包使用时的命令 webpack-cli
安装好后可以通过先前检查webpack的版本以确定是否安装成功:
webpack --version
在package.json文件中配置webpack运行脚本命令
"scripts": {"build": "webpack"},
- webpack-course- configwebpack.config.js- srcmain.js.gitignorepackage.json
1.4webpack基本使用
webpack默认情况下,会在./src目录下面去找index.js入口文件,默认是不需要任何的webpack配置。
默认入口 src/index.js
默认出口 dist/main.js
在项目根目录下面创建一个config/webpack.config.js
文件,此文件是webpack的默认配置文件名称,后续就可以在此目录下面对webpack进行运行打包配置
修改package.json
中的运行命令
{"name": "webpack-course","version": "1.0.0","description": "","main": "index.js","scripts": {"build": "webpack --config config/webpack.config.js"},"keywords": [],"author": "","license": "ISC","devDependencies": {"webpack": "^5.90.3","webpack-cli": "^5.1.4"}
}
如果 配置文件在项目的根目录,则不需要 通过 --config 设置配置文件
假如设定 src/main.js
作为项目的入口文件,则创建 webpack-course/src/main.js
// config/webpack.config.js
// webpack 基于nodejs的
// 书写配置文件得遵循 commonjs 规范
// export default ×
// module.exports √
// 可以暴露对象 也可以暴露一个函数返回一个对象,为了配置方便,采用函数返回对象形式
const path = require('path')
module.exports = function () {return {// mode 环境,development 开发环境,production生产环境// development 打包的项目代码不会压缩// production 生产环境 打包的项目代码会压缩mode: 'development',// 入口说明, 可以理解为从 package.json 所以在的目录开始计算路径// entry: './src/main.js', // 字符串// entry: ['./src/main.js'], // 数组写法entry: { // 对象写法app: './src/main.js'},// 出口说明output: {// 输出的路径一定式绝对路径// __dirname E:\workspace\bk2310\code\webpack-course\config// 确定打包文件的路径为 buildpath: path.resolve(__dirname, '../build'),// 打包出来的文件在 build/static/js// name标识输出的文件名// contenthash: 8 生成8位随机数,也可以直接写为 hash:8// filename: 'static/js/[name].js' // 此处的那么 代表的 entry中的 对象的写法的那个key// filename: 'static/js/[name].[hash:8].js' // [hash:8] 8位随机数filename: 'static/js/[name].[contenthash:8].js' }}
}
如果多次打包,发现 build 文件夹下出现更多打包的文件,并没有删除之前的,需要手动删除
# 删除打包的build目录
$ cnpm i -D clean-webpack-plugin
// config/webpack.config.js
// webpack 基于nodejs的
// 书写配置文件得遵循 commonjs 规范
// export default ×
// module.exports √
// 可以暴露对象 也可以暴露一个函数返回一个对象,为了配置方便,采用函数返回对象形式
const path = require('path')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
module.exports = function () {return {// mode 环境,development 开发环境,production生产环境// development 打包的项目代码不会压缩// production 生产环境 打包的项目代码会压缩mode: 'development',// 入口说明, 可以理解为从 package.json 所以在的目录开始计算路径// entry: './src/main.js', // 字符串// entry: ['./src/main.js'], // 数组写法entry: { // 对象写法app: './src/main.js'},// 出口说明output: {// 输出的路径一定式绝对路径// __dirname E:\workspace\bk2310\code\webpack-course\config// 确定打包文件的路径为 buildpath: path.resolve(__dirname, '../build'),// 打包出来的文件在 build/static/js// name标识输出的文件名// contenthash: 8 生成8位随机数,也可以直接写为 hash:8// filename: 'static/js/[name].js' // 此处的那么 代表的 entry中的 对象的写法的那个key// filename: 'static/js/[name].[hash:8].js' // [hash:8] 8位随机数filename: 'static/js/[name].[contenthash:8].js' },// webpack的插件,书写形式为一个数组plugins: [new CleanWebpackPlugin() // 清除缓存文件]}
}
1.5 配置访问入口模板文件
在项目根目录下面创建一个public目录,并在此目录中创建一个index.html文件,
<!-- public/index.html -->
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>webpack course</title>
</head>
<body><div id="root"></div>
</body>
</html>
使用webpack
的 html-webpack-plugin
插件,可以将此文件用于项目web入口文件模块
# 安装
$ cnpm i -D html-webpack-plugin
// webpack 基于nodejs的
// 书写配置文件得遵循 commonjs 规范
// export default ×
// module.exports √
// 可以暴露对象 也可以暴露一个函数返回一个对象,为了配置方便,采用函数返回对象形式
const path = require('path')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const HTMLWebpackPlugin = require('html-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = function () {return {// mode 环境,development 开发环境,production生产环境// development 打包的项目代码不会压缩// production 生产环境 打包的项目代码会压缩mode: 'development',// 入口说明, 可以理解为从 package.json 所以在的目录开始计算路径// entry: './src/main.js', // 字符串// entry: ['./src/main.js'], // 数组写法entry: { // 对象写法app: './src/main.js'},// 出口说明output: {// 输出的路径一定式绝对路径// __dirname E:\workspace\bk2310\code\webpack-course\config// 确定打包文件的路径为 buildpath: path.resolve(__dirname, '../build'),// 打包出来的文件在 build/static/js// name标识输出的文件名// contenthash: 8 生成8位随机数,也可以直接写为 hash:8// filename: 'static/js/[name].js' // 此处的那么 代表的 entry中的 对象的写法的那个key// filename: 'static/js/[name].[hash:8].js' // [hash:8] 8位随机数filename: 'static/js/[name].[contenthash:8].js' },// webpack的插件,书写形式为一个数组plugins: [new CleanWebpackPlugin(), // 清除缓存文件// new HtmlWebpackPlugin(), // 打包的文件夹内自动生成了一个 index.html 文件并且引入了打包文件new HTMLWebpackPlugin({ // 自动配置页面模板文件template: './public/index.html',// 默认引入js在head内,可以修改为bodyinject: 'body',// 压缩minify: {// 删除html模版中的注释语句removeComments: true,// 压缩HTML代码collapseWhitespace: true,// 删除属性的引号removeAttributeQuotes: true// https://www.npmjs.com/package/html-webpack-plugin}})]}
}
1.6 devServer创建
我们已经可以使用打包工具去将写好的代码进行打包了,但是在操作的过程中大家可能会发现有一个比较麻烦的地方:修改一次代码就得重新打包一次,那么有没有在开发阶段,编写代码后自动进行编译看效果并且最好还能提供web服务的功能呢?答案是有的,它就是webpack-dev-server
自动化打包工具。
# 安装 webpack-dev-server
$ cnpm i -D webpack-dev-server
给 package.json 添加启动命令
"scripts": {"start": "webpack serve --config config/webpack.config.js","dev": "npm run start","build": "webpack --config config/webpack.config.js"}
$ cnpm run start
发现在启动项目的过程中,会提示给你 可以通过
http://localhost:8080
访问项目那么 如果想要修改 端口号呢?如果想要和react一样自动打开默认浏览器呢?如果项目请求遇到了跨域问题呢?
// webpack 基于nodejs的
// 书写配置文件得遵循 commonjs 规范
// export default ×
// module.exports √
// 可以暴露对象 也可以暴露一个函数返回一个对象,为了配置方便,采用函数返回对象形式
const path = require('path')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const HTMLWebpackPlugin = require('html-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = function () {return {// mode 环境,development 开发环境,production生产环境// development 打包的项目代码不会压缩// production 生产环境 打包的项目代码会压缩mode: 'development',// 入口说明, 可以理解为从 package.json 所以在的目录开始计算路径// entry: './src/main.js', // 字符串// entry: ['./src/main.js'], // 数组写法entry: { // 对象写法app: './src/main.js'},// 出口说明output: {// 输出的路径一定式绝对路径// __dirname E:\workspace\bk2310\code\webpack-course\config// 确定打包文件的路径为 buildpath: path.resolve(__dirname, '../build'),// 打包出来的文件在 build/static/js// name标识输出的文件名// contenthash: 8 生成8位随机数,也可以直接写为 hash:8// filename: 'static/js/[name].js' // 此处的那么 代表的 entry中的 对象的写法的那个key// filename: 'static/js/[name].[hash:8].js' // [hash:8] 8位随机数filename: 'static/js/[name].[contenthash:8].js' },// webpack的插件,书写形式为一个数组plugins: [new CleanWebpackPlugin(), // 清除缓存文件// new HtmlWebpackPlugin(), // 打包的文件夹内自动生成了一个 index.html 文件并且引入了打包文件new HTMLWebpackPlugin({ // 自动配置页面模板文件template: './public/index.html',// 默认引入js在head内,可以修改为bodyinject: 'body',// 压缩minify: {// 删除html模版中的注释语句removeComments: true,// 压缩HTML代码collapseWhitespace: true,// 删除属性的引号removeAttributeQuotes: true// https://www.npmjs.com/package/html-webpack-plugin}})],// 开发服务器的配置 https://www.webpackjs.com/configuration/dev-server#rootdevServer: {// 开启开发服务器的端口号port: 'auto', // 也可以写固定值// 开发服务器准备就绪,自动打开默认浏览器运行open: true,// history 路由模式刷新页面404页面处理historyApiFallback: true,// 资源压缩compress: true,// 如果遇到代理问题proxy: [ // 写为数组形式{context: ['/myapi'],target: 'http://121.89.205.189:3000/api',changeOrigin: true,pathRewrite: {'^/myapi': ''}},]}}
}
// src/main.js
console.log('webpack course')
console.log('webpack course')fetch('/myapi/pro/list').then(res => res.json()).then(res => {console.log(res)
})
数据打印成功说明代理设置没有问题
1.7 加载器
1.7.1 加载器概述
在实际开发中,webpack只能打包处理以.js为后缀的模块,其他非.js后缀的模块webpack默认处理不了,而需要调用loader加载器才能正常打包,否则会报错!
loader加载器可以协助webpack打包处理特定的文件模块了,例如:
Ø sass-loader可以打包处理.scss相关的文件
Ø css-loader可以处理css样关的文件
Ø babel可以处理js兼容模块
Ø 配置图片处理 …
1.7.2 打包处理css文件
正如前面所说,webpack默认不能打包css文件,如果在没有安装css加载器的时候打包,包含css文件的项目则会报错:
/* src/style.css */
body {background-color: #f66;
}
import './style.css'
console.log(1)
console.log(2)
console.log(3)
fetch('/myapi/pro/list').then(res => res.json()).then(res => console.log(res.data))
我们需要安装一个CSS的加载器才能让webpack帮助我们打包css文件。
所以要想打包css文件,则需要安装css加载器,该加载器的安装命令为:
$ cnpm i -D style-loader css-loader
安装好需要的加载器后需要对webpack进行配置,告诉webpack当遇到css后缀的文件应该交由哪个加载器去处理。在webpack打包命令对应的module的rules数组中添加css-loader规则:
// webpack 基于nodejs的
// 书写配置文件得遵循 commonjs 规范
// export default ×
// module.exports √
// 可以暴露对象 也可以暴露一个函数返回一个对象,为了配置方便,采用函数返回对象形式
const path = require('path')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const HTMLWebpackPlugin = require('html-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = function () {return {// mode 环境,development 开发环境,production生产环境// development 打包的项目代码不会压缩// production 生产环境 打包的项目代码会压缩mode: 'development',// 入口说明, 可以理解为从 package.json 所以在的目录开始计算路径// entry: './src/main.js', // 字符串// entry: ['./src/main.js'], // 数组写法entry: { // 对象写法app: './src/main.js'},// 出口说明output: {// 输出的路径一定式绝对路径// __dirname E:\workspace\bk2310\code\webpack-course\config// 确定打包文件的路径为 buildpath: path.resolve(__dirname, '../build'),// 打包出来的文件在 build/static/js// name标识输出的文件名// contenthash: 8 生成8位随机数,也可以直接写为 hash:8// filename: 'static/js/[name].js' // 此处的那么 代表的 entry中的 对象的写法的那个key// filename: 'static/js/[name].[hash:8].js' // [hash:8] 8位随机数filename: 'static/js/[name].[contenthash:8].js' },// webpack的插件,书写形式为一个数组plugins: [new CleanWebpackPlugin(), // 清除缓存文件// new HtmlWebpackPlugin(), // 打包的文件夹内自动生成了一个 index.html 文件并且引入了打包文件new HTMLWebpackPlugin({ // 自动配置页面模板文件template: './public/index.html',// 默认引入js在head内,可以修改为bodyinject: 'body',// 压缩minify: {// 删除html模版中的注释语句removeComments: true,// 压缩HTML代码collapseWhitespace: true,// 删除属性的引号removeAttributeQuotes: true// https://www.npmjs.com/package/html-webpack-plugin}})],// 开发服务器的配置 https://www.webpackjs.com/configuration/dev-server#rootdevServer: {// 开启开发服务器的端口号port: 'auto', // 也可以写固定值// 开发服务器准备就绪,自动打开默认浏览器运行open: true,// history 路由模式刷新页面404页面处理historyApiFallback: true,// 资源压缩compress: true,// 如果遇到代理问题proxy: [ // 写为数组形式{context: ['/myapi'],target: 'http://121.89.205.189:3000/api',changeOrigin: true,pathRewrite: {'^/myapi': ''}},]},// 解析器loader的配置module: {rules: [ // 各中加载器 - 处理非js模块 以及 js 的高级语法{test: /\.css$/, // 正则, 以.css为结尾的文件// style-loader 将css代码放置 head 标签内部use: ['style-loader', 'css-loader'] // 使用的加载器 - 解读顺序从后到前}]}}
}
在写加载器use的时候,需要注意:
- use数组中指定的加载器顺序是固定的
- 多个加载器调用的顺序是:从右向左、从下往上调用(倒序执行)
在配置好对应的css加载器后,webpack才能打包对应的css文件
思考?如果做到css的自动兼容处理
使用postcss对样式兼容处理
$ cnpm i -D postcss postcss-loader postcss-preset-env
在项目根目录下面创建两个文件 postcss.config.js
和 .browserslistrc
// postcss.config.js
module.exports = {plugins: [require('postcss-preset-env')]
}
// .browserslistrc
>0.01%
last 100 version
not dead
// webpack 基于nodejs的
// 书写配置文件得遵循 commonjs 规范
// export default ×
// module.exports √
// 可以暴露对象 也可以暴露一个函数返回一个对象,为了配置方便,采用函数返回对象形式
const path = require('path')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const HTMLWebpackPlugin = require('html-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = function () {return {// mode 环境,development 开发环境,production生产环境// development 打包的项目代码不会压缩// production 生产环境 打包的项目代码会压缩mode: 'development',// 入口说明, 可以理解为从 package.json 所以在的目录开始计算路径// entry: './src/main.js', // 字符串// entry: ['./src/main.js'], // 数组写法entry: { // 对象写法app: './src/main.js'},// 出口说明output: {// 输出的路径一定式绝对路径// __dirname E:\workspace\bk2310\code\webpack-course\config// 确定打包文件的路径为 buildpath: path.resolve(__dirname, '../build'),// 打包出来的文件在 build/static/js// name标识输出的文件名// contenthash: 8 生成8位随机数,也可以直接写为 hash:8// filename: 'static/js/[name].js' // 此处的那么 代表的 entry中的 对象的写法的那个key// filename: 'static/js/[name].[hash:8].js' // [hash:8] 8位随机数filename: 'static/js/[name].[contenthash:8].js' },// webpack的插件,书写形式为一个数组plugins: [new CleanWebpackPlugin(), // 清除缓存文件// new HtmlWebpackPlugin(), // 打包的文件夹内自动生成了一个 index.html 文件并且引入了打包文件new HTMLWebpackPlugin({ // 自动配置页面模板文件template: './public/index.html',// 默认引入js在head内,可以修改为bodyinject: 'body',// 压缩minify: {// 删除html模版中的注释语句removeComments: true,// 压缩HTML代码collapseWhitespace: true,// 删除属性的引号removeAttributeQuotes: true// https://www.npmjs.com/package/html-webpack-plugin}})],// 开发服务器的配置 https://www.webpackjs.com/configuration/dev-server#rootdevServer: {// 开启开发服务器的端口号port: 'auto', // 也可以写固定值// 开发服务器准备就绪,自动打开默认浏览器运行// open: true,// history 路由模式刷新页面404页面处理historyApiFallback: true,// 资源压缩compress: true,// 如果遇到代理问题proxy: [ // 写为数组形式{context: ['/myapi'],target: 'http://121.89.205.189:3000/api',changeOrigin: true,pathRewrite: {'^/myapi': ''}},]},// 解析器loader的配置module: {rules: [ // 各中加载器 - 处理非js模块 以及 js 的高级语法{test: /\.css$/, // 正则, 以.css为结尾的文件// style-loader 将css代码放置 head 标签内部use: ['style-loader', 'css-loader', 'postcss-loader'] // 使用的加载器 - 解读顺序从后到前}]}}
}
/* src/style.css */
body {display: flex;background-color: #f66;
}
1.7.3 打包处理scss\less\stylus文件
安装css预处理loader
$ cnpm i -D sass sass-loader dart-sass
$ cnpm i -D less less-loader
$ cnpm i -D stylus stylus-loader
// webpack 基于nodejs的
// 书写配置文件得遵循 commonjs 规范
// export default ×
// module.exports √
// 可以暴露对象 也可以暴露一个函数返回一个对象,为了配置方便,采用函数返回对象形式
const path = require('path')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const HTMLWebpackPlugin = require('html-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = function () {return {// mode 环境,development 开发环境,production生产环境// development 打包的项目代码不会压缩// production 生产环境 打包的项目代码会压缩mode: 'development',// 入口说明, 可以理解为从 package.json 所以在的目录开始计算路径// entry: './src/main.js', // 字符串// entry: ['./src/main.js'], // 数组写法entry: { // 对象写法app: './src/main.js'},// 出口说明output: {// 输出的路径一定式绝对路径// __dirname E:\workspace\bk2310\code\webpack-course\config// 确定打包文件的路径为 buildpath: path.resolve(__dirname, '../build'),// 打包出来的文件在 build/static/js// name标识输出的文件名// contenthash: 8 生成8位随机数,也可以直接写为 hash:8// filename: 'static/js/[name].js' // 此处的那么 代表的 entry中的 对象的写法的那个key// filename: 'static/js/[name].[hash:8].js' // [hash:8] 8位随机数filename: 'static/js/[name].[contenthash:8].js' },// webpack的插件,书写形式为一个数组plugins: [new CleanWebpackPlugin(), // 清除缓存文件// new HtmlWebpackPlugin(), // 打包的文件夹内自动生成了一个 index.html 文件并且引入了打包文件new HTMLWebpackPlugin({ // 自动配置页面模板文件template: './public/index.html',// 默认引入js在head内,可以修改为bodyinject: 'body',// 压缩minify: {// 删除html模版中的注释语句removeComments: true,// 压缩HTML代码collapseWhitespace: true,// 删除属性的引号removeAttributeQuotes: true// https://www.npmjs.com/package/html-webpack-plugin}})],// 开发服务器的配置 https://www.webpackjs.com/configuration/dev-server#rootdevServer: {// 开启开发服务器的端口号port: 'auto', // 也可以写固定值// 开发服务器准备就绪,自动打开默认浏览器运行// open: true,// history 路由模式刷新页面404页面处理historyApiFallback: true,// 资源压缩compress: true,// 如果遇到代理问题proxy: [ // 写为数组形式{context: ['/myapi'],target: 'http://121.89.205.189:3000/api',changeOrigin: true,pathRewrite: {'^/myapi': ''}},]},// 解析器loader的配置module: {rules: [ // 各中加载器 - 处理非js模块 以及 js 的高级语法{test: /\.css$/, // 正则, 以.css为结尾的文件// style-loader 将css代码放置 head 标签内部use: ['style-loader', 'css-loader', 'postcss-loader'] // 使用的加载器 - 解读顺序从后到前},{test: /\.(sass|scss)$/, use: ['style-loader', 'css-loader', 'postcss-loader', 'sass-loader'] },{test: /\.less$/, use: ['style-loader', 'css-loader', 'postcss-loader', 'less-loader'] },{test: /\.(styl|stylus)$/, use: ['style-loader', 'css-loader', 'postcss-loader', 'stylus-loader'] }]}}
}
1.7.4 抽取单个css文件
开发环境下 使用 style-loader 生产环境下抽离css文件
安装插件
$ cnpm i -D mini-css-extract-plugin
// webpack 基于nodejs的
// 书写配置文件得遵循 commonjs 规范
// export default ×
// module.exports √
// 可以暴露对象 也可以暴露一个函数返回一个对象,为了配置方便,采用函数返回对象形式
const path = require('path')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const HTMLWebpackPlugin = require('html-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin') // ++++++++
module.exports = function (webpackEnv) { // ++++++++console.log('666', webpackEnv)const isDev = webpackEnv.WEBPACK_SERVE // ++++++++const isProd = webpackEnv.WEBPACK_BUILD // ++++++++return {// mode 环境,development 开发环境,production生产环境// development 打包的项目代码不会压缩// production 生产环境 打包的项目代码会压缩mode: 'development',// 入口说明, 可以理解为从 package.json 所以在的目录开始计算路径// entry: './src/main.js', // 字符串// entry: ['./src/main.js'], // 数组写法entry: { // 对象写法app: './src/main.js'},// 出口说明output: {// 输出的路径一定式绝对路径// __dirname E:\workspace\bk2310\code\webpack-course\config// 确定打包文件的路径为 buildpath: path.resolve(__dirname, '../build'),// 打包出来的文件在 build/static/js// name标识输出的文件名// contenthash: 8 生成8位随机数,也可以直接写为 hash:8// filename: 'static/js/[name].js' // 此处的那么 代表的 entry中的 对象的写法的那个key// filename: 'static/js/[name].[hash:8].js' // [hash:8] 8位随机数// filename: 'static/js/[name].[contenthash:8].js' filename: isProd ? 'static/js/[name].[contenthash:8].js' : isDev && 'static/js/bundle.js' // ++++++++},// webpack的插件,书写形式为一个数组plugins: [new CleanWebpackPlugin(), // 清除缓存文件// new HTMLWebpackPlugin(), // 打包的文件夹内自动生成了一个 index.html 文件并且引入了打包文件new HTMLWebpackPlugin( // ++++++++Object.assign({}, { // 合并对象template: './public/index.html',// 默认引入js在head内,可以修改为bodyinject: 'body',}, isProd ? {minify: {// 删除html模版中的注释语句removeComments: true,// 压缩HTML代码collapseWhitespace: true,// 删除属性的引号removeAttributeQuotes: true// https://www.npmjs.com/package/html-webpack-plugin}} : undefined)),new MiniCssExtractPlugin({filename: 'static/css/[name].[contenthash:8].css'})],// 开发服务器的配置 https://www.webpackjs.com/configuration/dev-server#rootdevServer: {// 开启开发服务器的端口号port: 'auto', // 也可以写固定值// 开发服务器准备就绪,自动打开默认浏览器运行// open: true,// history 路由模式刷新页面404页面处理historyApiFallback: true,// 资源压缩compress: true,// 如果遇到代理问题proxy: [ // 写为数组形式{context: ['/myapi'],target: 'http://121.89.205.189:3000/api',changeOrigin: true,pathRewrite: {'^/myapi': ''}},]},// 解析器loader的配置module: {rules: [ // 各中加载器 - 处理非js模块 以及 js 的高级语法{test: /\.css$/, // 正则, 以.css为结尾的文件// style-loader 将css代码放置 head 标签内部use: [isProd ? MiniCssExtractPlugin.loader : isDev && 'style-loader', 'css-loader', 'postcss-loader'] // 使用的加载器 - 解读顺序从后到前},{test: /\.(sass|scss)$/, use: [isProd ? MiniCssExtractPlugin.loader : isDev && 'style-loader', 'css-loader', 'postcss-loader', 'sass-loader'] },{test: /\.less$/, use: [isProd ? MiniCssExtractPlugin.loader : isDev && 'style-loader', 'css-loader', 'postcss-loader', 'less-loader'] },{test: /\.(styl|stylus)$/, use: [isProd ? MiniCssExtractPlugin.loader : isDev && 'style-loader', 'css-loader', 'postcss-loader', 'stylus-loader'] }]}}
}
1.8 图片处理
webpack5以前处理,webpack5也可用
$ cnpm i -D file-loader url-loader
// src/main.js
// import './style.css'
// import './style.less'
// import './style.scss'
// import './style.styl'import logo from './logo.svg' // 3KB
import banner from './banner1.jpg' // 93KB
console.log(logo)
console.log(banner)
console.log(1)
console.log(2)
console.log(3)fetch('/myapi/pro/list').then(res => res.json()).then(res => console.log(res.data))// webpack 基于nodejs的
// 书写配置文件得遵循 commonjs 规范
// export default ×
// module.exports √
// 可以暴露对象 也可以暴露一个函数返回一个对象,为了配置方便,采用函数返回对象形式
const path = require('path')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const HTMLWebpackPlugin = require('html-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
module.exports = function (webpackEnv) {console.log('666', webpackEnv)const isDev = webpackEnv.WEBPACK_SERVEconst isProd = webpackEnv.WEBPACK_BUILDreturn {// mode 环境,development 开发环境,production生产环境// development 打包的项目代码不会压缩// production 生产环境 打包的项目代码会压缩mode: 'development',// 入口说明, 可以理解为从 package.json 所以在的目录开始计算路径// entry: './src/main.js', // 字符串// entry: ['./src/main.js'], // 数组写法entry: { // 对象写法app: './src/main.js'},// 出口说明output: {// 输出的路径一定式绝对路径// __dirname E:\workspace\bk2310\code\webpack-course\config// 确定打包文件的路径为 buildpath: path.resolve(__dirname, '../build'),// 打包出来的文件在 build/static/js// name标识输出的文件名// contenthash: 8 生成8位随机数,也可以直接写为 hash:8// filename: 'static/js/[name].js' // 此处的那么 代表的 entry中的 对象的写法的那个key// filename: 'static/js/[name].[hash:8].js' // [hash:8] 8位随机数// filename: 'static/js/[name].[contenthash:8].js' filename: isProd ? 'static/js/[name].[contenthash:8].js' : isDev && 'static/js/bundle.js'},// webpack的插件,书写形式为一个数组plugins: [new CleanWebpackPlugin(), // 清除缓存文件// new HTMLWebpackPlugin(), // 打包的文件夹内自动生成了一个 index.html 文件并且引入了打包文件new HTMLWebpackPlugin(Object.assign({}, { // 合并对象template: './public/index.html',// 默认引入js在head内,可以修改为bodyinject: 'body',}, isProd ? {minify: {// 删除html模版中的注释语句removeComments: true,// 压缩HTML代码collapseWhitespace: true,// 删除属性的引号removeAttributeQuotes: true// https://www.npmjs.com/package/html-webpack-plugin}} : undefined)),new MiniCssExtractPlugin({filename: 'static/css/[name].[contenthash:8].css'})],// 开发服务器的配置 https://www.webpackjs.com/configuration/dev-server#rootdevServer: {// 开启开发服务器的端口号port: 'auto', // 也可以写固定值// 开发服务器准备就绪,自动打开默认浏览器运行// open: true,// history 路由模式刷新页面404页面处理historyApiFallback: true,// 资源压缩compress: true,// 如果遇到代理问题proxy: [ // 写为数组形式{context: ['/myapi'],target: 'http://121.89.205.189:3000/api',changeOrigin: true,pathRewrite: {'^/myapi': ''}},]},// 解析器loader的配置module: {rules: [ // 各中加载器 - 处理非js模块 以及 js 的高级语法{test: /\.css$/, // 正则, 以.css为结尾的文件// style-loader 将css代码放置 head 标签内部use: [isProd ? MiniCssExtractPlugin.loader : isDev && 'style-loader', 'css-loader', 'postcss-loader'] // 使用的加载器 - 解读顺序从后到前},{test: /\.(sass|scss)$/, use: [isProd ? MiniCssExtractPlugin.loader : isDev && 'style-loader', 'css-loader', 'postcss-loader', 'sass-loader'] },{test: /\.less$/, use: [isProd ? MiniCssExtractPlugin.loader : isDev && 'style-loader', 'css-loader', 'postcss-loader', 'less-loader'] },{test: /\.(styl|stylus)$/, use: [isProd ? MiniCssExtractPlugin.loader : isDev && 'style-loader', 'css-loader', 'postcss-loader', 'stylus-loader'] },{ // ++++++++++++++++test: /\.(gif|jpe?g|png|svg|webp)$/i,use: [{// file-loader 属于 url-loader的基础模块loader: 'url-loader',options: {// limit 属于允许用户使用的图片大小的限制// 如果用户使用图片目前大于10KB,就会在build文件夹下出现在media文件夹内// 如果使用图片小于10KB,图片以base64形式展示limit: 10 * 1024, // 10KBname: '[name].[hash:8].[ext]',outputPath: 'static/media'}}]}]}}
}
webpack5内置了资源模块
// webpack 基于nodejs的
// 书写配置文件得遵循 commonjs 规范
// export default ×
// module.exports √
// 可以暴露对象 也可以暴露一个函数返回一个对象,为了配置方便,采用函数返回对象形式
const path = require('path')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const HTMLWebpackPlugin = require('html-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
module.exports = function (webpackEnv) {console.log('666', webpackEnv)const isDev = webpackEnv.WEBPACK_SERVEconst isProd = webpackEnv.WEBPACK_BUILDreturn {// mode 环境,development 开发环境,production生产环境// development 打包的项目代码不会压缩// production 生产环境 打包的项目代码会压缩mode: 'development',// 入口说明, 可以理解为从 package.json 所以在的目录开始计算路径// entry: './src/main.js', // 字符串// entry: ['./src/main.js'], // 数组写法entry: { // 对象写法app: './src/main.js'},// 出口说明output: {// 输出的路径一定式绝对路径// __dirname E:\workspace\bk2310\code\webpack-course\config// 确定打包文件的路径为 buildpath: path.resolve(__dirname, '../build'),// 打包出来的文件在 build/static/js// name标识输出的文件名// contenthash: 8 生成8位随机数,也可以直接写为 hash:8// filename: 'static/js/[name].js' // 此处的那么 代表的 entry中的 对象的写法的那个key// filename: 'static/js/[name].[hash:8].js' // [hash:8] 8位随机数// filename: 'static/js/[name].[contenthash:8].js' filename: isProd ? 'static/js/[name].[contenthash:8].js' : isDev && 'static/js/bundle.js'},// webpack的插件,书写形式为一个数组plugins: [new CleanWebpackPlugin(), // 清除缓存文件// new HTMLWebpackPlugin(), // 打包的文件夹内自动生成了一个 index.html 文件并且引入了打包文件new HTMLWebpackPlugin(Object.assign({}, { // 合并对象template: './public/index.html',// 默认引入js在head内,可以修改为bodyinject: 'body',}, isProd ? {minify: {// 删除html模版中的注释语句removeComments: true,// 压缩HTML代码collapseWhitespace: true,// 删除属性的引号removeAttributeQuotes: true// https://www.npmjs.com/package/html-webpack-plugin}} : undefined)),new MiniCssExtractPlugin({filename: 'static/css/[name].[contenthash:8].css'})],// 开发服务器的配置 https://www.webpackjs.com/configuration/dev-server#rootdevServer: {// 开启开发服务器的端口号port: 'auto', // 也可以写固定值// 开发服务器准备就绪,自动打开默认浏览器运行// open: true,// history 路由模式刷新页面404页面处理historyApiFallback: true,// 资源压缩compress: true,// 如果遇到代理问题proxy: [ // 写为数组形式{context: ['/myapi'],target: 'http://121.89.205.189:3000/api',changeOrigin: true,pathRewrite: {'^/myapi': ''}},]},// 解析器loader的配置module: {rules: [ // 各中加载器 - 处理非js模块 以及 js 的高级语法{test: /\.css$/, // 正则, 以.css为结尾的文件// style-loader 将css代码放置 head 标签内部use: [isProd ? MiniCssExtractPlugin.loader : isDev && 'style-loader', 'css-loader', 'postcss-loader'] // 使用的加载器 - 解读顺序从后到前},{test: /\.(sass|scss)$/, use: [isProd ? MiniCssExtractPlugin.loader : isDev && 'style-loader', 'css-loader', 'postcss-loader', 'sass-loader'] },{test: /\.less$/, use: [isProd ? MiniCssExtractPlugin.loader : isDev && 'style-loader', 'css-loader', 'postcss-loader', 'less-loader'] },{test: /\.(styl|stylus)$/, use: [isProd ? MiniCssExtractPlugin.loader : isDev && 'style-loader', 'css-loader', 'postcss-loader', 'stylus-loader'] },// { // ++++++++++++++++// test: /\.(gif|jpe?g|png|svg|webp)$/i,// use: [// {// // file-loader 属于 url-loader的基础模块// loader: 'url-loader',// options: {// // limit 属于允许用户使用的图片大小的限制// // 如果用户使用图片目前大于10KB,就会在build文件夹下出现在media文件夹内// // 如果使用图片小于10KB,图片以base64形式展示// limit: 10 * 1024, // 10KB// name: '[name].[hash:8].[ext]',// outputPath: 'static/media'// }// }// ]// }// webpack5新增的{ // +++++ test: /\.(gif|jpe?g|png|svg)$/i,type: 'asset',generator: {filename: 'static/media/[name].[hash:8].[ext]'},parser: {dataUrlCondition: {// 小于10KB base64 大于10KB 文件maxSize: 10 * 1024}}}]}}
}
1.9 复制资源
像项目中字体资源是不需要进行打包处理的,可以直接的通过复制方式给打包到目标目录中
$ cnpm i -D copy-webpack-plugin
// webpack 基于nodejs的
// 书写配置文件得遵循 commonjs 规范
// export default ×
// module.exports √
// 可以暴露对象 也可以暴露一个函数返回一个对象,为了配置方便,采用函数返回对象形式
const path = require('path')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const HTMLWebpackPlugin = require('html-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const CopyWebpackPlugin = require('copy-webpack-plugin')
module.exports = function (webpackEnv) {console.log('666', webpackEnv)const isDev = webpackEnv.WEBPACK_SERVEconst isProd = webpackEnv.WEBPACK_BUILDreturn {// mode 环境,development 开发环境,production生产环境// development 打包的项目代码不会压缩// production 生产环境 打包的项目代码会压缩mode: 'development',// 入口说明, 可以理解为从 package.json 所以在的目录开始计算路径// entry: './src/main.js', // 字符串// entry: ['./src/main.js'], // 数组写法entry: { // 对象写法app: './src/main.js'},// 出口说明output: {// 输出的路径一定式绝对路径// __dirname E:\workspace\bk2310\code\webpack-course\config// 确定打包文件的路径为 buildpath: path.resolve(__dirname, '../build'),// 打包出来的文件在 build/static/js// name标识输出的文件名// contenthash: 8 生成8位随机数,也可以直接写为 hash:8// filename: 'static/js/[name].js' // 此处的那么 代表的 entry中的 对象的写法的那个key// filename: 'static/js/[name].[hash:8].js' // [hash:8] 8位随机数// filename: 'static/js/[name].[contenthash:8].js' filename: isProd ? 'static/js/[name].[contenthash:8].js' : isDev && 'static/js/bundle.js'},// webpack的插件,书写形式为一个数组plugins: [new CleanWebpackPlugin(), // 清除缓存文件// new HTMLWebpackPlugin(), // 打包的文件夹内自动生成了一个 index.html 文件并且引入了打包文件new HTMLWebpackPlugin(Object.assign({}, { // 合并对象template: './public/index.html',// 默认引入js在head内,可以修改为bodyinject: 'body',}, isProd ? {minify: {// 删除html模版中的注释语句removeComments: true,// 压缩HTML代码collapseWhitespace: true,// 删除属性的引号removeAttributeQuotes: true// https://www.npmjs.com/package/html-webpack-plugin}} : undefined)),new MiniCssExtractPlugin({filename: 'static/css/[name].[contenthash:8].css'}),new CopyWebpackPlugin({ // ++++++patterns: [{from: path.resolve('./public/favicon.ico'),to: path.resolve('./build')},// 继续拷贝别的资源{from: path.resolve('./public/logo192.png'),to: path.resolve('./build')},{from: path.resolve('./public/logo512.png'),to: path.resolve('./build')}]})],// 开发服务器的配置 https://www.webpackjs.com/configuration/dev-server#rootdevServer: {// 开启开发服务器的端口号port: 'auto', // 也可以写固定值// 开发服务器准备就绪,自动打开默认浏览器运行// open: true,// history 路由模式刷新页面404页面处理historyApiFallback: true,// 资源压缩compress: true,// 如果遇到代理问题proxy: [ // 写为数组形式{context: ['/myapi'],target: 'http://121.89.205.189:3000/api',changeOrigin: true,pathRewrite: {'^/myapi': ''}},]},// 解析器loader的配置module: {rules: [ // 各中加载器 - 处理非js模块 以及 js 的高级语法{test: /\.css$/, // 正则, 以.css为结尾的文件// style-loader 将css代码放置 head 标签内部use: [isProd ? MiniCssExtractPlugin.loader : isDev && 'style-loader', 'css-loader', 'postcss-loader'] // 使用的加载器 - 解读顺序从后到前},{test: /\.(sass|scss)$/, use: [isProd ? MiniCssExtractPlugin.loader : isDev && 'style-loader', 'css-loader', 'postcss-loader', 'sass-loader'] },{test: /\.less$/, use: [isProd ? MiniCssExtractPlugin.loader : isDev && 'style-loader', 'css-loader', 'postcss-loader', 'less-loader'] },{test: /\.(styl|stylus)$/, use: [isProd ? MiniCssExtractPlugin.loader : isDev && 'style-loader', 'css-loader', 'postcss-loader', 'stylus-loader'] },// { // ++++++++++++++++// test: /\.(gif|jpe?g|png|svg|webp)$/i,// use: [// {// // file-loader 属于 url-loader的基础模块// loader: 'url-loader',// options: {// // limit 属于允许用户使用的图片大小的限制// // 如果用户使用图片目前大于10KB,就会在build文件夹下出现在media文件夹内// // 如果使用图片小于10KB,图片以base64形式展示// limit: 10 * 1024, // 10KB// name: '[name].[hash:8].[ext]',// outputPath: 'static/media'// }// }// ]// }// webpack5新增的{ // +++++ test: /\.(gif|jpe?g|png|svg)$/i,type: 'asset',generator: {filename: 'static/media/[name].[hash:8].[ext]'},parser: {dataUrlCondition: {// 小于10KB base64 大于10KB 文件maxSize: 10 * 1024}}}]}}
}
1.10 js兼容处理
webpack在不需要引入任何loader可以对于js进行打包处理,但是它不会对于js兼容性进行任何的处理,而我们编写的项目是需要在不同的浏览器中运行的,此时就需要对于js的兼容性在打包过程中进行对应的处理。使用babel来完成对应的js兼容处理
cnpm i -D babel-loader @babel/core @babel/preset-env core-js
// webpack 基于nodejs的
// 书写配置文件得遵循 commonjs 规范
// export default ×
// module.exports √
// 可以暴露对象 也可以暴露一个函数返回一个对象,为了配置方便,采用函数返回对象形式
const path = require('path')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const HTMLWebpackPlugin = require('html-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const CopyWebpackPlugin = require('copy-webpack-plugin')
module.exports = function (webpackEnv) {console.log('666', webpackEnv)const isDev = webpackEnv.WEBPACK_SERVEconst isProd = webpackEnv.WEBPACK_BUILDreturn {// mode 环境,development 开发环境,production生产环境// development 打包的项目代码不会压缩// production 生产环境 打包的项目代码会压缩mode: 'development',// 入口说明, 可以理解为从 package.json 所以在的目录开始计算路径// entry: './src/main.js', // 字符串// entry: ['./src/main.js'], // 数组写法entry: { // 对象写法app: './src/main.js'},// 出口说明output: {// 输出的路径一定式绝对路径// __dirname E:\workspace\bk2310\code\webpack-course\config// 确定打包文件的路径为 buildpath: path.resolve(__dirname, '../build'),// 打包出来的文件在 build/static/js// name标识输出的文件名// contenthash: 8 生成8位随机数,也可以直接写为 hash:8// filename: 'static/js/[name].js' // 此处的那么 代表的 entry中的 对象的写法的那个key// filename: 'static/js/[name].[hash:8].js' // [hash:8] 8位随机数// filename: 'static/js/[name].[contenthash:8].js' filename: isProd ? 'static/js/[name].[contenthash:8].js' : isDev && 'static/js/bundle.js'},// webpack的插件,书写形式为一个数组plugins: [new CleanWebpackPlugin(), // 清除缓存文件// new HTMLWebpackPlugin(), // 打包的文件夹内自动生成了一个 index.html 文件并且引入了打包文件new HTMLWebpackPlugin(Object.assign({}, { // 合并对象template: './public/index.html',// 默认引入js在head内,可以修改为bodyinject: 'body',}, isProd ? {minify: {// 删除html模版中的注释语句removeComments: true,// 压缩HTML代码collapseWhitespace: true,// 删除属性的引号removeAttributeQuotes: true// https://www.npmjs.com/package/html-webpack-plugin}} : undefined)),new MiniCssExtractPlugin({filename: 'static/css/[name].[contenthash:8].css'}),new CopyWebpackPlugin({ // ++++++patterns: [{from: path.resolve('./public/favicon.ico'),to: path.resolve('./build')},// 继续拷贝别的资源{from: path.resolve('./public/logo192.png'),to: path.resolve('./build')},{from: path.resolve('./public/logo512.png'),to: path.resolve('./build')}]})],// 开发服务器的配置 https://www.webpackjs.com/configuration/dev-server#rootdevServer: {// 开启开发服务器的端口号port: 'auto', // 也可以写固定值// 开发服务器准备就绪,自动打开默认浏览器运行// open: true,// history 路由模式刷新页面404页面处理historyApiFallback: true,// 资源压缩compress: true,// 如果遇到代理问题proxy: [ // 写为数组形式{context: ['/myapi'],target: 'http://121.89.205.189:3000/api',changeOrigin: true,pathRewrite: {'^/myapi': ''}},]},// 解析器loader的配置module: {rules: [ // 各中加载器 - 处理非js模块 以及 js 的高级语法{test: /\.js$/,exclude: /node_modules/, // 不解析的文件use: [{ // +++++++++++++++++++loader: 'babel-loader',// 也可以不写optins,项目跟目录下用 babel.config.js 代替options: {presets: [['@babel/preset-env',{// 按需加载useBuiltIns: 'usage',// 指定core-js版本corejs: 3,// 兼容性做到哪个版本的浏览器targets: {chrome: '75'}}]]}}]},{test: /\.css$/, // 正则, 以.css为结尾的文件// style-loader 将css代码放置 head 标签内部use: [isProd ? MiniCssExtractPlugin.loader : isDev && 'style-loader', 'css-loader', 'postcss-loader'] // 使用的加载器 - 解读顺序从后到前},{test: /\.(sass|scss)$/, use: [isProd ? MiniCssExtractPlugin.loader : isDev && 'style-loader', 'css-loader', 'postcss-loader', 'sass-loader'] },{test: /\.less$/, use: [isProd ? MiniCssExtractPlugin.loader : isDev && 'style-loader', 'css-loader', 'postcss-loader', 'less-loader'] },{test: /\.(styl|stylus)$/, use: [isProd ? MiniCssExtractPlugin.loader : isDev && 'style-loader', 'css-loader', 'postcss-loader', 'stylus-loader'] },// { // ++++++++++++++++// test: /\.(gif|jpe?g|png|svg|webp)$/i,// use: [// {// // file-loader 属于 url-loader的基础模块// loader: 'url-loader',// options: {// // limit 属于允许用户使用的图片大小的限制// // 如果用户使用图片目前大于10KB,就会在build文件夹下出现在media文件夹内// // 如果使用图片小于10KB,图片以base64形式展示// limit: 10 * 1024, // 10KB// name: '[name].[hash:8].[ext]',// outputPath: 'static/media'// }// }// ]// }// webpack5新增的{ // +++++ test: /\.(gif|jpe?g|png|svg)$/i,type: 'asset',generator: {filename: 'static/media/[name].[hash:8].[ext]'},parser: {dataUrlCondition: {// 小于10KB base64 大于10KB 文件maxSize: 10 * 1024}}}]}}
}
// 如果不做 options的说明,需要在项目的根目录下设置 babel.config.js 或者 .babelrc// babel.config.js
module.exports = {presets: [['@babel/preset-env',{// 按需加载useBuiltIns: 'usage',// 指定core-js版本corejs: 3,// 兼容性做到哪个版本的浏览器targets: {chrome: '75'}}]],// 加载UI库时用的居多plugins: []
}
1.11 路径别名与导入后缀省略
// webpack 基于nodejs的
// 书写配置文件得遵循 commonjs 规范
// export default ×
// module.exports √
// 可以暴露对象 也可以暴露一个函数返回一个对象,为了配置方便,采用函数返回对象形式
const path = require('path')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const HTMLWebpackPlugin = require('html-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const CopyWebpackPlugin = require('copy-webpack-plugin')
module.exports = function (webpackEnv) {console.log('666', webpackEnv)const isDev = webpackEnv.WEBPACK_SERVEconst isProd = webpackEnv.WEBPACK_BUILDreturn {// mode 环境,development 开发环境,production生产环境// development 打包的项目代码不会压缩// production 生产环境 打包的项目代码会压缩mode: 'development',// 入口说明, 可以理解为从 package.json 所以在的目录开始计算路径// entry: './src/main.js', // 字符串// entry: ['./src/main.js'], // 数组写法entry: { // 对象写法app: './src/main.js'},// 出口说明output: {// 输出的路径一定式绝对路径// __dirname E:\workspace\bk2310\code\webpack-course\config// 确定打包文件的路径为 buildpath: path.resolve(__dirname, '../build'),// 打包出来的文件在 build/static/js// name标识输出的文件名// contenthash: 8 生成8位随机数,也可以直接写为 hash:8// filename: 'static/js/[name].js' // 此处的那么 代表的 entry中的 对象的写法的那个key// filename: 'static/js/[name].[hash:8].js' // [hash:8] 8位随机数// filename: 'static/js/[name].[contenthash:8].js' filename: isProd ? 'static/js/[name].[contenthash:8].js' : isDev && 'static/js/bundle.js'},// webpack的插件,书写形式为一个数组plugins: [new CleanWebpackPlugin(), // 清除缓存文件// new HTMLWebpackPlugin(), // 打包的文件夹内自动生成了一个 index.html 文件并且引入了打包文件new HTMLWebpackPlugin(Object.assign({}, { // 合并对象template: './public/index.html',// 默认引入js在head内,可以修改为bodyinject: 'body',}, isProd ? {minify: {// 删除html模版中的注释语句removeComments: true,// 压缩HTML代码collapseWhitespace: true,// 删除属性的引号removeAttributeQuotes: true// https://www.npmjs.com/package/html-webpack-plugin}} : undefined)),new MiniCssExtractPlugin({filename: 'static/css/[name].[contenthash:8].css'}),new CopyWebpackPlugin({ // ++++++patterns: [{from: path.resolve('./public/favicon.ico'),to: path.resolve('./build')},// 继续拷贝别的资源{from: path.resolve('./public/logo192.png'),to: path.resolve('./build')},{from: path.resolve('./public/logo512.png'),to: path.resolve('./build')}]})],// 开发服务器的配置 https://www.webpackjs.com/configuration/dev-server#rootdevServer: {// 开启开发服务器的端口号port: 'auto', // 也可以写固定值// 开发服务器准备就绪,自动打开默认浏览器运行// open: true,// history 路由模式刷新页面404页面处理historyApiFallback: true,// 资源压缩compress: true,// 如果遇到代理问题proxy: [ // 写为数组形式{context: ['/myapi'],target: 'http://121.89.205.189:3000/api',changeOrigin: true,pathRewrite: {'^/myapi': ''}},]},// 解析器loader的配置module: {rules: [ // 各中加载器 - 处理非js模块 以及 js 的高级语法{test: /\.js$/,exclude: /node_modules/, // 不解析的文件use: [{ // +++++++++++++++++++loader: 'babel-loader',// 也可以不写optins,项目跟目录下用 babel.config.js 代替options: {presets: [['@babel/preset-env',{// 按需加载useBuiltIns: 'usage',// 指定core-js版本corejs: 3,// 兼容性做到哪个版本的浏览器targets: {chrome: '75'}}]]}}]},{test: /\.css$/, // 正则, 以.css为结尾的文件// style-loader 将css代码放置 head 标签内部use: [isProd ? MiniCssExtractPlugin.loader : isDev && 'style-loader', 'css-loader', 'postcss-loader'] // 使用的加载器 - 解读顺序从后到前},{test: /\.(sass|scss)$/, use: [isProd ? MiniCssExtractPlugin.loader : isDev && 'style-loader', 'css-loader', 'postcss-loader', 'sass-loader'] },{test: /\.less$/, use: [isProd ? MiniCssExtractPlugin.loader : isDev && 'style-loader', 'css-loader', 'postcss-loader', 'less-loader'] },{test: /\.(styl|stylus)$/, use: [isProd ? MiniCssExtractPlugin.loader : isDev && 'style-loader', 'css-loader', 'postcss-loader', 'stylus-loader'] },// { // ++++++++++++++++// test: /\.(gif|jpe?g|png|svg|webp)$/i,// use: [// {// // file-loader 属于 url-loader的基础模块// loader: 'url-loader',// options: {// // limit 属于允许用户使用的图片大小的限制// // 如果用户使用图片目前大于10KB,就会在build文件夹下出现在media文件夹内// // 如果使用图片小于10KB,图片以base64形式展示// limit: 10 * 1024, // 10KB// name: '[name].[hash:8].[ext]',// outputPath: 'static/media'// }// }// ]// }// webpack5新增的{ // +++++ test: /\.(gif|jpe?g|png|svg)$/i,type: 'asset',generator: {filename: 'static/media/[name].[hash:8].[ext]'},parser: {dataUrlCondition: {// 小于10KB base64 大于10KB 文件maxSize: 10 * 1024}}}]},// 路径别名与导入后缀省略resolve: {// ++++++++++++++++++++++++++// 配置别名alias: {'@': path.resolve('./src')},// 缺省的后缀名extensions: ['.js', '.json', '.jsx', '.ts', '.tsx', '.css', '.scss', '.less', '.vue', '.svg', '.png', '.jpg']}}
}
import "@/style"
import logo from '@/logo'
import banner1 from '@/banner1'
console.log('webpack course')
console.log('webpack course', logo)
console.log('webpack course', banner1)fetch('/myapi/pro/list').then(res => res.json()).then(res => {console.log(res)
})
1.12 tree-shaking
tree-shaking是webpack中自带的功能,其作用是去除项目中无用代码(一般指的都是自己所写代码),减少代码体积(涉及到第三方类库,往往不一定有效。)
前提:
Ø 必须使用es6模块化
Ø 开启production环境
在package.json文件中添加了 "sideEffects": false 表示所有代码都没有副作用(所有代码都可以进行tree shaking)
问题:可能会把 css的@babel/polyfill (副作用)文件删除掉 解决:package.json文件中添加"sideEffects":["*.css"]
不考虑使用 低版本浏览器,建议直接设置为
false
即可
1.13 externals忽略不打入的包
例如项目中使用从 CDN 引入 jQuery,而不是把它打包进来使用
cnpm i jquery -S
src/main.js
import $ from 'jquery'
不添加 externals 属性 -出现jquery 32次,添加了 出现6次 ,也可以查看打包的文件的大小
// 记得把mode的选项设置为 development
// webpack 基于nodejs的
// 书写配置文件得遵循 commonjs 规范
// export default ×
// module.exports √
// 可以暴露对象 也可以暴露一个函数返回一个对象,为了配置方便,采用函数返回对象形式
const path = require('path')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const HTMLWebpackPlugin = require('html-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const CopyWebpackPlugin = require('copy-webpack-plugin')
module.exports = function (webpackEnv) {console.log('666', webpackEnv)const isDev = webpackEnv.WEBPACK_SERVEconst isProd = webpackEnv.WEBPACK_BUILDreturn {// mode 环境,development 开发环境,production生产环境// development 打包的项目代码不会压缩// production 生产环境 打包的项目代码会压缩mode: 'development',// 入口说明, 可以理解为从 package.json 所以在的目录开始计算路径// entry: './src/main.js', // 字符串// entry: ['./src/main.js'], // 数组写法entry: { // 对象写法app: './src/main.js'},// 出口说明output: {// 输出的路径一定式绝对路径// __dirname E:\workspace\bk2310\code\webpack-course\config// 确定打包文件的路径为 buildpath: path.resolve(__dirname, '../build'),// 打包出来的文件在 build/static/js// name标识输出的文件名// contenthash: 8 生成8位随机数,也可以直接写为 hash:8// filename: 'static/js/[name].js' // 此处的那么 代表的 entry中的 对象的写法的那个key// filename: 'static/js/[name].[hash:8].js' // [hash:8] 8位随机数// filename: 'static/js/[name].[contenthash:8].js' filename: isProd ? 'static/js/[name].[contenthash:8].js' : isDev && 'static/js/bundle.js'},// webpack的插件,书写形式为一个数组plugins: [new CleanWebpackPlugin(), // 清除缓存文件// new HTMLWebpackPlugin(), // 打包的文件夹内自动生成了一个 index.html 文件并且引入了打包文件new HTMLWebpackPlugin(Object.assign({}, { // 合并对象template: './public/index.html',// 默认引入js在head内,可以修改为bodyinject: 'body',}, isProd ? {minify: {// 删除html模版中的注释语句removeComments: true,// 压缩HTML代码collapseWhitespace: true,// 删除属性的引号removeAttributeQuotes: true// https://www.npmjs.com/package/html-webpack-plugin}} : undefined)),new MiniCssExtractPlugin({filename: 'static/css/[name].[contenthash:8].css'}),new CopyWebpackPlugin({ // ++++++patterns: [{from: path.resolve('./public/favicon.ico'),to: path.resolve('./build')},// 继续拷贝别的资源{from: path.resolve('./public/logo192.png'),to: path.resolve('./build')},{from: path.resolve('./public/logo512.png'),to: path.resolve('./build')}]})],// 开发服务器的配置 https://www.webpackjs.com/configuration/dev-server#rootdevServer: {// 开启开发服务器的端口号port: 'auto', // 也可以写固定值// 开发服务器准备就绪,自动打开默认浏览器运行// open: true,// history 路由模式刷新页面404页面处理historyApiFallback: true,// 资源压缩compress: true,// 如果遇到代理问题proxy: [ // 写为数组形式{context: ['/myapi'],target: 'http://121.89.205.189:3000/api',changeOrigin: true,pathRewrite: {'^/myapi': ''}},]},// 解析器loader的配置module: {rules: [ // 各中加载器 - 处理非js模块 以及 js 的高级语法{test: /\.js$/,exclude: /node_modules/, // 不解析的文件use: [{ // +++++++++++++++++++loader: 'babel-loader',// 也可以不写optins,项目跟目录下用 babel.config.js 代替options: {presets: [['@babel/preset-env',{// 按需加载useBuiltIns: 'usage',// 指定core-js版本corejs: 3,// 兼容性做到哪个版本的浏览器targets: {chrome: '75'}}]]}}]},{test: /\.css$/, // 正则, 以.css为结尾的文件// style-loader 将css代码放置 head 标签内部use: [isProd ? MiniCssExtractPlugin.loader : isDev && 'style-loader', 'css-loader', 'postcss-loader'] // 使用的加载器 - 解读顺序从后到前},{test: /\.(sass|scss)$/, use: [isProd ? MiniCssExtractPlugin.loader : isDev && 'style-loader', 'css-loader', 'postcss-loader', 'sass-loader'] },{test: /\.less$/, use: [isProd ? MiniCssExtractPlugin.loader : isDev && 'style-loader', 'css-loader', 'postcss-loader', 'less-loader'] },{test: /\.(styl|stylus)$/, use: [isProd ? MiniCssExtractPlugin.loader : isDev && 'style-loader', 'css-loader', 'postcss-loader', 'stylus-loader'] },// { // ++++++++++++++++// test: /\.(gif|jpe?g|png|svg|webp)$/i,// use: [// {// // file-loader 属于 url-loader的基础模块// loader: 'url-loader',// options: {// // limit 属于允许用户使用的图片大小的限制// // 如果用户使用图片目前大于10KB,就会在build文件夹下出现在media文件夹内// // 如果使用图片小于10KB,图片以base64形式展示// limit: 10 * 1024, // 10KB// name: '[name].[hash:8].[ext]',// outputPath: 'static/media'// }// }// ]// }// webpack5新增的{ // +++++ test: /\.(gif|jpe?g|png|svg)$/i,type: 'asset',generator: {filename: 'static/media/[name].[hash:8].[ext]'},parser: {dataUrlCondition: {// 小于10KB base64 大于10KB 文件maxSize: 10 * 1024}}}]},// 路径别名与导入后缀省略resolve: {// ++++++++++++++++++++++++++// 配置别名alias: {'@': path.resolve('./src')},// 缺省的后缀名extensions: ['.js', '.json', '.jsx', '.ts', '.tsx', '.css', '.scss', '.less', '.vue', '.svg', '.png', '.jpg']},externals: { // 忽略不打入的包 // +++++++++jquery: 'jQuery'}, }
}
1.14 搭建React
拷贝相关文件至 webpack-react 文件夹
$ cnpm i
$ cnpm i -D @babel/preset-react
$ cnpm i -S react react-dom
$ cnpm i antd -S
{test: /\.(js|jsx)$/, // ++++++++exclude: /node_modules/, // 不解析的文件use: [{loader: 'babel-loader',// 也可以不写optins,项目跟目录下用babel.config.js 代替options: {presets: [['@babel/preset-env',{// 按需加载useBuiltIns: 'usage',// 指定core-js版本corejs: 3,// 兼容性做到哪个版本的浏览器targets: {chrome: '75'}}],[ // ++++++++'@babel/preset-react']]}}]
},
在打包入口文件中引入React并进行单页面应用的渲染
src/main.js
import React from 'react'
import ReactDOM from 'react-dom/client'
import { ConfigProvider } from 'antd';
import App from '@/App'
import zhCN from 'antd/locale/zh_CN';
const root = ReactDOM.createRoot(document.getElementById('root'))root.render(<ConfigProvider locale={zhCN}><App /></ConfigProvider>
)
src/App.jsx
import React from 'react';
import { Button } from 'antd';
function App(props) {return (<div>App<Button type="primary">Primary Button</Button></div>);
}
export default App;
1.15 搭建Vue2
拷贝相关文件至 webpack-vue2文件夹
安装解析vue的相关loader和插件
$ cnpm i
$ cnpm i -D vue-loader@15 vue-template-compiler@2 // 切记一定要注意vue开发配置版本
$ cnpm i -S vue@2 element-ui
在webpack.config.js中配置
// webpack 基于nodejs的
// 书写配置文件得遵循 commonjs 规范
// export default ×
// module.exports √
// 可以暴露对象 也可以暴露一个函数返回一个对象,为了配置方便,采用函数返回对象形式
const path = require('path')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const HTMLWebpackPlugin = require('html-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const { VueLoaderPlugin } = require('vue-loader')
module.exports = function (webpackEnv) {console.log('666', webpackEnv)const isDev = webpackEnv.WEBPACK_SERVEconst isProd = webpackEnv.WEBPACK_BUILDreturn {// mode 环境,development 开发环境,production生产环境// development 打包的项目代码不会压缩// production 生产环境 打包的项目代码会压缩mode: 'development',// 入口说明, 可以理解为从 package.json 所以在的目录开始计算路径// entry: './src/main.js', // 字符串// entry: ['./src/main.js'], // 数组写法entry: { // 对象写法app: './src/main.js'},// 出口说明output: {// 输出的路径一定式绝对路径// __dirname E:\workspace\bk2310\code\webpack-course\config// 确定打包文件的路径为 buildpath: path.resolve(__dirname, '../build'),// 打包出来的文件在 build/static/js// name标识输出的文件名// contenthash: 8 生成8位随机数,也可以直接写为 hash:8// filename: 'static/js/[name].js' // 此处的那么 代表的 entry中的 对象的写法的那个key// filename: 'static/js/[name].[hash:8].js' // [hash:8] 8位随机数// filename: 'static/js/[name].[contenthash:8].js' filename: isProd ? 'static/js/[name].[contenthash:8].js' : isDev && 'static/js/bundle.js'},// webpack的插件,书写形式为一个数组plugins: [new CleanWebpackPlugin(), // 清除缓存文件// new HTMLWebpackPlugin(), // 打包的文件夹内自动生成了一个 index.html 文件并且引入了打包文件new HTMLWebpackPlugin(Object.assign({}, { // 合并对象template: './public/index.html',// 默认引入js在head内,可以修改为bodyinject: 'body',}, isProd ? {minify: {// 删除html模版中的注释语句removeComments: true,// 压缩HTML代码collapseWhitespace: true,// 删除属性的引号removeAttributeQuotes: true// https://www.npmjs.com/package/html-webpack-plugin}} : undefined)),new MiniCssExtractPlugin({filename: 'static/css/[name].[contenthash:8].css'}),new CopyWebpackPlugin({ // ++++++patterns: [{from: path.resolve('./public/favicon.ico'),to: path.resolve('./build')},// 继续拷贝别的资源{from: path.resolve('./public/logo192.png'),to: path.resolve('./build')},{from: path.resolve('./public/logo512.png'),to: path.resolve('./build')}]}),new VueLoaderPlugin()],// 开发服务器的配置 https://www.webpackjs.com/configuration/dev-server#rootdevServer: {// 开启开发服务器的端口号port: 'auto', // 也可以写固定值// 开发服务器准备就绪,自动打开默认浏览器运行// open: true,// history 路由模式刷新页面404页面处理historyApiFallback: true,// 资源压缩compress: true,// 如果遇到代理问题proxy: [ // 写为数组形式{context: ['/myapi'],target: 'http://121.89.205.189:3000/api',changeOrigin: true,pathRewrite: {'^/myapi': ''}},]},// 解析器loader的配置module: {rules: [ // 各中加载器 - 处理非js模块 以及 js 的高级语法{test: /\.vue$/,use:['vue-loader']},{test: /\.js$/,exclude: /node_modules/, // 不解析的文件use: [{ // +++++++++++++++++++loader: 'babel-loader',// 也可以不写optins,项目跟目录下用 babel.config.js 代替options: {presets: [['@babel/preset-env',{// 按需加载useBuiltIns: 'usage',// 指定core-js版本corejs: 3,// 兼容性做到哪个版本的浏览器targets: {chrome: '75'}}]]}}]},{test: /\.css$/, // 正则, 以.css为结尾的文件// style-loader 将css代码放置 head 标签内部use: [isProd ? MiniCssExtractPlugin.loader : isDev && 'style-loader', 'css-loader', 'postcss-loader'] // 使用的加载器 - 解读顺序从后到前},{test: /\.(sass|scss)$/, use: [isProd ? MiniCssExtractPlugin.loader : isDev && 'style-loader', 'css-loader', 'postcss-loader', 'sass-loader'] },{test: /\.less$/, use: [isProd ? MiniCssExtractPlugin.loader : isDev && 'style-loader', 'css-loader', 'postcss-loader', 'less-loader'] },{test: /\.(styl|stylus)$/, use: [isProd ? MiniCssExtractPlugin.loader : isDev && 'style-loader', 'css-loader', 'postcss-loader', 'stylus-loader'] },// { // ++++++++++++++++// test: /\.(gif|jpe?g|png|svg|webp)$/i,// use: [// {// // file-loader 属于 url-loader的基础模块// loader: 'url-loader',// options: {// // limit 属于允许用户使用的图片大小的限制// // 如果用户使用图片目前大于10KB,就会在build文件夹下出现在media文件夹内// // 如果使用图片小于10KB,图片以base64形式展示// limit: 10 * 1024, // 10KB// name: '[name].[hash:8].[ext]',// outputPath: 'static/media'// }// }// ]// }// webpack5新增的{ // +++++ test: /\.(gif|jpe?g|png|svg)$/i,type: 'asset',generator: {filename: 'static/media/[name].[hash:8].[ext]'},parser: {dataUrlCondition: {// 小于10KB base64 大于10KB 文件maxSize: 10 * 1024}}}]},// 路径别名与导入后缀省略resolve: {// ++++++++++++++++++++++++++// 配置别名alias: {'@': path.resolve('./src')},// 缺省的后缀名extensions: ['.js', '.json', '.jsx', '.ts', '.tsx', '.css', '.scss', '.less', '.vue', '.svg', '.png', '.jpg']},externals: { // 忽略不打入的包 // +++++++++jquery: 'jQuery'}, }
}
src/main.js
import Vue from 'vue';
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
import App from './App.vue';Vue.use(ElementUI);new Vue({el: '#root',render: h => h(App)
});
src/App.vue
<template><div>{{ count }}<el-button type="success" @click="count++">加1</el-button></div>
</template>
<script>
export default {data () {return {count: 10}}
}
</script>
1.16 搭建vue3
$ cnpm i vue -S
$ cnpm i vue-loader -D
$ cnpm i element-plus -S
// webpack 基于nodejs的
// 书写配置文件得遵循 commonjs 规范
// export default ×
// module.exports √
// 可以暴露对象 也可以暴露一个函数返回一个对象,为了配置方便,采用函数返回对象形式
const path = require('path')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const HTMLWebpackPlugin = require('html-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const { VueLoaderPlugin } = require('vue-loader') // 解析vue3的
module.exports = function (webpackEnv) {console.log('666', webpackEnv)const isDev = webpackEnv.WEBPACK_SERVEconst isProd = webpackEnv.WEBPACK_BUILDreturn {// mode 环境,development 开发环境,production生产环境// development 打包的项目代码不会压缩// production 生产环境 打包的项目代码会压缩mode: 'development',// 入口说明, 可以理解为从 package.json 所以在的目录开始计算路径// entry: './src/main.js', // 字符串// entry: ['./src/main.js'], // 数组写法entry: { // 对象写法app: './src/main.js'},// 出口说明output: {// 输出的路径一定式绝对路径// __dirname E:\workspace\bk2310\code\webpack-course\config// 确定打包文件的路径为 buildpath: path.resolve(__dirname, '../build'),// 打包出来的文件在 build/static/js// name标识输出的文件名// contenthash: 8 生成8位随机数,也可以直接写为 hash:8// filename: 'static/js/[name].js' // 此处的那么 代表的 entry中的 对象的写法的那个key// filename: 'static/js/[name].[hash:8].js' // [hash:8] 8位随机数// filename: 'static/js/[name].[contenthash:8].js' filename: isProd ? 'static/js/[name].[contenthash:8].js' : isDev && 'static/js/bundle.js'},// webpack的插件,书写形式为一个数组plugins: [new CleanWebpackPlugin(), // 清除缓存文件// new HTMLWebpackPlugin(), // 打包的文件夹内自动生成了一个 index.html 文件并且引入了打包文件new HTMLWebpackPlugin(Object.assign({}, { // 合并对象template: './public/index.html',// 默认引入js在head内,可以修改为bodyinject: 'body',}, isProd ? {minify: {// 删除html模版中的注释语句removeComments: true,// 压缩HTML代码collapseWhitespace: true,// 删除属性的引号removeAttributeQuotes: true// https://www.npmjs.com/package/html-webpack-plugin}} : undefined)),new MiniCssExtractPlugin({filename: 'static/css/[name].[contenthash:8].css'}),new CopyWebpackPlugin({ // ++++++patterns: [{from: path.resolve('./public/favicon.ico'),to: path.resolve('./build')},// 继续拷贝别的资源{from: path.resolve('./public/logo192.png'),to: path.resolve('./build')},{from: path.resolve('./public/logo512.png'),to: path.resolve('./build')}]}),new VueLoaderPlugin()],// 开发服务器的配置 https://www.webpackjs.com/configuration/dev-server#rootdevServer: {// 开启开发服务器的端口号port: 'auto', // 也可以写固定值// 开发服务器准备就绪,自动打开默认浏览器运行// open: true,// history 路由模式刷新页面404页面处理historyApiFallback: true,// 资源压缩compress: true,// 如果遇到代理问题proxy: [ // 写为数组形式{context: ['/myapi'],target: 'http://121.89.205.189:3000/api',changeOrigin: true,pathRewrite: {'^/myapi': ''}},]},// 解析器loader的配置module: {rules: [ // 各中加载器 - 处理非js模块 以及 js 的高级语法{test: /\.vue$/,use:['vue-loader']},{test: /\.js$/,exclude: /node_modules/, // 不解析的文件use: [{ // +++++++++++++++++++loader: 'babel-loader',// 也可以不写optins,项目跟目录下用 babel.config.js 代替options: {presets: [['@babel/preset-env',{// 按需加载useBuiltIns: 'usage',// 指定core-js版本corejs: 3,// 兼容性做到哪个版本的浏览器targets: {chrome: '75'}}]]}}]},{test: /\.css$/, // 正则, 以.css为结尾的文件// style-loader 将css代码放置 head 标签内部use: [isProd ? MiniCssExtractPlugin.loader : isDev && 'style-loader', 'css-loader', 'postcss-loader'] // 使用的加载器 - 解读顺序从后到前},{test: /\.(sass|scss)$/, use: [isProd ? MiniCssExtractPlugin.loader : isDev && 'style-loader', 'css-loader', 'postcss-loader', 'sass-loader'] },{test: /\.less$/, use: [isProd ? MiniCssExtractPlugin.loader : isDev && 'style-loader', 'css-loader', 'postcss-loader', 'less-loader'] },{test: /\.(styl|stylus)$/, use: [isProd ? MiniCssExtractPlugin.loader : isDev && 'style-loader', 'css-loader', 'postcss-loader', 'stylus-loader'] },// { // ++++++++++++++++// test: /\.(gif|jpe?g|png|svg|webp)$/i,// use: [// {// // file-loader 属于 url-loader的基础模块// loader: 'url-loader',// options: {// // limit 属于允许用户使用的图片大小的限制// // 如果用户使用图片目前大于10KB,就会在build文件夹下出现在media文件夹内// // 如果使用图片小于10KB,图片以base64形式展示// limit: 10 * 1024, // 10KB// name: '[name].[hash:8].[ext]',// outputPath: 'static/media'// }// }// ]// }// webpack5新增的{ // +++++ test: /\.(gif|jpe?g|png|svg)$/i,type: 'asset',generator: {filename: 'static/media/[name].[hash:8].[ext]'},parser: {dataUrlCondition: {// 小于10KB base64 大于10KB 文件maxSize: 10 * 1024}}}]},// 路径别名与导入后缀省略resolve: {// ++++++++++++++++++++++++++// 配置别名alias: {'@': path.resolve('./src')},// 缺省的后缀名extensions: ['.js', '.json', '.jsx', '.ts', '.tsx', '.css', '.scss', '.less', '.vue', '.svg', '.png', '.jpg']},externals: { // 忽略不打入的包 // +++++++++jquery: 'jQuery'}, }
}
src/main.js
import { createApp } from 'vue'
import App from '@/App'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
const root = createApp(App)
root.use(ElementPlus)
root.mount('#root')
src/App.vue
<template><div>{{ count }}<!-- <button @click="count+=10">加10</button> --><el-button type="primary" @click="count+=10">加10</el-button></div>
</template>
<script setup>import { ref } from 'vue'const count = ref(10)
</script>
相关文章:

Webpack 完整指南
🌈个人主页:前端青山 🔥系列专栏:Webpack篇 🔖人终将被年少不可得之物困其一生 依旧青山,本期给大家带来webpack篇专栏内容:webpack介绍 目录 介绍 一、webpack 1.1、webpack是什么 1.2 webpack五个核心配置 1.…...

如何在 Ubuntu20.04 安装FTP Server vsftpd
1.安装: sudo apt-get install vsftpd 2.启动 sudo service vsftpd start //启动 sudo service vsftpd stop //停止 sudo service vsftpd restart //重新启动 3.打开配置文件 sudo nano /etc/vsftpd.conf 4.配置:限制在指定目录&…...

基于FPGA的DDS信号发生器(图文并茂+深度原理解析)
篇幅有限,本文详细源文件已打包 至个人主页资源,需要自取...... 前言 DDS(直接数字合成)技术是先进的频率合成手段,在数字信号处理与硬件实现领域作用关键。它因低成本、低功耗、高分辨率以及快速转换时间等优点备受认可。 本文着重探究基于 FPGA 的简易 DDS 信号发生器设…...

QT:绘制事件和定时器
1.绘制时针 xx.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QTimer> #include<QPainter> #include <QTime>QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACEclass Widget : public QWidget {Q_OBJECTpubl…...

【算法——递归回溯】
这个东西还是很重要的,直接决定了你的动态规划章节的学习深度 78. 子集 方法1: vector<vector<int>>V; void dfs(vector<int> v,vector<int> nums,int index) {if(indexnums.size()) V.push_back(v);else{v.push_back(nums[i…...

手机在网状态接口的使用和注意事项
手机在网状态接口是用于查询手机号码在运营商数据库中的实时状态的工具,这种接口在互联网金融、贷款、租赁、保险等相关行业中尤为重要,因为它可以帮助这些行业进行更有效的风控审核。以下是对手机在网状态接口的详细介绍: 一、手机在网状态…...

WebGl 使用uniform变量动态修改点的颜色
在WebGL中,uniform变量用于在顶点着色器和片元着色器之间传递全局状态信息,这些信息在渲染过程中不会随着顶点的变化而变化。uniform变量可以用来设置变换矩阵、光照参数、材料属性等。由于它们在整个渲染过程中共享,因此可以被所有使用该着色…...

Leetcode 划分字母区间
题目要求: 将字符串 s 划分成尽量多的片段,保证每个片段中出现的字母不会出现在其他片段中。 具体解释如下: 尽量多的片段:题目要求的是在划分过程中,我们要尽量让划分的片段数量最大化,而不是最少化。每…...

可编辑div遇到的那些事
在日常开发中有时可能会遇到input 或 textarea 不能满足的开发场景,比如多行输入的情况下,textarea 的右下角icon 无法去除, 所以此时可以使用div 设置可编辑状态,完成功能开发,在开发的过程中仍会遇到一下问题。 1,如…...

什麼是高速HTTP代理?
高速HTTP代理是一種用於加速和優化互聯網連接的技術。它通過在用戶和目標網站之間充當仲介伺服器,幫助用戶快速訪問網路資源。HTTP代理不僅可以提高訪問速度,還能提供一定程度的隱私保護和安全性。 高速HTTP代理的工作原理 HTTP代理伺服器位於用戶設備…...

三子棋(C 语言)
目录 一、游戏设计的整体思路二、各个步骤的代码实现1. 菜单及循环选择的实现2. 棋盘的初始化和显示3. 轮流下棋及结果判断实现4. 结果判断实现 三、所有代码四、总结 一、游戏设计的整体思路 (1)提供一个菜单让玩家选择人机对战、玩家对战或者退出游戏…...

HWS赛题 入门 MIPS Pwn-Mplogin(MIPS_shellcode)
解题所涉知识点: 泄露或修改内存数据: 堆地址:栈地址:栈上数据的连带输出(Stack Leak) && Stack溢出覆盖内存libc地址:BSS段地址: 劫持程序执行流程:[[MIPS_ROP]] 获得shell或flag&am…...

纯血鸿蒙启动公测,爱加密鸿蒙加固平台发布,助力鸿蒙应用安全运营!
鸿蒙系统打破了移动操作系统两极格局,实现操作系统核心技术的自主可控、安全可靠,在神州大地上掀起一波科技革新的浪潮,HarmonyOS NEXT成为大型企业必须要布局的应用系统之一。 HarmonyOS NEXT于10月8日正式开启公测,距离面向全体…...

MySQL中 truncate、drop和delete的区别
MySQL中 truncate、drop和delete区别 truncate 执行速度快,删除所有数据,但是保留表结构不记录日志事务不安全,不能回滚可重置自增主键计数器 drop 执行速度较快,删除整张表数据和结构不记录日志事务不安全,不能回…...

什么开放式耳机值得买?开放式耳机推荐排行榜!
长时间佩戴传统入耳式耳机有时可能会影响耳道健康,鉴于此,转而选择不入耳设计的开放式耳机就成了不少人的新倾向,它们有助于减少细菌滋生和耳道闷热的烦恼。为了帮助大家找到合适的选项,下面我将列举一些市面上口碑不错的开放式耳…...

Apache Doris的分区与分桶详解
目录 第一章 Doris介绍和分区分桶作用 1.1 Doris背景介绍 1.2 分区与分桶的意义 第二章 原理解析 2.1 分区机制 2.1.1 定义 2.1.2 类型 2.1.3 工作原理 2.2 分桶机制 2.2.1 概念 2.2.2 实现方式 2.2.3 与分区的关系 第三章 手动分区与自动分区对比 3.1 手动分区 …...

docker详解介绍+基础操作 (二)info详解
1 docker相关信息和优化配置 1)查看docker版本详解 rootzz:~# docker version Client: Docker Engine - CommunityVersion: 27.3.1API version: 1.47Go version: go1.22.7Git commit: ce12230Built: Fri Sep 20 11:40:…...

C0023.在Clion中创建控件,对控件进行提升为自定义控件的步骤
新建Ui界面文件 修改新生成的ui文件头文件 关闭之前打开的ui文件,如上图Qt Designer中打开的,然后修改新生成的ui文件对应的头文件,改成自己需要的控件类即可。 提升控件为自定义类 将如下头文件中的类名和头文件名输入到提升窗口中&#…...

探索 C# 常用第三方库与框架
在 C# 开发中,第三方库和框架极大地提高了开发效率和代码质量。通过这些库,开发者可以快速处理 JSON 数据、简化对象映射、记录日志、以及高效地与数据库交互。本文将介绍四个常用的 C# 第三方库:Newtonsoft.Json、AutoMapper、NLog/Serilog …...

NodeJS GRPC简单的例子
1. 定义 .proto 文件 首先,创建一个 .proto 文件,定义服务和消息: syntax "proto3";package helloworld;service Greeter {rpc SayHello (HelloRequest) returns (HelloReply) {}rpc SayHelloAgain (HelloRequest) returns (Hel…...

无人机之三维航迹规划篇
一、基本原理 飞行环境建模:在三维航迹规划中,首先需要对飞行环境进行建模。这包括对地形、障碍物、气象等因素进行准确的测量和分析,以获得可行的飞行路径。 飞行任务需求分析:根据无人机的任务需求,确定航迹规划的…...

风格迁移-StyTr 2 : Image Style Transfer with Transformers
风格迁移-StyTr 2 : Image Style Transfer with Transformers 论文链接:Image Style Transfer with Transformers 源码链接:StyTR-2 文章目录 风格迁移-StyTr 2 : Image Style Transfer with TransformersStyTR架构图图像内容编码器内容感知位置编码&…...

上百种【基于YOLOv8/v10/v11的目标检测系统】目录(python+pyside6界面+系统源码+可训练的数据集+也完成的训练模型)
待更新(持续更新),早关注,不迷路............................................................................... 目标检测系统操作说明【用户使用指南】(pythonpyside6界面系统源码可训练的数据集也完成的训练模型ÿ…...

记录搜罗到的Matlab 对散点进行椭圆拟合
需要基于一些散点拟合椭圆估计并计算出椭圆的参数和周长,搜罗到直接上代码 (1)有用的椭圆拟合及参数计算函数 function W fitellipse(x,y) % 构造矩阵 D [x.*x, x.*y, y.*y, x, y,ones(size(x))]; S D*D; G zeros(6); G(1,3) 2; G(3,1)…...

分享我最近使用《柬埔寨语翻译通》App的体验,不会说高棉语也能去柬埔寨旅游,畅通无阻!
最近,我尝试了一款名为《柬埔寨语翻译通》的应用程序,它旨在帮助用户进行中文和高棉语之间的翻译。以下是我使用这款应用的一些体验和感受。 双向翻译功能:我首先测试了它的翻译功能。《柬埔寨语翻译通》能够将中文翻译成高棉语,反…...

文本语义检索系统的搭建过程,涵盖了召回、排序以及Milvus召回系统、短视频推荐等相关内容
大家好,我是微学AI,今天给大家介绍一下本文详细介绍了文本语义检索系统的搭建过程,涵盖了召回、排序以及Milvus召回系统的相关内容。通过使用PyTorch框架,我们提供了样例代码,以帮助读者更好地理解和实践。该系统具有广…...

redis在项目中运用(基础)
mysql学完命令之后,学过jdbc。 redis也要使用Java连接redis数据库 1.Jedis 2.RedisTemplate[重点] 1、Jedis【了解】 jedis是redis的java版本的客户端实现,jedis中提供了针对redis命令的操作 1.1导入jar文件 Maven方式 <dependency><group…...

libaom 源码分析系列:svc_encoder_rtc.cc 文件
源码函数关系 文件功能:实现 AV1 svc 编码的 RTC 功能 demo文件位置:libaom/examples/svc_encoder_rtc.cc文件内函数关系图: 结构体 AppInput:svc_encoder_rtc.cc 所属 demo 的结构体,作为从命令行接受参数的结构体;AvxVideoWriter:输出视频写入结构体;aom_codec_enc_c…...

MySQL备份和还原,用mysqldump、mysql和source命令来完成
MySQL备份和还原,都是利用mysqldump、mysql和source命令来完成的。 mysqldump命令使用方法 1运行 | cmd |利用 cd C:\Program Files\MySQL\MySQL Server 9.0\bin”命令进入bin文件夹 2输入命令 mysqldump -h127.0.0.1 -P3306 -uroot -pQWERTY zssjkcf>d:123.sql mysqldump -…...

MySQL Server、HeidiSQL(MySQL 数据库工具)
目录 一、MySQL Server (一)官网下载 (二)安装与配置 二、HeidiSQL软件 (一)安装 1. 官网下载 2. 打开 3. 使用 (1)打开服务 (2)新增数据库 ÿ…...