多环境变量是在项目开发·打包·生产时产生的概念,所谓的多环境变量指的就是一个项目适配多种环境。
配置不同环境变量可避免切换不同环境时手动修改项目配置,请求url等
在package.json
文件中这样设置:
"scripts": {
"serve": "vue-cli-service serve", //开发环境
"serve:test": "vue-cli-service serve --mode test", //测试环境
"build:test": "vue-cli-service build --mode test",
"build:production": "vue-cli-service build --mode production", //生产环境
},
注意:.env文件是环境配置,不允许胡乱命名
# 开发环境
NODE_ENV=development
VUE_APP_ENV=development
# 开发环境,接口地址
VUE_APP_BASE_URL =
# 生产环境
ODE_ENV=production
VUE_APP_ENV=production
# 生产环境,接口地址
VUE_APP_BASE_URL =
# 测试环境
NODE_ENV =test
VUE_APP_ENV =test
# 测试环境,接口地址
VUE_APP_BASE_URL =
.env
文件中的默认属性有 NODE_ENV
和 BASE_URL
VUE_APP_
开头,如:VUE_APP_XXX
process.env
在任何地方访问到当前环境配置属性// process.env 会根据当前的环境,加载对应的环境变量文件中的变量
console.log(process.env.VUE_APP_BASE_URL)
axios.defaults.baseURL = process.env.VUE_APP_BASE_URL
作用:
因为浏览器的兼容问题,不同浏览器对有些标签的默认值是不同的,如果没对CSS初始化往往会出现浏览器之间的页面显示差异。
安装
yarn add normalize.css
使用
main.js 导入 normalize.css
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
+ import 'normalize.css' //直接导入
createApp(App).use(store).use(router).mount('#app')
推荐直接下载 normalize.css,然后在main.js引入
添加依赖
yarn add element-ui
在项目中改变 SCSS 变量
Element 的 theme-chalk 使用 SCSS 编写,如果你的项目也使用了 SCSS,那么可以直接在项目中改变 Element 的样式变量。新建一个样式文件,例如 element-variables.scss
,写入以下内容:
/* 改变主题色变量 */
$--color-primary: teal;
/* 改变 icon 字体路径变量,必需 */
$--font-path: '~element-ui/lib/theme-chalk/fonts';
@import "~element-ui/packages/theme-chalk/src/index";
之后,在项目的入口文件中,直接引入以上样式文件即可(无需引入 Element 编译好的 CSS 文件):
// main.ts
import Vue from 'vue'
import Element from 'element-ui'
import './element-variables.scss'
Vue.use(Element)
注意
如果运行报如下错误
解决办法 sass 版本修改为 1.32.13, 执行下面命令
yarn add [email protected]
在 src/assets/scss
下新建变量配置文件:mixin.scss
// 全局scss变量
$theme-color: #317FEA;
$activeColor: #147af7;
// 暴露为js变量
:export {
themeColor: $theme-color;
}
vue.config.js文件配置(重新启动项目)
module.exports = {
outputDir: 'dist',
publicPath: '/',
// 配置scss文件全局变量
css: {
loaderOptions: {
// 没有分号会报错
sass: {
// data: '@import "@/assets/css/vars.scss";' //旧版sass-loader写法(8.0以下)
prependData: `@import "@/assets/scss/minix.scss";` //新版scss-loader(8.0及以上)
}
}
},
}
其他组件中直接使用
&:hover {
color: #fff;
background: $activeColor;
}
相关配置说明
// 这里的webpack配置会和公共的webpack.config.js进行合并
module.exports = {
// 执行 npm run build 统一配置文件路径(本地访问dist/index.html需'./')
// NODE_ENV:Node.js 暴露给执行脚本的系统环境变量。通常用于确定在开发环境还是生产环境
// publicPath: '/',
publicPath: process.env.NODE_ENV === 'production' ? '' : '/',
outputDir: 'dist', // 输出文件目录
// assetsDir: 'static', // 放置静态资源
// indexPath: 'index.html', // 可以不设置一般会默认
// filenameHashing:true, // 文件命名
lintOnSave: false, //设置是否在开发环境下每次保存代码时都启用 eslint验证
// runtimeCompiler: false, // 是否使用带有浏览器内编译器的完整构建版本
configureWebpack: { // 别名配置
resolve: {
alias: {
//'src': '@', 默认已配置
'assets': '@/assets',
'common': '@/common',
'components': '@/components',
'api': '@/api',
'views': '@/views',
'plugins': '@/plugins',
'utils': '@/utils',
}
}
// 使用前面可加~
},
productionSourceMap: false, //如果你不需要生产环境的 source map,可以将其设置为 false 以加速生产环境构建
css: { // css相关配置
// 是否将组件中的 CSS 提取至一个独立的 CSS 文件中,生产环境下是 true,开发环境下是 false
extract: process.env.NODE_ENV === "production",
// 是否为 CSS 开启 source map。设置为 true 之后可能会影响构建的性能。
sourceMap: false,
// 启用 CSS modules for all css / pre-processor files.(预加载)
requireModuleExtension: true,
loaderOptions: {
scss: {
// data: '@import "@/assets/css/vars.scss";' //旧版sass-loader写法(8.0以下)
prependData: `@import "@/assets/scss/minix.scss";` //新版scss-loader(8.0及以上)
}
}
},
devServer: {
port: 2021, // 设置端口号
host: '10.32.120.69', // ip
disableHostCheck: true, //是否关闭用于 DNS 重绑定的 HTTP 请求的 HOST 检查
hotOnly: false, // 热更新
https: false, // https:{type:Boolean}配置前缀
open: false, //配置自动启动浏览器
proxy: null, //设置代理
// proxy: { //目的是解决跨域,若测试环境不需要跨域,则不需要进行该配置
// '/api': { // 拦截以 /api 开头的url接口
// target: 'https://api.taobao.cn/', //目标接口域名
// changeOrigin: true, //是否跨域
// ws: true, //如果要代理 websockets,配置这个参数
// secure: false, // 如果是https接口,需要配置这个参数
// // 标识替换
// // 原请求地址为 /api/getData 将'/api'替换''时,
// // 代理后的请求地址为: http://xxx.xxx.xxx/getData
// // 若替换为'/other',则代理后的请求地址为 http://xxx.xxx.xxx/other/getData
// pathRewrite: { // 标识替换
// '^/api': '/' //重写接口 后台接口指向不统一 所以指向所有/
// '^/api': '/api/mock'
// }
// }
// }
},
// 这个插件中添加的service worker只在生产环境中启用(例如,只有当你运行npm run build或yarn build时)。
// 不推荐在开发模式中启用service worker,因为它会导致使用以前缓存的资产而不包括最新的本地更改的情况。
pwa: {
// serviceWorker:false,
// 允许您从一个现有的service worker文件开始,并创建一个该文件的副本,并将“预缓存清单”注入其中。
// workboxPluginMode:'InjectManifest',
// workboxOptions: {
// //swSrc: './app/sw.js', /* Empty file. */
// },
iconPaths: {
favicon32: "favicon.ico",
favicon16: "favicon.ico",
appleTouchIcon: "favicon.ico",
maskIcon: "favicon.ico",
msTileImage: "favicon.ico"
}
}
}
ESLint: Missing return type on function.(@typescript-eslint/explicit-module-boundary-types)
解决方法:
在.eslintrc.js文件里添加规则禁用它
"rules": {
"@typescript-eslint/explicit-module-boundary-types": "off"
},
ESLint: Type string trivially inferred from a string literal, remove type annotation.(@typescript-eslint/no-inferrable-types)
报错原因:
TypeScript代码类似:
const web: string = "Hello World";
从字符串文字中简单推断出字符串类型,删除类型注释。eslint @ typescript-eslint / no-inferrable-types
他觉得已经推断出是字符串类型,不需要写了
解决方法:
在.eslintrc.js文件里添加规则禁用它
rules: {
"@typescript-eslint/no-inferrable-types": "off" // 关闭类型推断
}
ESLint: Require statement not part of import statement. eslint@typescript-eslint/no-var-requires
解决方法:
"rules": {
'@typescript-eslint/no-var-requires': 'off'
},
warning Unexpected any. Specify a different type @typescript-eslint/no-explicit-any
解决方案:
关闭any类型的警告。
"rules": {
'@typescript-eslint/no-explicit-any': 'off'
},
ESLint: Forbidden non-null assertion.(@typescript-eslint/no-non-null-assertion)
解决方案:
"rules": {
@typescript-eslint/no-non-null-assertion': 'off'
},
SLint: ‘xxx’ is not defined.(no-undef) //说明全局变量未定义
解决方案:
"rules": {
...
},
"globals":{
"xxx": true//xxx 为你的全局变量
}
我项目的配置如下:
module.exports = {
root: true,
env: {
node: true
},
extends: [
'plugin:vue/essential',
'@vue/standard',
'@vue/typescript/recommended'
],
parserOptions: {
ecmaVersion: 2020
},
rules: {
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
'space-before-function-paren': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/explicit-module-boundary-types': 'off',
'@typescript-eslint/ban-ts-comment': 'off',
'@typescript-eslint/no-var-requires': 'off'
}
}
项目根目录下生成一个tsconfig.json文件,下面是一份tsconfig.json的说明:
{
"compilerOptions": {
/* 基本选项 */
"target": "es6", // 指定 ECMAScript 目标版本: 'ES3' (default), 'ES5', 'ES6'/'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'
"module": "commonjs", // 指定使用模块: 'commonjs', 'amd', 'system', 'umd' or 'es2015'
"lib": [], // 指定要包含在编译中的库文件
"allowJs": true, // 允许编译 javascript 文件
"checkJs": true, // 报告 javascript 文件中的错误
"jsx": "preserve", // 指定 jsx 代码的生成: 'preserve', 'react-native', or 'react'
"declaration": true, // 生成相应的 '.d.ts' 文件
"sourceMap": true, // 生成相应的 '.map' 文件
"outFile": "./", // 将输出文件合并为一个文件
"outDir": "./", // 指定输出目录
"rootDir": "./", // 用来控制输出目录结构 --outDir.
"removeComments": true, // 删除编译后的所有的注释
"noEmit": true, // 不生成输出文件
"importHelpers": true, // 从 tslib 导入辅助工具函数
"isolatedModules": true, // 将每个文件做为单独的模块 (与 'ts.transpileModule' 类似).
/* 严格的类型检查选项 */
"strict": true, // 启用所有严格类型检查选项
"noImplicitAny": true, // 在表达式和声明上有隐含的 any类型时报错
"strictNullChecks": true, // 启用严格的 null 检查
"noImplicitThis": true, // 当 this 表达式值为 any 类型的时候,生成一个错误
"alwaysStrict": true, // 以严格模式检查每个模块,并在每个文件里加入 'use strict'
/* 额外的检查 */
"noUnusedLocals": true, // 有未使用的变量时,抛出错误
"noUnusedParameters": true, // 有未使用的参数时,抛出错误
"noImplicitReturns": true, // 并不是所有函数里的代码都有返回值时,抛出错误
"noFallthroughCasesInSwitch": true, // 报告 switch 语句的 fallthrough 错误。(即,不允许 switch 的 case 语句贯穿)
/* 模块解析选项 */
"moduleResolution": "node", // 选择模块解析策略: 'node' (Node.js) or 'classic' (TypeScript pre-1.6)
"baseUrl": "./", // 用于解析非相对模块名称的基目录
"paths": {}, // 模块名到基于 baseUrl 的路径映射的列表
"rootDirs": [], // 根文件夹列表,其组合内容表示项目运行时的结构内容
"typeRoots": [], // 包含类型声明的文件列表
"types": [], // 需要包含的类型声明文件名列表
"allowSyntheticDefaultImports": true, // 允许从没有设置默认导出的模块中默认导入。
/* Source Map Options */
"sourceRoot": "./", // 指定调试器应该找到 TypeScript 文件而不是源文件的位置
"mapRoot": "./", // 指定调试器应该找到映射文件而不是生成文件的位置
"inlineSourceMap": true, // 生成单个 soucemaps 文件,而不是将 sourcemaps 生成不同的文件
"inlineSources": true, // 将代码与 sourcemaps 生成到一个文件中,要求同时设置了 --inlineSourceMap 或 --sourceMap 属性
/* 其他选项 */
"experimentalDecorators": true, // 启用装饰器
"emitDecoratorMetadata": true // 为装饰器提供元数据的支持
}
}