webpack开发vue-cli的项目实践
一、vue-cli开发
1. 项目整体目录
2. package.json
{ "name": "vue-cli", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "start": "npm run dev", "dev": "cross-env NODE_ENV=development webpack serve --config ./config/webpack.config.js", "build": "cross-env NODE_ENV=production webpack --config ./config/webpack.config.js" }, "keywords": [], "author": "cx", "license": "ISC", "browserslist": [ "last 2 version", "> 1%", "not dead" ], "devDependencies": { "@babel/core": "^7.17.10", "@babel/eslint-parser": "^7.17.0", "@vue/cli-plugin-babel": "^5.0.4", "babel-loader": "^8.2.5", "copy-webpack-plugin": "^10.2.4", "cross-env": "^7.0.3", "css-loader": "^6.7.1", "css-minimizer-webpack-plugin": "^3.4.1", "eslint-plugin-vue": "^8.7.1", "eslint-webpack-plugin": "^3.1.1", "html-webpack-plugin": "^5.5.0", "image-minimizer-webpack-plugin": "^3.2.3", "imagemin": "^8.0.1", "imagemin-gifsicle": "^7.0.0", "imagemin-jpegtran": "^7.0.0", "imagemin-optipng": "^8.0.0", "imagemin-svgo": "^10.0.1", "less-loader": "^10.2.0", "mini-css-extract-plugin": "^2.6.0", "postcss-loader": "^6.2.1", "postcss-preset-env": "^7.5.0", "sass": "^1.51.0", "sass-loader": "^12.6.0", "stylus-loader": "^6.2.0", "unplugin-auto-import": "^0.7.1", "unplugin-vue-components": "^0.19.3", "vue-style-loader": "^4.1.3", "vue-template-compiler": "^2.6.14", "webpack": "^5.72.0", "webpack-cli": "^4.9.2", "webpack-dev-server": "^4.9.0" }, "dependencies": { "element-plus": "^2.2.0", "vue": "^3.2.33", "vue-router": "^4.0.15" } }
3. eslintrc.js
这里需要继承vue3的eslint校验规则
module.exports = { root: true, env: { node: true, }, extends: ["plugin:vue/vue3-essential", "eslint:recommended"], // 继承 parserOptions: { parser: "@babel/eslint-parser", // 解析器 }, };
4. babel.config.js
这里直接使用@vue/cli-plugin-babel/preset
预设,这里面已经为我们做好了各种兼容性处理和优化,不用我们在像以前一样还要自己配置core-js
,@babel/plugin-transform-runtime
等优化性的配置了。
module.exports = { presets: ["@vue/cli-plugin-babel/preset"], // 预设 };
5. webpack.config.js
const path = require("path"); const EslintWebpackPlugin = require("eslint-webpack-plugin"); // eslint检查代码 const HtmlWebpackPlugin = require("html-webpack-plugin"); // 生成html文件 const MiniCssExtractPlugin = require("mini-css-extract-plugin"); // 提取css文件 const CssMinimizerWebpackPlugin = require("css-minimizer-webpack-plugin"); // 压缩css文件 const TerserWebpackPlugin = require("terser-webpack-plugin"); // 压缩js文件 const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin"); // 压缩图片 const CopyPlugin = require("copy-webpack-plugin"); // 拷贝文件 const { VueLoaderPlugin } = require("vue-loader"); // vue-loader插件 const { DefinePlugin } = require("webpack"); // 定义环境变量 const AutoImport = require("unplugin-auto-import/webpack"); // 按需加载element-plus const Components = require("unplugin-vue-components/webpack"); // 按需加载element-plus const { ElementPlusResolver } = require("unplugin-vue-components/resolvers"); // 按需加载element-plus const isProduction = process.env.NODE_ENV === "production"; // 判断是否是生产环境 // 返回处理样式loader函数 const getStyleLoaders = (pre) => { return [ isProduction ? MiniCssExtractPlugin.loader : "vue-style-loader", "css-loader", { // 处理css兼容性问题 // 配合package.json中browserslist来指定兼容性 loader: "postcss-loader", options: { postcssOptions: { plugins: ["postcss-preset-env"], }, }, }, pre && { loader: pre, options: pre === "sass-loader" ? { additionalData: `@use "@/styles/element/index.scss" as *;`, // 自定义element-plus主题 } : {}, }, ].filter(Boolean); }; module.exports = { entry: "./src/main.js", // 入口文件 output: { // 输出文件 path: isProduction ? path.resolve(__dirname, "../dist") : undefined, // 生产环境输出路径 filename: isProduction ? "static/js/[name].[contenthash:10].js" : "static/js/[name].js", // 生产环境文件名 chunkFilename: isProduction ? "static/js/[name].[contenthash:10].chunk.js" : "static/js/[name].chunk.js", // 生产环境代码分割文件名 assetModuleFilename: "static/media/[hash:10][ext][query]", // 生产环境资源文件名 clean: true, // 清除上一次打包文件 }, module: { // 处理模块规则 rules: [ // 处理css { test: /\.css$/, use: getStyleLoaders(), }, { test: /\.less$/, use: getStyleLoaders("less-loader"), }, { test: /\.s[ac]ss$/, use: getStyleLoaders("sass-loader"), }, { test: /\.styl$/, use: getStyleLoaders("stylus-loader"), }, // 处理图片 { test: /\.(jpe?g|png|gif|webp|svg)$/, type: "asset", parser: { dataUrlCondition: { maxSize: 10 * 1024, }, }, }, // 处理其他资源 { test: /\.(woff2?|ttf)$/, type: "asset/resource", }, // 处理js { test: /\.js$/, include: path.resolve(__dirname, "../src"), loader: "babel-loader", options: { cacheDirectory: true, cacheCompression: false, }, }, { test: /\.vue$/, // 处理vue loader: "vue-loader", options: { // 开启缓存 cacheDirectory: path.resolve(__dirname, "../node_modules/.cache/vue-loader"), }, }, ], }, // 处理html plugins: [ new EslintWebpackPlugin({ // eslint检查代码 context: path.resolve(__dirname, "../src"), // 指定eslint检查的目录 exclude: "node_modules", // 排除node_modules文件夹 cache: true, // 开启缓存 cacheLocation: path.resolve(__dirname, "../node_modules/.cache/.eslintcache"), // eslint缓存cache文件夹 }), new HtmlWebpackPlugin({ // 生成html文件 template: path.resolve(__dirname, "../public/index.html"), // 指定html模板 }), isProduction && new MiniCssExtractPlugin({ // 提取css文件 filename: "static/css/[name].[contenthash:10].css", // 生产环境文件名 chunkFilename: "static/css/[name].[contenthash:10].chunk.css", // 生产环境代码分割文件名 }), isProduction && new CopyPlugin({ // 拷贝文件 patterns: [ // 拷贝文件列表 { from: path.resolve(__dirname, "../public"), // 拷贝文件源 to: path.resolve(__dirname, "../dist"), // 拷贝文件目标 globOptions: { // 忽略index.html文件 ignore: ["**/index.html"], }, }, ], }), new VueLoaderPlugin(), // vue-loader插件 // cross-env定义的环境变量给打包工具使用 // DefinePlugin定义环境变量给源代码使用,从而解决vue3页面警告的问题 new DefinePlugin({ __VUE_OPTIONS_API__: true, __VUE_PROD_DEVTOOLS__: false, }), // 按需加载element-plus AutoImport({ resolvers: [ElementPlusResolver()], }), Components({ resolvers: [ ElementPlusResolver({ // 自定义主题,引入sass importStyle: "sass", }), ], }), ].filter(Boolean), mode: isProduction ? "production" : "development", devtool: isProduction ? "source-map" : "cheap-module-source-map", // 生产环境生成source-map optimization: { // 优化 splitChunks: { // 代码分割 chunks: "all", // 分割所有代码 cacheGroups: { // 缓存组 vue: { // 分割vue test: /[\\/]node_modules[\\/]vue(.*)?[\\/]/, name: "vue-chunk", priority: 40, }, elementPlus: { // 分割element-plus test: /[\\/]node_modules[\\/]element-plus[\\/]/, name: "elementPlus-chunk", priority: 30, }, libs: { // 分割第三方库 test: /[\\/]node_modules[\\/]/, name: "libs-chunk", priority: 20, }, }, }, runtimeChunk: { name: (entrypoint) => `runtime~${entrypoint.name}.js`, // 生成runtime文件 }, minimize: isProduction, // 生产环境压缩代码 minimizer: [ new CssMinimizerWebpackPlugin(), // 压缩css文件 new TerserWebpackPlugin(), // 压缩js文件 new ImageMinimizerPlugin({ // 压缩图片 minimizer: { // 压缩器 implementation: ImageMinimizerPlugin.imageminGenerate, // 使用imagemin options: { plugins: [ ["gifsicle", { interlaced: true }], ["jpegtran", { progressive: true }], ["optipng", { optimizationLevel: 5 }], [ "svgo", { plugins: [ "preset-default", "prefixIds", { name: "sortAttrs", params: { xmlnsOrder: "alphabetical", }, }, ], }, ], ], }, }, }), ], }, // webpack解析模块加载选项 resolve: { // 自动补全文件扩展名 extensions: [".vue", ".js", ".json"], // 路径别名 alias: { "@": path.resolve(__dirname, "../src"), }, }, devServer: { host: "localhost", port: 3000, open: true, hot: true, // 开启HMR historyApiFallback: true, // 解决前端路由刷新404问题 }, performance: false, // 关闭性能提示 };
二、解读webpack.config.js关于vue的配置部分
1. module 部分
处理 Vue 单文件组件的 loader:
{ test: /\.vue$/, // 处理vue loader: "vue-loader", options: { // 开启缓存 cacheDirectory: path.resolve(__dirname, "../node_modules/.cache/vue-loader") } }
这里使用 vue-loader 处理 .vue 文件,开启缓存加快构建速度。
2. plugins 部分
VueLoaderPlugin:
new VueLoaderPlugin()
在 webpack.config.js 文件中使用了 VueLoaderPlugin,这是用于 Vue-loader 的插件,它会在开发环境下编译 Vue 单文件组件。
DefinePlugin:
new DefinePlugin({ __VUE_OPTIONS_API__: true, __VUE_PROD_DEVTOOLS__: false })
Vue 3 项目会出现页面警告,可以使用 DefinePlugin 插件定义全局变量来解决,这里定义了 VUE_OPTIONS_API 和 VUE_PROD_DEVTOOLS。
按需加载element-plus
// 按需加载element-plus AutoImport({ resolvers: [ElementPlusResolver()], }),
3. optimization 部分
这部分主要是配置优化选项,其中包括代码分割、压缩等配置。
代码分割:
splitChunks: { chunks: "all", cacheGroups: { vue: { test: /[\\/]node_modules[\\/]vue(.*)?[\\/]/, name: "vue-chunk", priority: 40 }, elementPlus: { test: /[\\/]node_modules[\\/]element-plus[\\/]/, name: "elementPlus-chunk", priority: 30 }, libs: { test: /[\\/]node_modules[\\/]/, name: "libs-chunk", priority: 20 } } }
在 webpack.config.js 文件中使用了 SplitChunksPlugin 插件对代码进行了分割,其中包括了对 Vue、Element-UI 等第三方库的分割,可以提高页面加载速度。
生产环境压缩:
minimize: isProduction, minimizer: [ new CssMinimizerWebpackPlugin(), new TerserWebpackPlugin(), new ImageMinimizerPlugin({ minimizer: { implementation: ImageMinimizerPlugin.imageminGenerate, options: { plugins: [ ["gifsicle", { interlaced: true }], ["jpegtran", { progressive: true }], ["optipng", { optimizationLevel: 5 }], [ "svgo", { plugins: [ "preset-default", "prefixIds", { name: "sortAttrs", params: { xmlnsOrder: "alphabetical" } } ] } ] ] } } }) ]
在生产环境中使用了优化插件,包括压缩 CSS、JS 和图片等资源文件。
4. resolve部分
// webpack解析模块加载选项 resolve: { // 自动补全文件扩展名 extensions: [".vue", ".js", ".json"], // 路径别名 alias: { "@": path.resolve(__dirname, "../src"), }, },
到此这篇关于webpack开发vue-cli的项目实践的文章就介绍到这了,更多相关webpack开发vue-cli内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
解决vue.js出现Vue.js not detected错误的问题
这篇文章主要介绍了解决vue.js出现Vue.js not detected错误的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教2023-10-10详解Vue 中 extend 、component 、mixins 、extends 的区别
这篇文章主要介绍了Vue 中 extend 、component 、mixins 、extends 的区别,非常不错,具有参考借鉴价值,需要的朋友可以参考下2017-12-12ElementUI之表格toggleRowSelection选中踩坑记录
这篇文章主要介绍了ElementUI之表格toggleRowSelection选中踩坑记录,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教2024-03-03详解利用 Vue.js 实现前后端分离的RBAC角色权限管理
本篇文章主要介绍了利用 Vue.js 实现前后端分离的RBAC角色权限管理,非常具有实用价值,需要的朋友可以参考下2017-09-09使用Vant完成DatetimePicker 日期的选择器操作
这篇文章主要介绍了使用Vant完成DatetimePicker 日期的选择器操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧2020-11-11
最新评论