How to inject dotenv variables without REACT_APP prefix in create-react-app?

不羁岁月 提交于 2021-01-27 06:10:57

问题


I have a project to migrate from legacy React app to standard create-react-app one (not ejected).

In legacy project, it manually loads .env files with dotenv and dotenv-expand and injects through webpack DefinePlugin.

create-react-app intuitively supports dotenv but can only recognize variables with REACT_APP_ prefix.

There are so many places in legacy code also along with imported packages in other repositories that are using process.env.xxx variables, so it is impossible for now to rename them with prefix before migration.

In this case, how can I make create-react-app recognize dotenv variables without REACT_APP_ prefix?

BTW, I tried to rewire build script before with some simple customizations over webpack, like bundling js and css:

const path = require('path');
const rewire = require('rewire');
const defaults = rewire('react-scripts/scripts/build.js');

let webpackConfig = defaults.__get__('config');

webpackConfig.output.filename = 'static/js/[name].js';
webpackConfig.optimization.splitChunks = { cacheGroups: { default: false } };
webpackConfig.optimization.runtimeChunk = false;
webpackConfig.plugins.find(plugin => plugin.__proto__.constructor.name === 'MiniCssExtractPlugin').options.filename = 'static/css/[name].css';
webpackConfig.plugins.find(plugin => plugin.__proto__.constructor.name === 'MiniCssExtractPlugin').options.moduleFilename = () => 'static/css/[name].css';

But it seems dotenv and DefinePlugin are more complicated. Not sure if it can be achieved in the same way.


回答1:


Also use rewire

// "start": "node start.js"
const rewire = require('rewire');

process.env.NODE_ENV = 'development';

let getClientEnvironment = rewire('react-scripts/config/env.js');
getClientEnvironment.__set__(
  'REACT_APP',
  /(^REACT_APP_|API|DEPLOY|SECRET|TOKEN|URL)/,
);

let configFactory = rewire('react-scripts/config/webpack.config.js');
configFactory.__set__('getClientEnvironment', getClientEnvironment);

let start = rewire('react-scripts/scripts/start.js');
start.__set__('configFactory', configFactory);

build is a little bit different

// "build": "node build.js"
const rewire = require('rewire');

process.env.NODE_ENV = 'production';

let getClientEnvironment = rewire('react-scripts/config/env.js');
getClientEnvironment.__set__(
  'REACT_APP',
  /(^REACT_APP_|API|DEPLOY|SECRET|TOKEN|URL)/,
);

let configFactory = rewire('react-scripts/config/webpack.config.js');
configFactory.__set__('getClientEnvironment', getClientEnvironment);

let webpackConfig = configFactory('production');

let build = rewire('react-scripts/scripts/build.js');
build.__set__('config', webpackConfig);



回答2:


Years ago Dan Abramov (co-creator of CRA) suggested to redefine the variables to fit REACT_APP_ in an entrypoint script that then calls react-scripts in package.json.

If you have simpler needs to support these variables, such as CI platform variables like Netlify's COMMIT_REF or Gitlab's CI_COMMIT_SHA, you could set those variables inline without adding another script.

  "scripts": {
    "start": "react-scripts start",
    "build": "REACT_APP_COMMIT_SHA=$COMMIT_REF$CI_COMMIT_SHA react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },

This will set REACT_APP_COMMIT_SHA to the value of the hash of whichever service it's built in (since the other variable will be empty).



来源:https://stackoverflow.com/questions/61395056/how-to-inject-dotenv-variables-without-react-app-prefix-in-create-react-app

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!