Closed joshhornby closed 7 years ago
Have you tried it? I’m not entirely sure if it works because it’s not clear what you tried, and what problems you have encountered.
I would just note that dynamic expressions in require
cause all files to be included in your bundle. This means you'll likely ship your development config to production. I would suggest to explicitly compare NODE_ENV
and doing static require()
s in conditional branches instead.
I have a similar need : static configuration folder with nested key => values.
I'm currently using nwb, with webpack + node-config-loader. It works great, and support a lot of file and formats.
I configured a "config" alias to the .configloaderrc file at the root of the project, which is handled by the loader. I can write something like :
import config from 'config';
console.log(config.api.baseUrl);
@gaearon Is there a way to solve this with CRA out of the box? Do you think of another solution?
For anyone finding this issue, a working solution has been to have a config
folder at the project root, inside I have production.js
and development.js
, each file looks something like:
module.exports = { key: 'value' }
I then have a index.js
:
const merge = require('lodash/merge');
const global = require('./global');
var env; // let doesn't seem to work here
if (process.env.NODE_ENV === 'development') {
env = require('./development');
} else {
env = require('./production');
}
module.exports = merge(global, env);
And then in code I have just import
this file and get the values eg config.key
This is how I handle configuration in my own project-I'd like to do something similar with create-react-app
This is how my index.js
looks
fetch('env.json')
.then(res => res.json())
.then(env => render(<app env={env}/>)
In the production file build I want the code to fetch an env.json
in the root directory-this file isn't emitted by the build, it's just expected to exist and I update it by hand depending on the environment
I want the dev server to serve up the process.env object in response to app.get('/env.json')
so that I can configure my local environment to run against different servers by setting environment variables
webpack-dev-server
can be configured to do this with the devServer.setup
option:
setup(app) {
app.get('/env.json', (req, res) => {
res.json(process.env);
});
}
EDIT: I'm fine with following the strategy posted above, but it requires that I commit environment configuration files and build for particular environments
@moodysalem This is not a very good way because the user has to wait a whole extra request before the app starts.
The approach suggested by @joshhornby sounds like the best solution to me.
@gaearon I agree it's not ideal to wait for the extra request, but I add headers to let the file be cached by the client for a day so it only happens on the first request of the day.
I don't know another way to get around creating N builds for N environments on the front end though-we have dev/staging/prd which point to different APIs and sometimes we create additional temporary environments which is easier if I don't have to commit the configuration
@moodysalem You can use environment variables for this (and indeed create separate builds for each environment).
@gaearon Would the impact of an additional request right at the beginning of the entry JS be reduced by http2? If not when initiated via fetch
, you could put a <script src="env.js" ...></script>
tag in the body and store config in window.env
The practice of separating your build from your environment config has a couple of upsides:
With the downside that if you are caching the environment config file, it would take time for your changes to propagate to the users
Yea, maybe there are ways to make it work. Just saying in most cases it’s suboptimal in my opinion.
@gaearon With the 1.0 updates the method listed above (https://github.com/facebookincubator/create-react-app/issues/1469#issuecomment-290081143) breaks due to the config file being outside src
.
What do you suggest now? I don't think pulling the config
folder into src
makes sense, so would be interested to hear how you'd solve this issue.
After searching through the issues I can't seem to find anyone asking this, but if I have missed it please link me to it.
I know CRA has the concept of env variables but I am looking for a little more than this (I want to include objects and arrays). I want to have a
config
directory in the root of my project, and inside anindex.js
something like:This will give me a config file for each environment but also a
local.js
where I can override anything I need, for example during development I want to change anAPI_URL
to a local branch.My question is using CRA can I get webpack to recognize this file outside of the
src
directory? I don't want to have to eject just to add some static config files.