Vue-13.创建完整的Vue项目(vue+vue-cli+js)-1

news2024/9/25 13:15:34

前言

之前写了命令创建Vue项目,但是事实上我们可以直接用编译器直接创建项目,这里我使用webstorm(因为我是前后端兼修的所以我习惯使用Idea家族的编译器)

  • 只写前端的推荐用VsCode
  • 前后端都写的推荐用webstorm

新建项目

在这里插入图片描述

项目初始目录

yueerba/                  # 项目根目录
├── node_modules/         # 依赖包安装目录,包含项目所需的所有第三方依赖
├── public/               # 公共资源目录,用于存放不需要经过构建的静态资源
│   ├── index.html        # 主页面模板,作为整个应用的入口页面
│   └── ...
├── src/                  # 源代码目录,包含应用的核心代码
│   ├── assets/           # 静态资源,如图像、样式等
│   ├── components/       # Vue组件,用于构建页面和 UI
│   ├── views/            # 页面级组件,通常和路由相关
│   ├── App.vue           # 根组件,应用的主要 Vue 组件
│   └── main.js           # 项目入口文件,初始化 Vue 应用和导入全局资源
├── .gitignore            # Git 忽略配置文件,指定哪些文件或目录不会被提交到版本控制
├── babel.config.js       # Babel 配置文件,用于转译新的 JavaScript 语法特性
├── jsconfig.json         # JavaScript 项目配置文件,配置代码智能感知等
├── package.json          # 项目依赖和配置文件,包含项目的元数据和依赖信息
├── README.md             # 项目说明文件,描述项目的基本信息和使用说明
├── vue.config.js         # Vue CLI 配置文件,用于自定义 Vue 项目的构建和开发配置
├── yarn.lock             # 锁定依赖版本的文件,确保依赖在不同环境中的一致性

新建.env

.env

NODE_ENV=production
VUE_APP_PREVIEW=false
VUE_APP_BASE_API=/api

.env.development

NODE_ENV=development
VUE_APP_PREVIEW=true
VUE_APP_BASE_API=/api

.env.preview

NODE_ENV=production
VUE_APP_PREVIEW=true
VUE_APP_BASE_API=/api

移除package.json 中的eslintConfig和browserslist配置

{
  "name": "yueerba",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint"
  },
  "dependencies": {
    "core-js": "^3.8.3",
    "vue": "^3.2.13"
  },
  "devDependencies": {
    "@babel/core": "^7.12.16",
    "@babel/eslint-parser": "^7.12.16",
    "@vue/cli-plugin-babel": "~5.0.0",
    "@vue/cli-plugin-eslint": "~5.0.0",
    "@vue/cli-service": "~5.0.0",
    "eslint": "^7.32.0",
    "eslint-plugin-vue": "^8.0.3"
  },
  "eslintConfig": {
    "root": true,
    "env": {
      "node": true
    },
    "extends": [
      "plugin:vue/vue3-essential",
      "eslint:recommended"
    ],
    "parserOptions": {
      "parser": "@babel/eslint-parser"
    },
    "rules": {}
  },
  "browserslist": [
    "> 1%",
    "last 2 versions",
    "not dead",
    "not ie 11"
  ]
}

新建.browserslistrc

> 1%              ## 适用于市场份额大于1%的浏览器
last 2 versions   ## 适用于每个浏览器的最近两个版本
not dead          ## 排除已不再被支持的浏览器
not ie 11         ## 排除Internet Explorer 11

新建.editorconfig

# 通用设置
[*]
# 使用 UTF-8 字符集
charset = utf-8
# 使用 LF(换行符)
end_of_line = lf
# 文件末尾不需要插入空行
insert_final_newline = false
# 使用空格作为缩进
indent_style = space
# 缩进大小为 2 个空格
indent_size = 2

# 针对特定文件类型的设置
[{*.ng,*.sht,*.html,*.shtm,*.shtml,*.htm}]
# 使用空格作为缩进
indent_style = space
# 缩进大小为 2 个空格
indent_size = 2

# 针对另一系列文件类型的设置
[{*.jhm,*.xslt,*.xul,*.rng,*.xsl,*.xsd,*.ant,*.tld,*.fxml,*.jrxml,*.xml,*.jnlp,*.wsdl}]
# 使用空格作为缩进
indent_style = space
# 缩进大小为 2 个空格
indent_size = 2

# 针对一些配置文件的设置
[{.babelrc,.stylelintrc,jest.config,.eslintrc,.prettierrc,*.json,*.jsb3,*.jsb2,*.bowerrc}]
# 使用空格作为缩进
indent_style = space
# 缩进大小为 2 个空格
indent_size = 2

# 针对 .svg 文件的设置
[*.svg]
# 使用空格作为缩进
indent_style = space
# 缩进大小为 2 个空格
indent_size = 2

# 针对 .js.map 文件的设置
[*.js.map]
# 使用空格作为缩进
indent_style = space
# 缩进大小为 2 个空格
indent_size = 2

# 针对 .less 文件的设置
[*.less]
# 使用空格作为缩进
indent_style = space
# 缩进大小为 2 个空格
indent_size = 2

# 针对 .vue 文件的设置
[*.vue]
# 使用空格作为缩进
indent_style = space
# 缩进大小为 2 个空格
indent_size = 2

# 针对另一些配置文件的设置
[{.analysis_options,*.yml,*.yaml}]
# 使用空格作为缩进
indent_style = space
# 缩进大小为 2 个空格
indent_size = 2

新建.eslintrc.js

module.exports = {
  root: true, // 根配置文件
  env: {
    node: true, // 运行环境为 Node.js
  },
  extends: [
    'plugin:vue/vue3-essential', // 使用 Vue 3 的基本规则
    'eslint:recommended', // 使用 ESLint 推荐的规则
    'plugin:prettier/recommended', // 集成 Prettier 的推荐规则
  ],
  parserOptions: {
    parser: '@babel/eslint-parser', // 使用 Babel 解析器
  },
  rules: {
    'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off', // 在生产环境禁用 debugger
    'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off', // 在生产环境禁用 console
    'space-before-function-paren': 0, // 函数定义括号前不需要空格
    'vue/require-default-prop': 'off', // 不要求默认的 prop
    'vue/require-prop-types': 'off', // 不要求 prop 的类型
    'generator-star-spacing': 'off', // 禁用 generator 函数 * 后的空格警告
    'no-mixed-operators': 0, // 允许混合使用运算符
    'vue/max-attributes-per-line': [
      // 每行最多属性数
      2,
      {
        singleline: 5, // 单行最多 5 个属性
        multiline: 1, // 多行模式下每行最大属性数量
      },
    ],
    'vue/attribute-hyphenation': 0, // 不强制属性使用连字符
    'vue/html-self-closing': 0, // 不强制自闭合标签
    'vue/component-name-in-template-casing': 0, // 组件名大小写不敏感
    'vue/html-closing-bracket-spacing': 0, // 不强制标签闭合前的空格
    'vue/singleline-html-element-content-newline': 0, // 单行元素内容不需要新行
    'vue/no-unused-components': 0, // 允许定义未使用的组件
    'vue/multiline-html-element-content-newline': 0, // 多行元素内容不需要新行
    'vue/no-use-v-if-with-v-for': 0, // 允许同时使用 v-if 和 v-for
    'vue/html-closing-bracket-newline': 0, // 标签闭合括号不需要新行
    'vue/no-parsing-error': 0, // 允许存在解析错误
    'no-tabs': 0, // 允许使用制表符
    quotes: [
      // 引号配置
      2,
      'single',
      {
        avoidEscape: true, // 避免转义
        allowTemplateLiterals: true, // 允许模板字符串
      },
    ],
    semi: [
      // 分号配置
      2,
      'never',
      {
        beforeStatementContinuationChars: 'never',
      },
    ],
    'no-delete-var': 2, // 禁止删除变量
    'prefer-const': [
      // 建议使用 const
      2,
      {
        ignoreReadBeforeAssign: false,
      },
    ],
    'template-curly-spacing': 'off', // 关闭模板字符串中花括号间的空格
    indent: 'off', // 关闭缩进检查
  },
  overrides: [
    {
      files: ['**/__tests__/*.{j,t}s?(x)', '**/tests/unit/**/*.spec.{j,t}s?(x)'],
      env: {
        jest: true, // 在测试文件中启用 Jest 环境
      },
    },
  ],
}

新建.prettierrc

{
  "printWidth": 120,
  "semi": false,
  "singleQuote": true,
  "prettier.spaceBeforeFunctionParen": true
}

新增依赖

删除所有依赖项

删除node_modules文件夹,并删除对应的配置

{
  "name": "yueerba",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint"
  },
  "dependencies": {
   
  },
  "devDependencies": {
  
  }
}

安装生产依赖项(都取最新的)

npm install ant-design-vue axios core-js echarts enquire.js highlight.js lodash.clonedeep lodash.get lodash.pick md5 mockjs2 moment nprogress sortablejs store v-viewer vditor vue vue-clipboard2 vue-container-query vue-copy-to-clipboard vue-cropper vue-grid-layout vue-i18n vue-router vue-svg-component-runtime vue-upload-component vuex

安装开发依赖项(都取最新的)

npm install -D @ant-design/colors @vue/cli-plugin-babel @vue/cli-plugin-eslint @vue/cli-plugin-router @vue/cli-plugin-unit-jest @vue/cli-plugin-vuex @vue/cli-service @vue/eslint-config-standard @vue/test-utils babel-eslint babel-plugin-import babel-plugin-transform-remove-console compression-webpack-plugin eslint eslint-plugin-html eslint-plugin-react eslint-plugin-vue git-revision-webpack-plugin less less-loader opencollective opencollective-postinstall vue-svg-icon-loader vue-template-compiler webpack-theme-color-replacer

完成之后生成的依赖项,并补全一下配置

```json
{
  "name": "yueerba",  // 项目名称
  "version": "0.1.0",  // 项目版本
  "private": true,  // 声明项目为私有
  "scripts": {
    "dev": "set NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service serve",  // 启动开发服务器的命令
    "build": "set NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service build",  // 构建生产版本的命令
    "test:unit": "set NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service test:unit",  // 运行单元测试的命令
    "lint": "set NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service lint",  // 运行代码风格检查的命令
    "build:preview": "set NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service build --mode preview",  // 构建预览版本的命令
    "lint:nofix": "set NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service lint --no-fix"  // 运行代码风格检查,但不自动修复的命令
  },
  "dependencies": {
    // Ant Design 的 Vue 组件库
    "ant-design-vue": "^4.0.0",
    // HTTP 请求库
    "axios": "^1.4.0",
    // JavaScript 标准库的新特性的垫片
    "core-js": "^3.8.3",
    // 可视化图表库
    "echarts": "^5.4.3",
    // 媒体查询库,用于响应式设计
    "enquire.js": "^2.1.6",
    // 代码高亮库
    "highlight.js": "^11.8.0",
    // Lodash 的深拷贝函数
    "lodash.clonedeep": "^4.5.0",
    // Lodash 的属性获取函数
    "lodash.get": "^4.4.2",
    // Lodash 的属性选择函数
    "lodash.pick": "^4.4.0",
    // MD5 哈希函数
    "md5": "^2.3.0",
    // 生成模拟数据的库
    "mockjs2": "^1.0.8",
    // 日期时间操作库
    "moment": "^2.29.4",
    // 页面加载进度条库
    "nprogress": "^0.2.0",
    // 可拖拽排序库
    "sortablejs": "^1.15.0",
    // 数据持久化库
    "store": "^2.0.12",
    // 图片查看器
    "v-viewer": "^1.6.4",
    // 实时预览 Markdown 编辑器
    "vditor": "^3.9.4",
    // Vue.js 框架
    "vue": "^3.2.13",
    // 复制文本到剪贴板库
    "vue-clipboard2": "^0.3.3",
    // Vue 容器查询库
    "vue-container-query": "^0.1.0",
    // 复制文本到剪贴板的 Vue 组件
    "vue-copy-to-clipboard": "^1.0.3",
    // 图片剪裁组件
    "vue-cropper": "^0.6.2",
    // 可拖拽布局库
    "vue-grid-layout": "^2.4.0",
    // 国际化库
    "vue-i18n": "^9.2.2",
    // Vue 路由库
    "vue-router": "^4.2.4",
    // 在运行时渲染 Vue 组件的 SVG 图标库
    "vue-svg-component-runtime": "^1.0.1",
    // Vue 文件上传组件
    "vue-upload-component": "^2.8.23",
    // Vue 状态管理库
    "vuex": "^4.1.0"
  },
  "devDependencies": {
    // Ant Design 的颜色库
    "@ant-design/colors": "^7.0.0",
    // Vue CLI 插件,用于集成 Babel
    "@vue/cli-plugin-babel": "^5.0.8",
    // Vue CLI 插件,用于集成 ESLint
    "@vue/cli-plugin-eslint": "^5.0.8",
    // Vue CLI 插件,用于集成 Vue 路由
    "@vue/cli-plugin-router": "^5.0.8",
    // Vue CLI 插件,用于集成 Jest 进行单元测试
    "@vue/cli-plugin-unit-jest": "^5.0.8",
    // Vue CLI 插件,用于集成 Vuex 状态管理
    "@vue/cli-plugin-vuex": "^5.0.8",
    // Vue CLI 服务,用于启动开发服务器和构建应用
    "@vue/cli-service": "^5.0.8",
    // Vue 的 ESLint 配置,基于标准规范
    "@vue/eslint-config-standard": "^8.0.1",
    // Vue 的测试工具库
    "@vue/test-utils": "^2.4.1",
    // Babel 解析器,用于在 ESLint 中解析 JavaScript
    "babel-eslint": "^10.1.0",
    // Babel 插件,用于按需导入 Ant Design 的组件
    "babel-plugin-import": "^1.13.8",
    // Babel 插件,用于移除控制台输出
    "babel-plugin-transform-remove-console": "^6.9.4",
    // Webpack 插件,用于压缩文件
    "compression-webpack-plugin": "^10.0.0",
    // ESLint,用于检查代码规范
    "eslint": "^8.47.0",
    // ESLint 插件,用于处理 HTML 文件中的脚本块
    "eslint-plugin-html": "^7.1.0",
    // ESLint 插件,用于检查 React 代码规范
    "eslint-plugin-react": "^7.33.2",
    // ESLint 插件,用于检查 Vue 代码规范
    "eslint-plugin-vue": "^9.17.0",
    // Webpack 插件,用于获取 Git 版本信息
    "git-revision-webpack-plugin": "^5.0.0",
    // Less 编译器
    "less": "^4.2.0",
    // Less 加载器,用于将 Less 转换成 CSS
    "less-loader": "^11.1.3",
    // Open Collective 支持库
    "opencollective": "^1.0.3",
    // Open Collective 安装后脚本
    "opencollective-postinstall": "^2.0.3",
    // Vue SVG 图标加载器
    "vue-svg-icon-loader": "^2.1.1",
    // Vue 模板编译器
    "vue-template-compiler": "^2.7.14",
    // Webpack 主题颜色替换插件
    "webpack-theme-color-replacer": "^1.4.7"
  }
}

少了的依赖项

npm install webpack
npm install eslint eslint-plugin-vue @vue/eslint-config-prettier prettier --save-dev
npm install @babel/eslint-parser --save-dev

需要移除的依赖

npm uninstall babel-eslint --save-dev

配置一下eslint设置

在这里插入图片描述

更改babel.config.js

const IS_PROD = ['production', 'prod'].includes(process.env.NODE_ENV)

const plugins = []
if (IS_PROD) {
  plugins.push('transform-remove-console') // 如果是生产环境,移除 console
}

// 懒加载 ant-design-vue
// 如果您使用按需导入,使用以下代码
plugins.push([
  'import',
  {
    libraryName: 'ant-design-vue',
    libraryDirectory: 'es',
    style: true, // `style: true` 会加载 less 文件
  },
])

module.exports = {
  presets: [
    '@vue/cli-plugin-babel/preset',
    [
      '@babel/preset-env',
      {
        useBuiltIns: 'entry',
        corejs: 3,
      },
    ],
  ],
  plugins,
}

更改jsconfig.json

{
  "compilerOptions.comment": {
    "target": "目标编译版本为 ECMAScript 6",
    "module": "生成模块的代码风格为 ES6 模块规范",
    "moduleResolution": "模块解析策略为 Node.js 风格",
    "baseUrl": "模块导入时的基本路径,这里设置为当前目录",
    "paths": "模块导入路径的映射,以 @/ 开头的映射到 src/ 目录",
    "lib": "包含的 TypeScript 标准库文件,包括最新特性、DOM 相关定义和宿主环境定义"
  },
  "compilerOptions": {
    "target": "es6",
    "module": "esnext",
    "moduleResolution": "node",
    "baseUrl": "./",
    "paths": {
      "@/*": ["src/*"]
    },
    "lib": [
      "esnext",
      "dom",
      "dom.iterable",
      "scripthost"
    ]
  },
  "exclude.comment": {
    "exclude": "排除的文件或文件夹,不会被编译"
  },
  "exclude": ["node_modules", "dist"],
  "include.comment": {
    "include": "包含的文件,会被编译"
  },
  "include": ["src/**/*"]
}

更新vue.config.js

const webpack = require('webpack')
const path = require('path')
const { GitRevisionPlugin } = require('git-revision-webpack-plugin')
const GitRevision = new GitRevisionPlugin()
const buildDate = JSON.stringify(new Date().toLocaleString())
const createThemeColorReplacerPlugin = require('./config/plugin.config')
const CompressionWebpackPlugin = require('compression-webpack-plugin')
const productionGzipExtensions = ['js', 'css']

function resolve(dir) {
  return path.join(__dirname, dir)
}

// 获取当前 Git 版本哈希值
function getGitHash() {
  try {
    return GitRevision.version()
  } catch (e) {
    /* empty */
  }
  return 'unknown'
}

// 判断是否为生产环境
const isProd = process.env.NODE_ENV === 'production'

// 外部 CDN 资源配置
const assetsCDN = {
  externals: {
    vue: 'Vue',
    'vue-router': 'VueRouter',
    vuex: 'Vuex',
    axios: 'axios',
  },
  css: [],
  js: [
    '//cdn.jsdelivr.net/npm/vue@3.2.13/dist/vue.global.min.js',
    '//cdn.jsdelivr.net/npm/vue-router@4.2.4/dist/vue-router.min.js',
    '//cdn.jsdelivr.net/npm/vuex@4.1.0/dist/vuex.min.js',
    '//cdn.jsdelivr.net/npm/axios@1.4.0/dist/axios.min.js',
  ],
}

// Vue 配置对象
const vueConfig = {
  configureWebpack: {
    plugins: [
      // 忽略 moment.js 中的所有本地化文件
      new webpack.IgnorePlugin({
        resourceRegExp: /^\.\/locale$/,
        contextRegExp: /moment$/,
      }),
      // 定义全局常量,用于标识应用的版本、Git 哈希值和构建日期
      new webpack.DefinePlugin({
        APP_VERSION: `"${require('./package.json').version}"`,
        GIT_HASH: JSON.stringify(getGitHash()),
        BUILD_DATE: buildDate,
      }),
      // 配置 compression-webpack-plugin 压缩插件
      new CompressionWebpackPlugin({
        algorithm: 'gzip',
        // 仅压缩指定文件类型的文件
        test: new RegExp('\\.(' + productionGzipExtensions.join('|') + ')$'),
        // 文件大小大于 10KB 时才会进行压缩
        threshold: 10240,
        // 压缩比例设置
        minRatio: 0.8,
      }),
    ],
    // 如果是生产环境,则引用外部库,避免打包到项目中
    externals: isProd ? assetsCDN.externals : {},
  },

  chainWebpack: (config) => {
    // 配置路径别名,方便在代码中引用
    config.resolve.alias
      .set('@$', resolve('src'))
      .set('@assets', resolve('src/assets'))
      .set('@views', resolve('src/views'))

    // 处理 SVG 文件,支持内联和外部引用
    const svgRule = config.module.rule('svg')
    svgRule.uses.clear()
    svgRule
      .oneOf('inline')
      .resourceQuery(/inline/)
      .use('vue-svg-icon-loader')
      .loader('vue-svg-icon-loader')
      .end()
      .end()
      .oneOf('external')
      .use('file-loader')
      .loader('file-loader')
      .options({
        name: 'assets/[name].[hash:8].[ext]',
      })

    // 如果是生产环境,将 CDN 资源添加到 HTML 中
    if (isProd) {
      config.plugin('html').tap((args) => {
        args[0].cdn = assetsCDN
        return args
      })
    }
  },

  css: {
    // 配置 Less 主题
    loaderOptions: {
      less: {
        modifyVars: {
          // 修改 Ant Design 主题颜色
          'primary-color': '#2f54eb',
        },
        javascriptEnabled: true,
      },
    },
  },

  devServer: {
    // 开发服务器端口
    port: 80,
    // 配置代理,将请求转发到后端 API
    proxy: {
      [process.env.VUE_APP_BASE_API]: {
        target: `http://127.0.0.1:8080`,
        changeOrigin: true,
        pathRewrite: {
          ['^' + process.env.VUE_APP_BASE_API]: '',
        },
      },
    },
    disableHostCheck: true, // 解决使用外网映射工具映射时的报错
  },

  // 是否生成生产环境的 Source Map
  productionSourceMap: false,
  lintOnSave: undefined,
  // 指定需要进行 Babel 转译的依赖
  transpileDependencies: ['core-js', 'register-service-worker'],

  // Vue 3 的新特性,开启
  runtimeCompiler: true,
}

// 仅在预览模式下启用插件
if (process.env.VUE_APP_PREVIEW === 'true') {
  console.log('VUE_APP_PREVIEW', true)
  // 添加创建主题颜色替换插件到 webpack 插件中
  vueConfig.configureWebpack.plugins.push(createThemeColorReplacerPlugin())
}

// 导出 Vue 配置对象
module.exports = vueConfig

plugin.config.js

// 引入 webpack-theme-color-replacer 模块
const ThemeColorReplacer = require('webpack-theme-color-replacer')
// 引入 ant-design/colors 中的生成函数
const generate = require('@ant-design/colors/lib/generate').default

// 获取一系列 Ant Design 的颜色变化
const getAntdSerials = (color) => {
  // 淡化(即 less 的 tint)
  const lightens = new Array(9).fill().map((t, i) => {
    return ThemeColorReplacer.varyColor.lighten(color, i / 10)
  })
  // 生成颜色调色板
  const colorPalettes = generate(color)
  // 将颜色转换为 RGB 值
  const rgb = ThemeColorReplacer.varyColor.toNum3(color.replace('#', '')).join(',')
  return lightens.concat(colorPalettes).concat(rgb)
}

// 定义主题颜色替换插件的配置选项
const themePluginOption = {
  fileName: 'css/theme-colors-[contenthash:8].css', // 输出文件名,含 hash 值
  matchColors: getAntdSerials('#1890ff'), // 主色系列为 #1890ff
  // 修改样式选择器,以解决样式覆盖问题
  changeSelector(selector) {
    switch (selector) {
      // 添加选择器的修改规则
      case '.ant-calendar-today .ant-calendar-date':
        return ':not(.ant-calendar-selected-date):not(.ant-calendar-selected-day)' + selector
      case '.ant-btn:focus,.ant-btn:hover':
        return '.ant-btn:focus:not(.ant-btn-primary):not(.ant-btn-danger),.ant-btn:hover:not(.ant-btn-primary):not(.ant-btn-danger)'
      case '.ant-btn.active,.ant-btn:active':
        return '.ant-btn.active:not(.ant-btn-primary):not(.ant-btn-danger),.ant-btn:active:not(.ant-btn-primary):not(.ant-btn-danger)'
      case '.ant-steps-item-process .ant-steps-item-icon > .ant-steps-icon':
      case '.ant-steps-item-process .ant-steps-item-icon>.ant-steps-icon':
        return ':not(.ant-steps-item-process)' + selector
      // 添加更多选择器的修改规则
      default:
        return selector
    }
  },
}

// 创建主题颜色替换插件并导出
const createThemeColorReplacerPlugin = () => new ThemeColorReplacer(themePluginOption)

module.exports = createThemeColorReplacerPlugin

themePluginConfig.js

// 导出一个主题配置对象,用于实现动态切换应用的主题色
export default {
  theme: [
    // 明亮主题选项
    {
      key: 'dark', // 主题的唯一标识
      fileName: 'dark.css', // 输出的主题样式文件名
      theme: 'dark', // 主题类型为深色
    },
    {
      key: '#F5222D',
      fileName: '#F5222D.css',
      modifyVars: {
        '@primary-color': '#F5222D', // 修改主题颜色变量
      },
    },
    {
      key: '#FA541C',
      fileName: '#FA541C.css',
      modifyVars: {
        '@primary-color': '#FA541C',
      },
    },
    {
      key: '#FAAD14',
      fileName: '#FAAD14.css',
      modifyVars: {
        '@primary-color': '#FAAD14',
      },
    },
    {
      key: '#13C2C2',
      fileName: '#13C2C2.css',
      modifyVars: {
        '@primary-color': '#13C2C2',
      },
    },
    {
      key: '#52C41A',
      fileName: '#52C41A.css',
      modifyVars: {
        '@primary-color': '#52C41A',
      },
    },
    {
      key: '#2F54EB',
      fileName: '#2F54EB.css',
      modifyVars: {
        '@primary-color': '#2F54EB',
      },
    },
    {
      key: '#722ED1',
      fileName: '#722ED1.css',
      modifyVars: {
        '@primary-color': '#722ED1',
      },
    },

    // 深色主题选项
    {
      key: '#F5222D',
      theme: 'dark', // 主题类型为深色
      fileName: 'dark-#F5222D.css',
      modifyVars: {
        '@primary-color': '#F5222D',
      },
    },
    {
      key: '#FA541C',
      theme: 'dark',
      fileName: 'dark-#FA541C.css',
      modifyVars: {
        '@primary-color': '#FA541C',
      },
    },
    {
      key: '#FAAD14',
      theme: 'dark',
      fileName: 'dark-#FAAD14.css',
      modifyVars: {
        '@primary-color': '#FAAD14',
      },
    },
    {
      key: '#13C2C2',
      theme: 'dark',
      fileName: 'dark-#13C2C2.css',
      modifyVars: {
        '@primary-color': '#13C2C2',
      },
    },
    {
      key: '#52C41A',
      theme: 'dark',
      fileName: 'dark-#52C41A.css',
      modifyVars: {
        '@primary-color': '#52C41A',
      },
    },
    {
      key: '#2F54EB',
      theme: 'dark',
      fileName: 'dark-#2F54EB.css',
      modifyVars: {
        '@primary-color': '#2F54EB',
      },
    },
    {
      key: '#722ED1',
      theme: 'dark',
      fileName: 'dark-#722ED1.css',
      modifyVars: {
        '@primary-color': '#722ED1',
      },
    },
  ],
}

新增jest.config.js

module.exports = {
  preset: "@vue/cli-plugin-unit-jest",
};

在这里插入图片描述

import { shallowMount } from '@vue/test-utils'
import HelloWorld from '@/components/HelloWorld.vue'

describe('HelloWorld.vue', () => {
  it('renders props.msg when passed', () => {
    const msg = 'new message'
    const wrapper = shallowMount(HelloWorld, {
      props: { msg },
    })
    expect(wrapper.text()).toMatch(msg)
  })
})

安装并使用cypress

在项目中集成 Cypress 并使用它进行端到端测试是一个很好的实践,可以帮助您确保应用的各个部分都正常工作。以下是集成 Cypress 并进行测试的一般步骤:
如果你选择下载 Cypress 的压缩包并手动安装,可以按照以下步骤进行操作:

  1. 设置环境变量 CYPRESS_INSTALL_BINARY:
    在这里插入图片描述

  2. 下载对应的安装包,然后在项目目录下的终端窗口执行以下命令:

npm config set CYPRESS_INSTALL_BINARY="${C:\\Users\\binary\\cypress.zip}
  1. 安装 Cypress

在项目根目录下,使用以下命令安装 Cypress:

npm install cypress --save-dev
  1. 创建如下测试结构
    在这里插入图片描述

  2. 创建 Cypress 配置文件

  • 在项目根目录下,创建 cypress.config.js 文件,并根据项目需要配置 Cypress。以下是一个简单的示例:
const { defineConfig } = require('cypress')

module.exports = defineConfig({
  // 指定测试用例的 fixtures 文件夹路径
  fixturesFolder: 'tests/e2e/fixtures',
  // 指定截图保存的文件夹路径
  screenshotsFolder: 'tests/e2e/screenshots',
  // 指定录像保存的文件夹路径
  videosFolder: 'tests/e2e/videos',
  e2e: {
    // 这里导入了旧的 Cypress 插件。稍后您可能希望通过导入这些插件来清理代码。
    // 用于设置 Cypress 节点事件的回调函数
    setupNodeEvents(on, config) {
      // 使用 './tests/e2e/plugins/index.js' 文件中的回调函数
      return require('./tests/e2e/plugins/index.js')(on, config)
    },
    // 使用新的配置选项 e2e.specPattern 来指定测试用例的匹配模式
    specPattern: 'tests/e2e/specs/**/*.cy.{js,jsx,ts,tsx}',
    // 指定支持文件的路径
    supportFile: 'tests/e2e/support/index.js',
  },
})


  1. 创建tests/e2e/plugins/index.js
module.exports = (on, config) => {
  // 注释: 使用 on 函数注册文件预处理器,这里使用 webpack 预处理器
  // 注释: webpackOptions 包含 @vue/cli-service/webpack.config 的配置选项
  // 注释: watchOptions 可以进行额外的监视选项设置
  // on('file:preprocessor', webpack({
  //   webpackOptions: require('@vue/cli-service/webpack.config'),
  //   watchOptions: {}
  // }))

  // 返回一个配置对象,将原始配置与新的配置项合并
  return Object.assign({}, config, {
    // 指定测试用例的 fixtures 文件夹路径
    fixturesFolder: 'tests/e2e/fixtures',
    // 指定截图保存的文件夹路径
    screenshotsFolder: 'tests/e2e/screenshots',
    // 指定录像保存的文件夹路径
    videosFolder: 'tests/e2e/videos',
    e2e: {
      // 指定测试用例的匹配模式,使用 glob 模式来匹配特定文件
      specPattern: 'tests/e2e/specs/**/*.cy.{js,jsx,ts,tsx}',
      // 指定支持文件的路径,例如定制的命令或断言
      supportFile: 'tests/e2e/support/index.js',
    },
  })
}

  1. 运行 Cypress

在项目根目录下,运行以下命令启动 Cypress:

npx cypress open

这会打开 Cypress 的测试运行界面,您可以选择执行测试用例。
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

  1. 编写测试用例

tests/e2e/specs 目录下,您可以创建测试用例文件。这些文件可以是 .spec.js.spec.ts 等文件,具体格式取决于您的项目配置。

以下是一个简单的测试用例示例:

// https://docs.cypress.io/api/table-of-contents

describe("My First Test", () => {
  it("Visits the app root url", () => {
    cy.visit("/");
    cy.contains("h1", "Welcome to Your Vue.js App");
  });
});

  1. 运行测试

在 Cypress 界面中,单击测试用例的文件名,它将在浏览器中运行测试。

  1. 自动化测试

您可以使用命令行在 CI/CD 流程中运行 Cypress 测试。例如,您可以在 package.json 中添加以下脚本:

{
  "scripts": {
    "test:e2e": "cypress run"
  }
}

然后,使用以下命令运行自动化测试:

npm run test:e2e

这就是集成 Cypress 并进行测试的基本步骤。根据您的项目需求,您还可以配置更多的选项,编写更多的测试用例,并使用 Cypress 的各种功能来提高测试覆盖率和质量。请参考 Cypress 官方文档 以获取更多详细信息和示例。

新增postcss.config.js

这里我只是使用了,Autoprefixer: 这是一个流行的 PostCSS 插件,用于自动添加浏览器前缀,以确保您的样式在不同浏览器中具有一致的效果。在配置中使用 “autoprefixer”: {} 来启用。

module.exports = {
  plugins: {
    autoprefixer: {},
  },
}

新增.travis.yml(构建的话,用Jenkins吧,这个玩意限制太多只提一下)

Travis CI 提供了一些免费的服务,但也有一些限制和付费选项。以下是关于 Travis CI 免费使用的一些信息:

  1. 免费服务:Travis CI 提供了免费的 CI/CD 服务,您可以在 GitHub 仓库上使用 Travis CI 进行构建和测试。

  2. 限制:免费服务有一些限制,例如,每月最多可以运行一定数量的构建,构建的时间可能有限制,以及并发构建的数量也可能受到限制。

  3. 付费选项:Travis CI 还提供了付费的服务套餐,称为 Travis CI Pro 和 Travis CI Team,这些付费选项可以提供更多的构建次数、并发构建和更长的构建时间等额外的功能和资源。

  4. 开源项目:Travis CI 为开源项目提供免费的构建和测试服务,只要您的项目是开源的并且托管在 GitHub 上,您就可以免费使用 Travis CI 进行构建和测试。

  5. 个人项目:对于私有项目,Travis CI 提供了一定的免费构建时间额度,但可能需要在超过免费额度后支付费用或考虑升级到付费套餐。

请注意,Travis CI 的政策和服务可能会随着时间的变化而发生变化,建议您在使用之前查看官方网站上的最新信息以获取准确的信息。如果您对 Travis CI 的具体定价、功能和服务有疑问,可以前往 Travis CI 官方网站或联系其支持团队获取更多信息。

language: node_js
node_js:
  - v18.17.1
cache: yarn
script:
  - yarn
  - yarn run lint --no-fix && yarn run build

新增LICENSE

在这里插入图片描述

MIT 许可证:

  • 非常宽松的许可证,允许修改和再分发代码,甚至可以闭源商用。
  • 要求包含版权和许可声明。
  • 适合那些希望代码被广泛使用和共享的开发者。
MIT License

Copyright (c) [2023] [yueerba]

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

启动项目

在这里插入图片描述

npm run dev

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/907701.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

记录node 版本对应的 node-sass 版本号

当我们在项目中使用 node-sass 时,电脑的 node版本号一定要与 node-sass 版本号对应,不对应时下载就会报错 一、官方文档地址 https://www.npmjs.com/package/node-sass 二、对应版本表格

一张图看懂 USDT三种类型地址 Omni、ERC20、TRC20的区别

USDT是当前实用最广泛,市值最高的稳定币,它是中心化的公司Tether发行的。在今年的4月17日之前,市场上存在着2种不同类型的USDT。4月17日又多了一种波场TRC20协议发行的USDT,它们各自有什么区别呢?哪个转账最快到账?哪…

Android kotlin 跳转手机热点开关页面和判断热点是否打开

Android kotlin 跳转手机热点开关页面和判断热点是否打开 判断热点是否打开跳转手机热点开关页面顺带介绍一些其他常用的设置页面跳转 其他热点的一些相关知识Local-only hotspot 参考 判断热点是否打开 网上方法比较多,我这边使用了通过WifiManager 拿反射的getWi…

【C#学习笔记】委托和事件

文章目录 委托委托的定义委托实例化委托的调用多播委托 为什么使用委托?官方委托泛型方法和泛型委托 事件为什么要有事件?事件和委托的区别: 题外话——委托与观察者模式 委托 在 .NET 中委托提供后期绑定机制。 后期绑定意味着调用方在你所…

问题解决:Failed to start sshd.service: Unit is masked.

centos7.6 ssh突然不能用了 也启动不了 错误如下: 解决方式: systemctl unmask sshd systemctl start sshd

day 34 | ● 62.不同路径 ● 63. 不同路径 II

62.不同路径 递归公式为上 左 func uniquePaths(m int, n int) int {dp : make([][]int, m)for i : 0; i < m; i{tmp : make([]int, n)dp[i] tmpdp[i][0] 1}for i : 0; i < n; i{dp[0][i] 1}for i : 1; i < m; i{for j : 1; j < n; j{dp[i][j] dp[i - 1][j] …

倒计时动效

1. 效果 2. html <div class"count"><span>3</span><span>2</span><span>1</span> </div>3. css body {width: 100vw;height: 100vh;overflow: hidden;display: flex;justify-content: center;align-items: cente…

数据存储效率对决:Redis String vs. Hash性能大比拼,哪个更适合你?

一、Redis的数据类型 1、常规类型 1&#xff09;String&#xff08;字符串&#xff09;&#xff1a;最基本的数据结构&#xff0c;可以存储任何类型的字符串、数字或二进制数据。 2&#xff09;Hash&#xff08;哈希表&#xff09;&#xff1a;类似于关联数组或字典&#xff…

售后服务管理软件怎么选择?售后服务管理系统有什么用?

随着企业信息化发展&#xff0c;越来越多的企业纷纷选择售后服务管理软件来服务客户和进行内部人员管理。借助这款软件&#xff0c;企业能够高效地满足客户提出的需求&#xff0c;并提高客户对售后服务的满意度。售后服务通常涉及客户、客服、维修师傅和服务管理人员等各种角色…

[JavaWeb]【八】web后端开发-Mybatis

目录 一 介绍 二 Mybatis的入门 2.1 快速入门 2.1.1 准备SpringBoot工程 2.1.2 创建数据库mybatis以及对应库表user 2.1.3 创建User实体类 2.1.4 配置application.properties数据库连接信息 2.1.5 编写sql语句&#xff08;注解方式&#xff09; 2.1.6 测试运行 2.1.7 配…

Unity封装Debug.Log导致代码定位失准的解决办法

笔者通过翻资料&#xff0c;实现了这样的一个编辑器&#xff0c;虽然无法彻底消除指定的日志信息 但是可以实现”双击日志不跳转到这里的任意一个文件“ using System.Collections.Generic; using System.IO; using UnityEditor; using UnityEngine;namespace AirEditor {publ…

浅谈java自定义中类两个对象的比较

目录 实现比较两个对象是否相同 1.前置代码 1.学生类 2.示例 3.输出 4.原因 2.那么我们要怎么做呢? 1.对Student类中重新实现quals方法(即对equals方法重写) 2.完整代码如下: 3.具体操作 4.演示 1.示例 2.输出 3.原因 实现比较两个对象的大小 第一种: 用…

智慧小区建设方案【47页PPT】

导读&#xff1a;原文《智慧小区建设方案【47页PPT】》&#xff08;获取来源见文尾&#xff09;&#xff0c;本文精选其中精华及架构部分&#xff0c;逻辑清晰、内容完整&#xff0c;为快速形成售前方案提供参考。 部分页面&#xff1a; 喜欢文章&#xff0c;您可以关注评论转…

实现图片的动态连续展示 JAVA

目录 1、前言&#xff1a;2、图片的展示以及自动关闭&#xff1a;3、动画的连续展示&#xff1a; 1、前言&#xff1a; 要实现动画的流畅展示需要在能展示图片的基础上对图片进行关闭&#xff0c;再切换下一张图片&#xff0c;这要关闭窗口&#xff0c;与延时函数以及while函数…

从SVG到Canvas:选择最适合你的Web图形技术

SVG 和 Canvas 都是可以在 Web 浏览器中绘制图形的技术。 众所周知&#xff0c; icon 通常使用 svg&#xff08;如 iconfont&#xff09;&#xff0c;而交互式游戏采用 Canvas。二者具体的区别是什么&#xff1f;该如何选择&#xff1f; 声明式还是命令式&#xff1f;绘制的图形…

C语言:库函数atoi及其模拟实现

i&#xff1a; atof是C语言标准库中的一个函数&#xff0c;用于将字符串转换为对应的浮点数/整形数。 函数接受一个参数str&#xff0c;该参数是一个指向以null结尾的字符串的指针。atof函数会尝试将这个字符串转换为一个浮点数&#xff0c;并返回转换后的结果。 要注意的是&a…

【3D激光SLAM】LOAM源代码解析--laserOdometry.cpp

系列文章目录 【3D激光SLAM】LOAM源代码解析–scanRegistration.cpp 【3D激光SLAM】LOAM源代码解析–laserOdometry.cpp 写在前面 本系列文章将对LOAM源代码进行讲解&#xff0c;在讲解过程中&#xff0c;涉及到论文中提到的部分&#xff0c;会结合论文以及我自己的理解进行解…

Numpy入门(4)— 保存和导入文件

NumPy保存和导入文件 4.1 文件读写 NumPy可以方便的进行文件读写&#xff0c;如下面这种格式的文本文件&#xff1a; # 使用np.fromfile从文本文件a.data读入数据 # 这里要设置参数sep &#xff0c;表示使用空白字符来分隔数据 # 空格或者回车都属于空白字符&#xff0c;读…

leetcode 542. 01 Matrix(01矩阵)

矩阵中只有0&#xff0c;1值&#xff0c;返回每个cell到最近的0的距离。 思路&#xff1a; 0元素到它自己的距离是0&#xff0c; 只需考虑1到最近的0是多少距离。 BFS. 先把元素1处的距离更新为无穷大。 0的位置装入queue。 从每个0出发&#xff0c;走上下左右4个方向&…

Redis的8种数据结构和应用场景介绍,面试题答案

面试原题&#xff1a;你用过Redis哪些数据结构&#xff1f;&#xff08;网易一面 2023&#xff09;(面试题来自牛客网) 参考答案 后面有 详细答案解析&#xff0c;帮助更快记忆~ 参考答案共652字符&#xff0c;阅读约需1分8秒&#xff1b;全文共8694字符&#xff0c;阅读约需…