# componenttemplate **Repository Path**: haibobo1111/componenttemplate ## Basic Information - **Project Name**: componenttemplate - **Description**: 预约类公共模板 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2022-06-09 - **Last Updated**: 2023-06-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Vue + Vant 移动端 H5 模版 ## version :1.0.0 ## Date :2021-9-18 ## 目录 ```js |____App.vue |____utils //工具类 | |____index.js | |____directive //自定义指令 | | |____index.js | |____http //axios请求 | | |____axios.js | | |____index.js |____main.js |____styles //样式类 | |____mixins //less混入样式 | | |____index.less | |____font_face //字体样式 | | |____index.css | |____index.less | |____normalize // 兼容样式 | | |____index.less | |____common // 公共样式 | | |____index.less | |____variables //样式变量 | | |____variables.less | | |____vant_variables.less //vant样式变量 | |____reset_mobile //重置样式 | | |____index.less |____components //公共组件 | |____Swiper.vue | |____GridContent.vue |____api //接口请求API | |____home | | |____index.js | |____login | | |____index.js |____views //路由页面目录 | |____home //父路由 | | |____index.vue | | |____container //子路由 | | | |____index.vue | |____notFound | | |____index.vue | |____login | | |____index.vue |____assets //静态资源 | |____2.jpg | |____3.jpg | |____1.jpg |____store //全局状态管理 | |____.DS_Store | |____index.js | |____moduleLogin | | |____index.js | |____moduleHome | | |____index.js |____router //路由文件 | |____index.js | |____routerEach.js //路由拦截 | |____routes.js //路由文件 | |____addRoute.js //添加路由 ``` ## husky git 代码提交工具 最新 husky v7.x 版本 node>=12 git >=2.9 在 packgae.json 中添加 prepare 脚本 ```js { "scripts": { "prepare": "husky install" } } ``` ```js npm install husky --save-dev ``` # commitlint 安装配置 ```js npm install --save-dev @commitlint/{cli,config-conventional} ``` # 初始化配置文件 ```js echo "module.exports = {extends: ['@commitlint/config-conventional']};" > commitlint.config.js ``` ```js module.exports = { extends: ["@commitlint/config-conventional"], rules: { "type-enum": [ 2, "always", ["feat", "fix", "docs", "style", "refactor", "test", "chore", "revert"], ], "subject-full-stop": [0, "never"], "subject-case": [0, "never"], }, }; ``` type(必须) 用于说明 git commit 的类别,只允许使用下面的标识。 feat:新功能(feature)。 fix/to:修复 bug,可以是 QA 发现的 BUG,也可以是研发自己发现的 BUG。 fix:产生 diff 并自动修复此问题。适合于一次提交直接修复问题 to:只产生 diff 不自动修复此问题。适合于多次提交。最终修复问题提交时使用 fix docs:文档(documentation)。 style:格式(不影响代码运行的变动)。 refactor:重构(即不是新增功能,也不是修改 bug 的代码变动)。 perf:优化相关,比如提升性能、体验。 test:增加测试。 chore:构建过程或辅助工具的变动。 revert:回滚到上一个版本。 merge:代码合并。 sync:同步主线或分支的 Bug。 subject(必须) subject 是 commit 目的的简短描述,不超过 50 个字符。 ## git-cz ### 安装 package.json ```js "cz-conventional-changelog": "^3.3.0", "cz-customizable": "^6.3.0", ``` ### 自定义的 Commit message 格式 ```js npm install -g commitizen ``` ```js commitizen init cz-conventional-changelog --save --save-exact ``` ### 新建 .cz-config.js ```js "use strict"; module.exports = { types: [ { value: "功能", name: "特性: 一个新的功能" }, { value: "修复", name: "修复: 修复一个Bug" }, { value: "文档", name: "文档: 变更的只有文档" }, { value: "样式", name: "格式: 空格, 分号等格式修复" }, { value: "重构", name: "重构: 代码重构,注意和特性、修复区分开" }, { value: "性能", name: "性能: 提升性能" }, { value: "测试", name: "测试: 添加一个测试" }, { value: "工具", name: "工具: 开发工具变动(构建、脚手架工具等)" }, { value: "回滚", name: "回滚: 代码回退" }, ], scopes: [{ name: "UE静态页面" }, { name: "FE功能接口" }], // it needs to match the value for field type. Eg.: 'fix' /* scopeOverrides: { fix: [ {name: 'merge'}, {name: 'style'}, {name: 'e2eTest'}, {name: 'unitTest'} ] }, */ // override the messages, defaults are as follows messages: { type: "选择一种你的提交类型:", scope: "选择一个scope (可选):", // used if allowCustomScopes is true customScope: "Denote the SCOPE of this change:", subject: "短说明:\n", body: '长说明,使用"|"换行(可选):\n', // breaking: "非兼容性说明 (可选):\n", // footer: "关联关闭的issue,例如:#31, #34(可选):\n", confirmCommit: "确定提交说明?", }, allowCustomScopes: true, allowBreakingChanges: ["特性", "修复"], // limit subject length subjectLimit: 100, }; ``` ### package.json ```js "config": { "commitizen": { "path": "node_modules/cz-customizable" } } ``` ## 自动按需引入组件 babel-plugin-import 是一款 babel 插件,它会在编译过程中将 import 的写法自动转换为按需引入的方式。我们选择此方式。 ### 安装 ```js npm i babel-plugin-import -D ``` ### 在 babel.config.js 中添加配置 ```js module.exports = { presets: ["@vue/cli-plugin-babel/preset"], plugins: [ [ "import", { libraryName: "Vant", libraryDirectory: "es", style: true, }, ], ], }; ``` ## 适配 ### 安装 ```js npm install amfe-flexible postcss-px2rem -S ``` amfe-flexible:是 rem 的适配插件。(例:750px == 10rem) postcss-px2rem:负责将输入的 px 自动转为 rem。 #### 在项目根目录下添加 postcss.config.js 文件,配置如下 ```js // css相关配置 css: { // 是否开启 CSS source maps sourceMap: false, loaderOptions: { postcss: { plugins: [ // 设计稿宽度的1/10,一般为75 require("postcss-px2rem")({ remUnit: 75, }), ], }, }, }, ``` ### 解决 css 移动端字母或者文字大小有时会变化的问题 ```css html { -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; } ``` ### dayjs 为现代浏览器解析、验证、操作和显示日期和时间 ```js npm install dayjs --save ``` ## 打包优化 ### 代码压缩 去除 console.log 打印以及注释 ```js npm install uglifyjs-webpack-plugin --save-dev ``` ```js const UglifyJsPlugin = require('uglifyjs-webpack-plugin') const isProduction = process.env.NODE_ENV === 'production'; configureWebpack: config => { const plugins = []; if (isProduction) { plugins.push( new UglifyJsPlugin({ uglifyOptions: { output: { comments: false, // 去掉注释 }, warnings: false, compress: { drop_console: true, drop_debugger: false, pure_funcs: ['console.log']//移除console } } }) ) } }, ``` ### 使用 CDN 加速优化 ```js const isProduction = process.env.NODE_ENV === "production"; // externals const externals = { vue: "Vue", "vue-router": "VueRouter", vuex: "Vuex", vant: "vant", axios: "axios", }; // CDN外链,会插入到index.html中 const cdn = { // 开发环境 dev: { css: [], js: [], }, // 生产环境 build: { css: ["https://unpkg.com/browse/vant@2.12.26/lib/index.less"], js: [ "https://unpkg.com/vue@2.6.11/dist/vue.min.js", "https://unpkg.com/vue-router@3.5.2/dist/vue-router.min.js", "https://unpkg.com/vuex@3.6.2/dist/vuex.min.js", "https://unpkg.com/browse/vant@2.12.26/lib/vant.min.js", "https://unpkg.com/axios@0.21.4/dist/axios.min.js", ], }, }; module.exports = { configureWebpack: (config) => { // 为生产环境修改配置... if (isProduction) { // externals config.externals = externals; } }, chainWebpack: (config) => { /** * 添加CDN参数到htmlWebpackPlugin配置中 */ config.plugin("html").tap((args) => { if (isProduction) { args[0].cdn = cdn.build; } else { args[0].cdn = cdn.dev; } return args; }); }, }; ``` ### 对资源文件进行压缩 安装低版本 ```js npm i compression-webpack-plugin@5.0.1 ``` ```js const CompressionWebpackPlugin = require("compression-webpack-plugin"); module.exports = { // 根据你的实际情况更改这里 publicPath, assetsDir: "assets", lintOnSave: true, configureWebpack: { plugins: [ new CompressionWebpackPlugin({ filename: "[path].gz[query]", algorithm: "gzip", // test: /\.js$|\.html$|\.json$|\.css/, test: /\.js$|\.json$|\.css/, threshold: 10240, // 只有大小大于该值的资源会被处理 minRatio: 0.8, // 只有压缩率小于这个值的资源才会被处理 // deleteOriginalAssets: true // 删除原文件 }), ], }, }; ``` #### 压缩后也会节省一部分空间,单后端要对 nginx 修改,配合前端 #### nginx 配置示例: ```js location ~ .*\.(js|json|css)$ { gzip on; gzip_static on; # gzip_static是nginx对于静态文件的处理模块,该模块可以读取预先压缩的gz文件,这样可以减少每次请求进行gzip压缩的CPU资源消耗。 gzip_min_length 1k; gzip_http_version 1.1; gzip_comp_level 9; gzip_types text/css application/javascript application/json; root /dist; } ``` #### 图片压缩 ```js npm install image-webpack-loader --save-dev ``` ```js module.exports = { // 根据你的实际情况更改这里 publicPath, assetsDir: "assets", lintOnSave: true, // image 压缩 定义在chainWebpack中 chainWebpack: (config) => { config.module .rule("images") .use("image-webpack-loader") .loader("image-webpack-loader") .options({ bypassOnDebug: true, }) .end(); }, }; ``` #### 只打包改变的文件 ```js const { HashedModuleIdsPlugin } = require("webpack"); configureWebpack: (config) => { const plugins = []; plugins.push(new HashedModuleIdsPlugin()); }; ``` #### 公共代码抽离 ```js config.optimization = { splitChunks: { //默认作用于异步chunk,值为all/initial/async/function(chunk),值为function时第一个参数为遍历所有入口chunk时的chunk模块,chunk._modules为chunk所有依赖的模块,通过chunk的名字和所有依赖模块的resource可以自由配置,会抽取所有满足条件chunk的公有模块,以及模块的所有依赖模块,包括css chunks: "async", minSize: 30000, //表示在压缩前的最小模块大小,默认值是30kb minChunks: 1, // 表示被引用次数,默认为1; maxAsyncRequests: 5, //所有异步请求不得超过5个 maxInitialRequests: 3, //初始话并行请求不得超过3个 automaticNameDelimiter: "~", //名称分隔符,默认是~ name: true, //打包后的名称,默认是chunk的名字通过分隔符(默认是~)分隔 cacheGroups: { // 缓存组 vendors: { name: `chunk-vendors`, test: /[\\/]node_modules[\\/]/, priority: -10, // 缓存组权重,数字越大优先级越高 chunks: "initial", // 只处理初始 chunk }, common: { name: `chunk-common`, minChunks: 2, // common 组的模块必须至少被 2 个 chunk 共用 (本次分割前) priority: -20, chunks: "initial", // 只针对同步 chunk reuseExistingChunk: true, // 复用已被拆出的依赖模块,而不是继续包含在该组一起生成 }, }, }, }; ``` #### 配置打包分析 ```js npm i webpack-bundle-analyzer -D ``` ```js const BundleAnalyzerPlugin = require("webpack-bundle-analyzer") .BundleAnalyzerPlugin; module.exports = { chainWebpack: (config) => { // 打包分析 if (IS_PROD) { config.plugin("webpack-report").use(BundleAnalyzerPlugin, [ { analyzerMode: "static", }, ]); } }, }; ```