- webpack基本概念和作用
- 现代 javascript 应用程序的 静态模块打包器 (module bundler)
- 静态: 文件资源
- 模块: node环境, 引入文件, 遵守模块化语法
- 开发完项目, 可以用node+webpack来分析, 翻译, 压缩, 打包
- ==减小代码包体积, 让浏览器更快速打开网页==
- 除了合并代码, 还可以翻译和压缩代码
-
- less/sass -> css
-
- ES6/7/8 -> ES5
-
- html/css/js -> 压缩合并
- webpack使用步骤
- webpack依赖Node环境,npm或yarn等模块管理工具
- 创建webpack基础使用文件夹
- 下载yarn webpack工程模块化工具,打包 下载yarn下载地址: yarn.bootcss.com/docs/instal…
下载地址: <https://yarn.bootcss.com/docs/install/#windows-stable>
- ==建议不要安装到中文路径下==
- ==建议和node安装到一个盘符下==
- mac - 通过命令安装(也可还用npm)
sudo npm i -g yarn
如果上面不行, 试试这个
curl -o- -L https://yarnpkg.com/install.sh | bash
使用yarn:
与npm类似, 可以试试, 新建一个空白文件夹, 执行以下命令尝试一下
# 1. 初始化, 得到package.json文件(终端路径所在文件夹下)
yarn init
# 类似: npm init
# 2. 添加依赖(下包)
# 语法: yarn add [package]
# 3. 移除包
# 语法: yarn remove [package]
# 4. 安装项目全部依赖(一般拿到别人的项目时, 缺少node_modules)
yarn
# 会根据当前项目package.json记录的包名和版本, 全部下载到当前工程中
# 类似: npm i
# 5. 全局
# 安装: yarn global add [package]
# 卸载: yarn global remove [package]
# 注意: global一定在add左边
#6.下载vue全局
yarn global add @vue/cli
#7.在package.json中, 配置scripts(自定义命令)
scripts: {
"build": "webpack"
}
- webpack-插件-自动生成html文件
- 自动生成html文件
- 自动引入打包后文件 html-webpack-plugin插件文档 下载插件
yarn add html-webpack-plugin@5.3.1 -D
webpack.config.js配置
// 引入自动生成 html 的插件
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
// ...省略其他代码
plugins: [
new HtmlWebpackPlugin({
// 以此为基准生成打包后html文件
template: './public/index.html'
})
]
}
- webpack-加载器-处理css文件问题
yarn add css-loader@5.2.1 style-loader@2.0.0 -D
webpack.config.js 配置
module.exports = {
// ...其他代码
module: { // 如何处理项目中不同模块文件
rules: [ // 规则
{
test: /\.css$/, // 匹配所有的css文件
// use数组里从右向左运行
// 先用 css-loader 让webpack能够识别 css 文件的内容并打包
// 再用 style-loader 将样式, 把css插入到dom中
use: [ "style-loader", "css-loader"]
}
]
}
}
- ==在main.js引入index.css==
import "./css/index.css"
- 配置完之后运行打包命令:
yarn build
- webpack-加载器-处理less文件
- less-loader文档
- 引入到main.js中
yarn add less@4.1.1 less-loader@8.1.0 -D
webpack.config.js 配置
module: {
rules: [
// ...省略其他
{
test: /\.less$/, // 匹配.less结尾文件
// 使用less-loader, 让webpack处理less文件, 内置还会用less模块, 翻译less代码成css代码
use: [ "style-loader", "css-loader", 'less-loader']
}
]
}
- 对图片有哪两种处理方案
- webpack-加载器-处理图片文件
- webpack5内置处理方案, 只需要填入配置即可
- asset module资源模块文档
module: {
rules: [
// ...省略其他
{
test: /\.(png|jpg|gif|jpeg)$/i, // 匹配图片文件
type: 'asset' // 在导出一个 data URI 和一个单独的文件之间自动选择
}
]
}
asset模块区分
module: {
rules: [
// ...省略其他
{
test: /\.(png|jpg|gif|jpeg)$/i, // 匹配图片文件
type: 'asset' // 在导出一个 data URI 和一个单独的文件之间自动选择
// 小于8kb的, 转成data URI(图片转成base64字符串打包进js中)
// 大于8kb的, 直接复制文件到dist目录下(因为转base64会体积增30%)
}
]
}
- 默认8kb以下图片, 转成base64字符串打包进js中, 减少网络请求次数
- 超过8kb的图片, 直接复制到dist下, 转base64会增加30%体积
- webpack-加载器-处理字体文件 在main.js引入iconfont.css
// 引入字体图标文件
import './assets/fonts/iconfont.css'
在public/index.html使用字体图标样式
<i class="iconfont icon-weixin"></i>
配置
- webpack5, 用asset module技术
- webpack.config.js
{
test: /\.(eot|svg|ttf|woff|woff2)$/,
type: 'asset/resource', // 当做静态资源直接复制文件
generator: {
filename: 'font/[name].[hash:6][ext]' // 放到dist/font文件 夹, 文件名格式如左
}
}
- webpack-加载器-处理高版本js语法
- webpack, 对高版本js语法降级
- babel编译器=>用于处理高版本js语法的兼容性babel官网
- webpack配合babel-loader 对js语法做处理 babel-loader文档 src/main.js - 编写箭头函数
const fn = () => { // 高级语法
console.log("你好babel");
}
console.log(fn) // 一定打印函数, 才会被webpack把"函数体"打包起来
安装包
yarn add -D babel-loader@8.2.2 @babel/core@7.13.15 @babel/preset-env@7.13.15
webpack.config.js 配置规则
module: {
rules: [
{
test: /\.js$/, // 匹配js结尾文件
exclude: /(node_modules|bower_components)/, // 不转换这2个文件夹里的js
use: {
loader: 'babel-loader', // 使用加载器-处理
options: {
presets: ['@babel/preset-env'] // 预设:转码规则(用bable开发环境本来预设的)
}
}
}
]
}
打包后观察dist/的js文件, 自动变成普通函数
-
总结: 只要找到对应的loader加载器, 就能让webpack处理不同类型文件
-
效果:
- src并列处, 生成dist目录和main.js文件
- 查看main.js文件, 是打包压缩后的代码
- css代码被打包进了dist/bundle.js中
- 运行时, css代码插入到html的style标签中
- 下载包可以用到的几个命令:
- 方式一:安装nrm全局包(得到nrm命令)
- 作用: 切换npm包下载地址:
// 全局下载 - 得到nrm命令
npm i nrm -g
// 查看有哪些可用的下载地址
nrm ls
// 切换npm下载地址
nrm use taobao
// 查看效果是否成功
npm config list
// 查看registry下载地址是否变化
- 方式二:安装cnpm全局包(得到cnpm命令)
- 作用:以后用cnpm来下包
// 全局下载 cnpm - 得到cnpm命令
npm i cnpm -g
// 可以用cnpm 代替 npm使用
// 下包 cnpm i 包名
- 通常情况下使用yarn即可
- 下载webpack-dev-server, 启动一个开发服务器, 用于快速开发应用程序
yarn add webpack-dev-server@3.11.2 -D
配置自定义命令serve
scripts: {
"build": "webpack",
"serve": "webpack serve"
}
运行命令-启动webpack开发服务器
yarn serve
#或者 npm run serve
- 启动一个web服务器和端口, 在浏览器访问查看
- 效果: 以后改src下的代码, 自动打包更新到浏览器上 webpack-dev-server配置文档 webpack.config.js中添加服务器配置
module.exports = {
// ...其他配置
devServer: {
port: 3000, // 端口号
open: true // 启动后自动打开浏览器
}
}
准备一个后端web服务, 把dist放进去, 暴露成静态资源目录供别人访问
// 准备一个node+express的web服务, 可以部署和启动在一个接入外网的电脑上, 别人都可以访问
const express = require('express')
const app = express()
// . 当前文件所在文件夹
// / 打开文件夹
// ./当前当前文件夹(也可以省略)
app.use(express.static('./dist'))
app.listen(4005)
- 打包优化:
1. 打包优化- yarn build生成 dist目录
- 双击无法打开, 默认打包出来的路径是绝对路径 => 服务器环境
- 方法1:
- 修改配置允许dist目录双击打开
- 修改打包路径为相对路径
在
vue.config.js文件夹中追加配置
module.exports = {
//希望打包时 以相对路径
publicPath: './'
}
- 方法2:
- dist根目录VScode打开
- VScode中下载live server 插件
- 这样就可以查看自己打包后的代码是否可以运行了
2.打包优化-配置路由懒加载
- 用户第一次点进来, 加载了所有组件, 希望 他看到了哪个组件, 加载对应的组件
- 首屏加载更快,只需要加载首屏对应的登录组件即可, 用户体验更好 在路由页面把普通的路由引入方式换出以下:
const Login = () => import('@/views/Login')
const Reg = () => import('@/views/Reg')
const Layout = () => import('@/views/Layout')
const Home = () => import('@/views/Home')
const ArtCategory = () => import('@/views/ArtCategory')
const ArtList = () => import('@/views/ArtList')
const UserInfo = () => import('@/views/UserInfo')
const ChangeAvatar = () => import('@/views/ChangeAvatar')
const ResetPwd = () => import('@/views/ResetPwd')
打包优化-打包移除 console控制台打印
下载插件
`yarn add terser-webpack-plugin -D`
vue.config.js文件中配置
module.exports = {
chainWebpack: (config) => {
config.optimization.minimizer('terser').tap((args) => {
args[0].terserOptions.compress.drop_console = true
return args
})
}
}
打包优化-移除第三方包引入cdn地址
- cdn 在线链接
// 获取当前的打包环境
const env = process.env.NODE_ENV
// 打包排除项
let externals = {}
// 根据打包环境,动态设置打包排除项
if (env === 'production') {
externals = {
// import 时的包名称: window 全局的成员名称
vue: 'Vue',
'vue-router': 'VueRouter',
vuex: 'Vuex',
axios: 'axios',
dayjs: 'dayjs',
echarts: 'echarts',
'element-ui': 'ELEMENT',
'vue-quill-editor': 'VueQuillEditor'
}
}
module.exports = {
publicPath: './',
// 增强 vue-cli 的 webpack 配置项
configureWebpack: {
// 打包优化
//配置排除项后下载的包就会走cnd
//一旦设置了这些排除项后,webpack就不会把这个包打进项目
externals
},
// 移除控制台打印
chainWebpack: (config) => {
config.optimization.minimizer('terser').tap((args) => {
args[0].terserOptions.compress.drop_console = true
return args
})
}
}
<!DOCTYPE html>
<html lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title><%= htmlWebpackPlugin.options.title %></title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/quill@1.3.7/dist/quill.core.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/quill@1.3.7/dist/quill.snow.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/quill@1.3.7/dist/quill.bubble.css">
</head>
<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- 如果是开发环境 不要加载这些cdn资源, 如果是生产环境再加载这些资源 -->
<% if(htmlWebpackPlugin.options.env === 'production') { %>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue-router@3.5.2/dist/vue-router.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuex@3.6.2/dist/vuex.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/axios@0.21.3/dist/axios.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/dayjs@1.10.6/dayjs.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/echarts@5.2.0/dist/echarts.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/element-ui@2.15.5/lib/index.js"></script>
<script src="https://cdn.jsdelivr.net/npm/quill@1.3.7/dist/quill.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue-quill-editor@3.0.6/dist/vue-quill-editor.js"></script>
<% } %>
<!-- built files will be auto injected -->
</body>
</html>