如何使用配置?

Node

这个和传统Java, C#应用程序基本一致,

- config
  - default.yaml
  - development.yaml
  - production.yaml
  - test.yaml
- src
- test
- .env
- .env.production
- .env.test

index.js

require('dotenv').config(); // 这句后续应交由dotenv-cli来实现
const config = require('config');

config是用来做常规设置,而dotenv区别config主要有2个因素:

  1. dotenv写到process的环境变量,比如说NODE_ENV, DEBUG的这些和process.env强绑定的设置
  2. 用户名密码之类不对外公开的信息,如果放在config则一并上传到了git repo,如果是公开的repo则公开了用户名密码,所以一般.env是不用来上传的

注:

  • 整个加载过程是层叠覆盖式的,比如当NODE_ENV=production时,会先加载.env,然后再加载.env.production覆盖 (dotenv-cli -e则不会显式层叠加载)

对应的webpack.config.js

const path = require('path');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const TerserPlugin = require('terser-webpack-plugin');
const _externals = require('externals-dependencies');

module.exports = {
  mode: 'production',
  target: 'node',
  entry: './src/index.js',
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: [
          /test/,
          /node_modules/
        ],
        loader: 'babel-loader'
      }
    ]
  },
  node: {
    __filename: false,
    __dirname: false
  },
  output: {
    path: path.join(__dirname, 'build'),
    filename: 'bundle.js'
  },
  optimization: {
    minimizer: [new TerserPlugin()]
    // minimizer: []
  },
  plugins: [
        new CopyWebpackPlugin(['config', '.env*', 'package.json'])
  ],
  externals: _externals()
};

在运行build的时候还是需要先制定NODE_ENV

NODE_ENV=production node bundle.js

再来看dotenv-cli, 这样可以去掉require(‘dotenv’).config(),然后在运行时选择NODE_ENV,

.env

NODE_ENV=development
DEBUG=app*

.env.production

NODE_ENV=production

ok, 然后配置运行指令,

dotenv -e .env node app
dotenv -e .env.prodcution node app

这样就比较有一致性了。

最后补充一下pm2的情况,

dotenv -e .env.production pm2 reload ecosystem.config.js

最终可以整理如下:

"scripts": {
  "start": "node src/index",
  "start:prod": "cross-env NODE_ENV=production node src/index",
  "pm2": "dotenv -e .env.production pm2 reload ecosystem.config.js",
  "build": "webpack --mode production --progress --display-modules --colors --display-reasons"
},

参考:

React

React的配置比Node会受限一些,主要是因为它运行在浏览器中,刚刚的config都是运行时,但React的配置则基本是编译时,因为.env的内容直接hard code到最终编译的js, 所以和Node是不同的,遵循create-react-app的要求,可以采用.env和.env.production等支持多环境,在加载.env.production时会先加载.env。

如果需要运行时,就比如build以后需要做配置,则需要在HTML中引入js,

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>React App</title>

    <script type="text/javascript">
      window.RUNTIME = {
        SERVICE: "http://xyz.api"
      };
    </script>
  </head>
  <body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
  </body>
</html>

然后在页面获取,

function App() {
  return (
    <div className="App">
      {window.RUNTIM && window.RUNTIME.SERVICE &&
        <h1>{window.RUNTIME.SERVICE}</h1>
      }
      <h1>{process.env.REACT_APP_MESSAGE}</h1>
    </div>
  );
}

此外,yarn start时NODE_ENV=development, yarn build后则NODE_ENV=production

现在需求来了,

  • 在本地运行时,默认连接本地的服务,但可以手动设置采用其他服务地址
  • 编译后, 则默认使用云端地址, 可手动修改服务地址

config.js

import Debug from 'debug';

const debug = Debug('app:config');

class Config {
  constructor() {
    debug(`NODE_ENV: ${process.env.NODE_ENV}`);

    if (window.RUNTIME && window.RUNTIME.SERVICE) {
      this.service = window.RUNTIME.SERVICE;
    } else {
      if (process.env.REACT_APP_SERVICE) {
        this.service = process.env.REACT_APP_SERVICE;
      } else {
        throw new Error("Missing service configration");
      }
    }
  }

}

export default new Config();

在index.js中直接可以import './config', 然后在app.js就可以消费了,

function App() {
  return (
    <div className="App">
      <h1>{config.service}</h1>
    </div>
  );
}

最后补充一下env,

.env

REACT_APP_SERVICE=http://localhost:9007

.env

REACT_APP_SERVICE=https://api.space365.live

如果在HTML设置了service,则无视.env

<script type="text/javascript">
  window.RUNTIME = { SERVICE: "http://xyz.api" };
</script>

上述代码可以在这里获取。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值