前言

前后端分离的项目中,前端会有很多环境:本地开发,测试环境,预发布环境,正式上线环境等等,我们的项目有多套基本相同的项目,处于多种环境,当每个环境都需要打包的时候,手动修改配置就很繁琐而且难免出错,比如每个环境对应的服务器地址不同,项目名称不同,专门定制的功能。


一、环境变量

制定环境变量:

  1. 在根目录添加.env文件,配置所有情况下都会用到的配置(不知道这个存在的意义,所有的都需要的也就不需要配置了吧)。
  2. 在根目录添加.env.local 文件,配置所有情况下都会用到的配置,与.env的区别是只会在本地,该文件不会被git跟踪。
  3. 在根目录添加.env.[mode] 文件,配置对应某个模式下的配置,比如:.env.development来配置开发环境的配置。
  4. 在根目录添加.env.[mode].local文件,配置对应某个模式下的配置,与.env.[mode]的区别也只是会在本地生效,该文件不会被git跟踪

Git忽略.env.[mode].local文件:
.gitignore文件里处理

二、.gitignore的用法

Git忽略文件.gitignore详解
在工程中,并不是所有文件都需要保存到版本库中的,例如“target”目录及目录下的文件就可以忽略。在Git工作区的根目录下创建一个特殊的.gitignore文件,然后把要忽略的文件名填进去,Git就会自动忽略这些文件或目录。
在这里插入图片描述

# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js

# /public

# testing
/coverage

# production
/build

# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
.env.sz.local
.env.zj.local

npm-debug.log*
yarn-debug.log*
yarn-error.log*

/build.rar

三、使用步骤

1.在项目中安装 dotenvdotenvdotenv-expand

代码如下(示例):

dotenv、dotenv-expand详情

npm install dotenv
npm install dotenv-expand

1.dotenv

在这里插入图片描述
在这里插入图片描述
基本常用的方法场景就这些了,更完整的用法可以直接查阅文档
dotenv

2.dotenv-expand

在这里插入图片描述
在这里插入图片描述
基本常用的方法场景就这些了,更完整的用法可以直接查阅文档
dotenv-expand
使用 dotenv 、dotenv-expand可以让我们免于在各个文件中引入配置文件,也可以很好的解决敏感信息的泄漏,利于后期代码维护

2.根目录下创建 .env 文件

HOST=localhost
//本地运行端口
PORT=3008

在这里插入图片描述

根目录下 env.js 下引入 dotenv 并使用(简单示例):
在这里插入图片描述

require('dotenv').config({ path: '.env' })

// 使用
console.log(process.env.HOST) // localhost
console.log(process.env.PORT) // 3000

3.根目录下多环境 .env.xxx 文件

在根目录下创建.env.xxx文件,例如.env.development,.env.test,env.sz(sz是我的项目标识)等等
在这里插入图片描述
在这里插入图片描述
请注意,只有 NODE_ENV,BASE_URL 和以REACT_APP_开头的变量将通过 webpack.DefinePlugin 静态地嵌入到客户端侧的代码中。这是为了避免意外公开机器上可能具有相同名称的私钥。
如果需要自定义:
在·config·文件目录下 的env.js文件更改(建议统一使用):

// Grab NODE_ENV and REACT_APP_* environment variables and prepare them to be
// injected into the application via DefinePlugin in Webpack configuration.
const REACT_APP = /^REACT_APP_/i;

在这里插入图片描述
.env.sz代码:

PORT=3008
//不加`REACT_APP_`无效
Version_Code=ShenZhenYouLian //无效
//项目标识
REACT_APP_Titlee=xxxx项目管理系统

REACT_APP_Version_Code=ShenZhenYouLian
//接口地址
REACT_APP_MOCK_API='http://172.17.17.17:8080/api'  
//等等

注意:
如果使用React/TypeScript要在react-app-env.d.ts类型声明文件,声明上述(REACT_APP_Version_Code)类型
在这里插入图片描述
当项目编译时将会根据tsconfig.json中include指定的目录去找代码所需要的类型声明文件,而react-app-env.d.ts会告诉编译器含有哪些类型声明,里面含有一些常用的类型声明,比如react、react-dom的一些API类型声明,图片、样式模块类型声明等等。
react-app-env.d.ts的作用以及如何生成的(删除后再次生成)?

package.json配置打包命令:
在这里插入图片描述
config/paths.js文件配置:
在这里插入图片描述config/env.js文件配置:
config/env.js文件配置:
process.argv简单了解一下
在这里插入图片描述

//nodejs模块——fs模块:fs模块用于对系统文件及目录进行读写操作
const fs = require('fs');
//path模块是nodejs官方提供的、用来处理路径的模块。它提供了一系列的方法和属性,用来满足用户对路径的处理需求
const path = require('path');
 //上述配置config/paths.js
const paths = require('./paths');

//获取命令行参数,例如打包时(npm run build:sz)获取:sz
//npm run build:sz在--package.json配置:"scripts": { "build:sz": "node scripts/build.js version=sz"}等等相同
function findVERSION() {
  try {
 // process 对象是一个全局变量,它提供当前 Node.js 进程的有关信息,以及控制当前 Node.js 进程。
 // 因为是全局变量,所以无需使用 require()。
 //process.argv 属性返回一个数组,这个数组包含了启动Node.js进程时的命令行参数
 //其中:
 //数组的第一个元素process.argv[0]——返回启动Node.js进程的可执行文件所在的绝对路径
 //第二个元素process.argv[1]——为当前执行的JavaScript文件路径
 //剩余的元素为其他命令行参数

    const list = process.argv.slice(2); //log:version=sz
    for (let index = 0; index < list.length; index++) {
      const str = list[index].split("=");
      if (str.length === 2 && str[0] === "version") {
        return str[1];
      }
    }
  } catch (e) {
    return false;
  }
}
const VERSION = findVERSION();
// 命令控制面板上去进行单文件调试
// 比如: node config/evn.js version=sz
console.log('调试',VERSION);

// https://github.com/bkeepers/dotenv#what-other-env-files-can-i-use
//判断
const dotenvFiles = [
  VERSION && `${paths.dotenv}.${VERSION}.local`,//env.sz.local
  VERSION && `${paths.dotenv}.${VERSION}`,
  `${paths.dotenv}.${NODE_ENV}.local`,
  `${paths.dotenv}.${NODE_ENV}`,
  // Don't include `.env.local` for `test` environment
  // since normally you expect tests to produce the same
  // results for everyone
  NODE_ENV !== 'test' && `${paths.dotenv}.local`,
  paths.dotenv,
].filter(Boolean);

dotenvFiles.forEach(dotenvFile => {
  //fs.existsSync- Check whether the directory exists synchronously.
  if (fs.existsSync(dotenvFile)) {
    require('dotenv-expand')(
      // 包含环境变量的文件位于其他位置,则可以指定自定义路径require('dotenv').config({ path: dotenvFile })
      require('dotenv').config({
        path: dotenvFile,
      })
    );
  }
});

如何对上述配置文件方法进行调试(只能命令行调试–只有执行命令时脚本(env.js或start.js、build.js)才执行):
如果保存查看报错原因:或在config/start.js内打断点或return---命令(node scripts/start.js version=zj)
在这里插入图片描述

执行命令(可多命令打包-需要配置):

//打包build
npm run build:sz
//运行项目start
cnpm run start:sz


总结

这样就可以执行不同版本项目,例如:
配置接口基地址:

export const MOCK_API = process.env.REACT_APP_MOCK_API ;

或进行逻辑判断:

if(process.env.REACT_APP_Version_Code === 'ShenZhenYouLian'){
...
}else if(process.env.REACT_APP_Version_Code === 'xxx'){
...
}else{
...
}
等等
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐