打包工具
所有打包工具是基于 node 运行的
1. Webpack
内置模块
- path
- extname: 后缀名
- basename: 文件名
- dirname:文件的父级文件夹路径
- join(x,y): 路径拼接,
- resolve(): 返回绝对路径
安装
npm webpack webpack-cli -D
webpack-cli: 识别命令行中 webpack 的命令,如果只是在 js 文件中使用 webpack,则不用
webpack 的运行依赖 webpack-cli
基本配置
webpack.config.js
固定名字
const path = require('path')
module.exports = {
mode:'development', // 默认是生产环境
context:'', // 默认值是webpack启动路径,
entry:'./src/main.js', // 入口 相对于context
output: {
filename:'bundle.js'
path:path.resolve(__dirname,'./build')
},
module: {
rules:[ // 配置loader 解析配置文件
{
test:/\.css$/,
use:[
// 执行顺序是从列表的左边向右解析
{loader:'style-loader'} // 插入到页面中
{loader:'css-loader'}, // 只负责解析
{
loader:'postcss-loader',
options:{
postcssOptions:{
plugins:[
'autoprefixer'
]
}
}
}
]
}
]
}
}
指定配置文件:package.json 中可以通过 stripts:
loader
webpack 对除了 js 文件以外的文件,不支持处理
loader: 处理模块,对源码进行转换
常用 loader:
-
css-loader: 只负责 css 解析
-
style-loader: 将 css 插入页面中
-
less-loader: 解析 less 文件成 css
-
postcss-loader:通过 js 进行转换样式的工具,如浏览器前缀,css 样式的重置
-
autoprefixer: 浏览器前缀插件
可以通过 postcss.config.js 进行配置,
module.exports = { plugins: [ // 'autoprefixer' "postcss-preset-env", ], };
-
postcss-preset-env: 将很多插件预设好了
-
-
babel-loader: 将 ES6 转为 ES5
-
@babel/preset-env
// babel.config.js module.exports = { //plugins:[ // @babel/plugin-xxxxxxxx //] presets:[ @babel/preset-env ] }
-
资源模块
webpack5 之前在处理资源的时候,需要使用各种 loader: raw-loader,url-loader,file-loader,
webpack5 之后,可以直接使用资源模块类型 asset module type
资源模块类型:
- asset/resource: 发送一个单独的文件并导出 URL , 与 file-loader 对应
- asset/inline:导出一个资源的 data URL ,与 url-loader 对应
- asset/source:导出资源的源码,与 raw-loader 对应
- asset:在导入一个 data URL 和发送一个单独的文件之间自动选择,url-loader 配置资源体积限制实现
// webpack.config.js
...
rules:[
...
{
test:/\.(png|jpe?g|gif|svg)$/ig,
type:'asset',
generator:{
// 占位符
// name 文件名
// ext 扩展名
// hash hash:2 前两位
filename:'img/[name].[hash:6][ext]'
},
parser:{
dataUrlCondition:{
maxSize: 60*1024
}
}
}
]
extensions 和 alias 配置
extensions: 文件扩展名配置
如果是文件,当不写扩展名时,尝试去 extensions 中查找
如果是文件夹,去当前文件夹下查找 index.js
alias: 配置别名
module.exports = {
//...
resolve: {
extensions: [".js", ".json", ".wasm", "vue", "ts"],
},
alias: {
utils: path.resolve(__dirname, "./utils"),
},
};
插件 Plugin
loader 用来转换特定类型的模块,plugin 可以用于执行更加广泛的任务,如打包优化,资源管理,环境变量注入等
-
clean-webpack-plugin
: 清除打包文件 -
html-webpack-plugin
: -
DefinePlugin
: 内置的
const {CleanWebpackPlugin} = require('clean-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const {DefinePlugin} = require('webpack')
module.exports = {
//...
plugins:[
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
title:'自定义模板',
template:'./index.html'
})
new DefinePlugin({
"BASE_URL":'"./"'
})
]
};
// index.html
source-map
将已经转换的代码,映射到原始的源文件,使浏览器可以重构原始源,并且在调试器中显示重建的原始源
使用 source-map
// webpack.config.js
module.exports = {
...
devtool: "source-map", // 26个值可以设置 不同的值会明显影响到构建(build)和重新构建(rebuild)的速度。
...
};
浏览器会将转换后的代码中的注释 //# sourceMappingURL=bundle.js.map 加载对应的 sourcemap 文件,并根据 source-map 文件还原我们的代码
devtool 值:
-
none: 默认,production 环境下,不生成 source-map
-
false: 不生成 source-map
-
eval: development 模式下,也不会生成 source-map, 会使用 eval 函数,还原源文件,但是位置信息不准确
-
source-map: production 环境下,生成完整的 source-map 文件
-
eval-source-map: 生成 source-map,会以 DataUrl 添加到 eval 函数的后面
-
inline-source-map: 生成 source-map,会以 DataUrl 添加到文件的后面
-
cheap-source-map: development 模式下,高效一些,不会生成列位置映射,
-
cheap-module-source-map: 对 loader 处理的代码,生成的 source-map 处理的更好
-
hidden-source-map: production 环境下, 生成 source-map 但是不会对文件进行引用,需要手动引用
//# sourceMappingURL=bundle.js.map
-
nosource-source-map: 生成的 sourcemap 只有错误信息的提示,不会生成源代码文件
推荐使用:
- 开发阶段:source-map 或者 cheap-module-source-map
- 测试阶段:source-map 或者 cheap-module-source-map
- 发布阶段:false,缺省值(不写)
分析 source-map
{
"version": 3, // 版本号 第三版文件大小约是源文件的2.5倍大小
"file": "bundle.js", // 打包之后的文件
"mappings": "AACAA,QAAQC,IADQ,eAIdD,QAAQC,IAAI", // 编码,与源文件进行映射,记录位置信息的字符串
"sources": [
// 源文件列表
"webpack://source-map/./src/main.js"
],
"sourcesContent": [
// 转换前文件的原始内容。
"const message = \"hello world\";\r\nconsole.log(message);\r\n\r\nconst foo = () => {\r\n console.log(\"foo function exec~\");\r\n};\r\nfoo();\r\n"
],
"names": [
// 转换前的所有变量名和属性名。
"console",
"log"
],
"sourceRoot": "" // 转换前的文件所在的目录。如果与转换前的文件在同一目录,该项为空。
}
-
mappings
-
第一层是行对应,以分号(; )表示,每个分号对应转换后源码的一行。所以,第一个分号前的内容,就对应源码的第一行,以此类推。
-
第二层是位置对应,以逗号(, )表示,每个逗号对应转换后源码的一个位置。所以,第一个逗号前的内容,就对应该行源码的第一个位置,以此类推。
-
第三层是位置转换,以VLQ 编码表示,代表该位置对应的转换前的源码位置。
// 源码转换前 const message = "hello world"; console.log(message); const foo = () => { console.log("foo function exec~"); }; foo();
源码转换后:
console.log("hello world"), console.log("foo function exec~");
"mappings": "AACAA,QAAQC,IADQ,eAIdD,QAAQC,IAAI",
正常来说,每个位置最多由 5 个字母组成,5 个字母的含义分别是:
- 第一位,表示这个位置在(转换后的代码的)的第几列。
- 第二位,表示这个位置属于 sources 属性中的哪一个文件。
- 第三位,表示这个位置属于转换前代码的第几行。
- 第四位,表示这个位置属于转换前代码的第几列。
- 第五位,表示这个位置属于 names 属性中的哪一个变量。
每一个位置都可以用VLQ 编码转换,形成一种映射关系。可以在这个网站自己转换测试,将
AACAA,QAAQC,IADQ,eAIdD,QAAQC,IAAI
转换后的结果:[0,0,1,0,0], [8,0,0,8,1], [4,0,-1,8], [15,0,4,-14,-1], [8,0,0,8,1], [4,0,0,4],AACAA [0,0,1,0,0] 表示:
- 压缩代码的第一列。
- 第一个源代码文件,main.js
- 源代码的第二行。
- 源代码第一列
- names 中第一个变量
-
Mode 配置
- production: 默认
- none:不使用任何默认优化选项
- development:开发环境
development
devtool:'eval' # 设置source-map
production
开启本地服务器
想要自动完成编译和展示
-
webpack watch mode
-
webpack-dev-server
{ ... scripts:{ 'serve':'webpack serve --config webpack.config.js' } } // npm run serve
-
webpack-dev-middle
模块热更新(HMR)
应用程序运行过程中,添加、替换、删除模块,无需重新刷新整个页面
{
...
devServer:{
hot: true // 默认是true
}
}
// 指定哪个模块需要HMR
if (module.hot){
module.hot.accept('./utils.js')
}
devServer 配置
{
devServer:{
port:8888, // 端口号
host:'0.0.0.0', // 其他都可访问
open:true, // 是否要自动打开浏览器
compress:true// 是否对文件进行压缩
}
}
环境配置
Vue 脚手架早期:
webpack.dev.config.js:开发环境
webpack.pro.config.js:生产环境
webpack.comm.config.js: 公共部分,
使用webpack-merge 将公共部分和私有部分合并, merge(coom,{自定义})
分包
vue3 中使用 import 函数导入模块自动分包
const Home = () => import(/*webpackChunkName: 'home'*/, './views/Home.vue')
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· DeepSeek在M芯片Mac上本地化部署