一、前言
前端开发中,打包工具是不可或缺的工具之一。它们可以将分散的代码、样式和资源文件打包成更高效的形式,以提高性能、减少加载时间,并优化开发流程。
(一)、打包和打包工具
打包:将多个文件或模块组合成一个或少数几个文件的过程,以减少网络请求和提高性能。
打包工具:用于自动化打包和优化前端项目资源的软件,它们将多个文件合并、压缩,并处理依赖关系,以提供更高性能的输出。
(二)、打包工具的作用
2.1 代码分割
将应用程序拆分为小块,按需加载,减少首次加载时间。
2.2 依赖管理
自动分析和管理模块之间的依赖关系,确保正确加载和执行。
2.3 优化资源
压缩、混淆和图片优化等,减小文件大小,提高性能。
(三)、打包工具的原理
3.1 入口文件
指定一个或多个入口文件,打包工具从这些文件开始分析和构建。
3.2 模块系统
使用模块系统来组织和管理代码,如CommonJS、ES6模块等。
3.3 转换和加载器
通过转换器(Loader)处理不同类型的文件,如JavaScript、CSS、图像等。
3.4 依赖图
根据模块之间的依赖关系构建依赖图,确保正确的加载顺序。
webpack和vite都是前端模块的打包工具
二、webpack
webpack只负责项目打包,其他功能需要在webpack.config.js配置文件里进行设置。
webpack适用于大型,复杂的项目,它可以处理多种不同类型的文件,并根据需求进行转换、压缩、打包。
webpack唯一不好的就是配置比较复杂,需要花费一定的时间和精力进行学习和调试。
(一)、webpack配置八大模块
Entry 必选项
指定读取入口文件(项目开始的文件)
output 必选项
配置代码打包后的地址
打包后的.js就是普通的js文件,.mjs就是es模块的文件
mode webpack4以后必填
devServer 非必填
开发模式配置
modules 非必填 loader编写的地方(用于预处理文件,文件加载器)
使用css-loader可以处理js中的样式
使用style-loader,让css样式生效
编译ts,需要ts-loader
编译vue,需要vue-loader
使用babel-loader,将新的js语法转换为旧的js,以提高代码的兼容性。
plugins 非必填
插件(**用于增强功能,扩展器 **)
optimization 非必填
优化相关
resolve 非必填
提供一些简化功能(别名,文件后缀名省略等等)
https://www.webpackjs.com/configuration/resolve/
单入口--> runtime+vendor+核心业务+异步模块
多入口--> runtime+vendor+每个入口的核心业务代码+common
(二)、webpack.config.js配置文件
const minicss = require("mini-css-extract-plugin")
module.exports = {mode:"production",//none,development(开发模式),production(生产模式)entry:{app:"./app.js"//根据你的项目,自行配置入口文件},output:{path:__dirname+"/dist",//__dirname当前路径下的绝对路径chunkFilename: "[name].js",filename: 'assets/js/[name].[chunkhash:4].bundle.js',//[chunkhash:4]前4位 [name]app名},optimization:{},devServer:{hot: true, // 打开热更新开关historyApiFallback:true},resolve:{extensions: ['.vue','.js', '.ts', '.css'],alias: {"@": resolve("src"),},},modelu:{rules:[//css样式{test:/\.css$/i,use:[minicss.loader,"style-loader","css-loader"]},//图片生效{test: /\.(png|jpe?g|gif)$/,type: 'asset/resource',generator: {filename: 'assets/img/[hash][ext]'}},{test: /\.vue$/,use: 'vue-loader'},//label把es6转为es5,兼容性{test: /\.less$/i,use: [// compiles Less to CSSminicss.loader,'style-loader','css-loader','less-loader',],},{test:/\.m?js$/,exclude:/(node_modules|bower_components)/,use:{loader:"babel-loader",options:{//告诉babel-leader采用presets:["@babel/preset-env"]规范进行编译。不然就会编译失效//presets对象可以写在当前对象文件中或者可以写进项目根目录的.babelrc文件里,不过需要注意的是,是要以对象的形式写进去presets:["@babel/preset-env",{targets:{//编译目标browsers:[">1%",//支持大于百分之一的浏览器"last 2 version",//支持厂商浏览器最后两个版本"not ie<=8",//不支持小于ie8以下的]}}]}}},//webpack的typeScript加载器{test: /\.(j|t)sx?$/,exclude: /node_modules/,use:['babel-loader',{loader: 'ts-loader',options: {appendTsSuffixTo: [/\.vue$/],// 重要transpileOnly: true,// 重要 取消类型检测 直接进行编译happyPackMode: false,}}]}},//打包输出文件output: {filename: 'assets/js/[name].[contenthash:6].js',path: path.resolve(__dirname, './dist')},//webpack扩展功能plugins: [new VueLoaderPlugin(),//为webpack打包后的js指定模板new HtmlWebpackPlugin({template: path.resolve(__dirname, './public/index.html')})new minicss({filename:"test.bundle.css"}),new minimizer()],optimization: {//代码分割splitChunks: {chunks: "all",//all,async,initialcacheGroups:{vendor:{test:/[\\/]node_modules[\\/]/,filename: "vendor.[chunkhash:4].js",chunks: "all",minChunks: 1},common:{filename: "common.[chunkhash:4].js"chunks: "all",miniChunks:2,//重复出现2次以上,拆分为独立的模块minSize: 0//大于0byte文件才拆分出来}}},runtimeChunk: {//运行时的chunk文件name:"runtime"}},devServer: {hot: true, // 打开热更新开关historyApiFallback:true},]}
}
2.1 多入口写法与当入口写法
//多入口写法
module.exports = {...entry:{app:"./app.js",app1:"./app1.js"}
}//单入口写法
module.exports = {...entry:"./app.js"
}
- devtool
devtool:"inline-source-map" //设置代码映射,查看源码,方便调试
2.2 webpack配置项技巧
- 1.require.context(批量引入指定文件夹下的所有文件)
- 2.resolve
2.1 alias-别名,提供路径的简写
2.2 Extensions-扩展省略,定义可省略的扩展名
(三)、webpack的package.json配置
{"name": "沉默小管",//项目名称"version": "0.0.1",//版本"description": "沉默小管",//项目描述"author": "沉默小管",//作者"license": "MIT","scripts": {//运行脚本"watch": "webpack --watch","dev": "webpack server --open --mode=development","build": "webpack --mode=production"},"husky": {"hooks": {"pre-commit": "lint-staged"}},"lint-staged": {"src/**/*.{js,vue}": ["eslint --fix","git add"]},"keywords": [],//项目关键词"dependencies": {},//项目依赖"devDependencies": { },//开发时依赖"engines": {//启动引擎版本"node": ">=8.9","npm": ">= 3.0.0"},"browserslist": [//设置兼容列表"> 1%","last 2 versions"]
}
三、vite
相较于webpack,vite采用了不同的运行方式。开发时,并不对代码打包,而是直接采用ES模块的方式来运行项目。
在项目部署时,再对项目进行打包。他比webpack少了分析依赖关系的环节。因此,vite的开发速度更快,也适合小型,简单的项目。
(一)、vite.config.js或vite.config.ts文件来配置打包
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import path from 'path';export default defineConfig({// 与插件有关的操作,如自动导入plugins: [visualizer({ open: true }),vue(),AutoImport({resolvers: [ElementPlusResolver()],}),Components({resolvers: [ElementPlusResolver()],}),],// 配置目录路径相关操作,如下@的配置resolve: {alias: {'@': fileURLToPath(new URL('./src', import.meta.url))}},// 对全局样式进行相关修改,操作相关操作css: {preprocessorOptions: {scss: {additionalData: '@use "@/assets/styles/variables.scss" as *;'}}},// 开发服务器选项,配置跨区代理api、端口等操作server: {host: "0.0.0.0",port: 3001, // 服务端口号open: true, // 服务启动时是否自动打开浏览器cors: true, // 允许跨域//配置代理proxy: {'/api': {target: '*****', // 请求地址changeOrigin: true, // 是否将发送请求host设置为当前的hostrewrite: (path) => path.replace(/^\/api/, 'api'),}}},// 打包构建相关操作build: {// 配置rollup打包项rollupOptions: {output: {// 入口文件// 自己写的js文件entryFileNames: `js/[name]-[hash].js`,// 引入的相关js、ts文件,比如分包之后的jschunkFileNames: `js/[name]-[hash].js`,// 写法1// [ext] 根据不同的后缀名进行分类// assetFileNames: `[ext]/[name]-[hash]`// 写法2// 函数的形式,可对文件进行相关操作assetFileNames: (assetInfo: any) => {if (assetInfo.name.endsWith(".css")) {return `css/[name]-[hash].css`}const imgType = ['.png', 'jpg', '.bmp', '.webp', '.svg', 'gif']if (imgType.some(ext => assetInfo.name.endsWith(ext))) {return `images/[name]-[hash].[ext]`}return `assets/[name]-[hash].[ext]`},// 对打包进行处理,项目中会用到相关的库,而打包变动时,// 这些库不需要变化,要变的只是我们修改的业务相关的js// 所以此操作对不需要变更的库进行统一处理,修改逻辑之后也不会再次进行打包manualChunks: (id) => {if (id.includes("node_modules")) {return `vender`}}},}},
})
四、webpack和vite区别
1、webpack服务器启动速度比vite慢;由于vite启动的时候不需要打包,也就无需分析模块依赖、编译,所以启动速度非常快。
2、vite热更新比webpack快;vite在hrm方面,当某个模块内容改变时,让浏览器去重新请求该模块即可。
3、vite用esbuild预构建依赖,而webpack基于node。
4、vite的生态不及webpack,加载器、插件不够丰富。
四、创建webpack和vite项目
(一)、vite项目
基于vite创建(官方推荐)
创建命令:
npm create vue@latest
具体配置:
1.创建命令
npm create vue@latest
2.具体配置
配置项目名称
Project name: vue3_test
是否添加TypeScript支持
Add TypeScript? Yes
是否添加JSX支持
Add JSX Support? No
是否添加路由环境
Add Vue Router for Single Page Application development? No
是否添加pinia环境
Add Pinia for state management? No
是否添加单元测试
Add Vitest for Unit Testing? No
是否添加端到端测试方案
Add an End-to-End Testing Solution? » No
是否添加ESLint语法检查
Add ESLint for code quality? Yes
是否添加Prettiert代码格式化
Add Prettier for code formatting? No
vite也可以搭建vue2的项目,如下操作:
vite的版本采用2.8.0的,最新的版本创建后续可能会出现问题
npm init vite@2.8.0 // 指定版本
npm init vite@latest // 正常下载
进入项目之后安装vite对vue2的依赖:
npm install vite-plugin-vue2
// 注意:vite-plugin-vue2的版本为1.9.3
npm install vite-plugin-vue2@1.9.3 -D
要使用 vite 插件,需要在项目的根目录创建 vite.config.js 文件
import { defineConfig } from 'vite'
import { createVuePlugin } from 'vite-plugin-vue2'export default defineConfig({plugins: [createVuePlugin()]
})
安装 vue 依赖
npm install vue@2
npm install vue-template-compiler通过npm install vue安装会直接安装3.0版本的因此要指定好vue版本
npm install vue@2.x vue-template-compiler@2.x -S
创建src文件夹,将main.js拉到src目录下
修改 src/main.js
import Vue from "vue";
import App from './App.vue';new Vue({el: '#app',render: h => h(App)
})或import Vue from 'vue'
import App from './App.vue'new Vue({render: h => h(App)
}).$mount('#app')
在src下创建 App.vue 文件
不推荐vite创建vue2项目,容易出问题也没有必要
(二)、webpack
用脚手架vue-cli就可以,详情看以下文章
VUE3学习笔记-CSDN博客
参考文章:
【vue3】webpack和vite介绍与使用【超详细】_vue3 webpack-CSDN博客
vite搭建vue2项目的实战过程_vue.js_脚本之家