问题
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