Skip to content

Commit 53f4e19

Browse files
authored
update day 27 code snippets
1 parent 5cbe33b commit 53f4e19

File tree

1 file changed

+91
-64
lines changed

1 file changed

+91
-64
lines changed

day-27/post.md

Lines changed: 91 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -207,12 +207,12 @@ module.exports = {
207207
// ...
208208
plugins: [
209209
// ...
210-
// Makes some environment variables available to
211-
// the JS code, for example:
212-
// if (process.env.NODE_ENV === 'development') {
213-
// ...
214-
// }. See `env.js`
215-
new webpack.DefinePlugin(env),
210+
// Makes some environment variables available to the JS code, for example:
211+
// if (process.env.NODE_ENV === 'production') { ... }. See `./env.js`.
212+
// It is absolutely essential that NODE_ENV is set to production
213+
// during a production build.
214+
// Otherwise React will be compiled in the very slow development mode.
215+
new webpack.DefinePlugin(env.stringified),
216216
// ...
217217
]
218218
}
@@ -248,15 +248,41 @@ Looking at the `config/env.js` file, we can see that it takes all the variables
248248

249249
```javascript
250250
// ...
251-
module.exports = Object
252-
.keys(process.env)
253-
.filter(key => REACT_APP.test(key))
254-
.reduce((env, key) => {
255-
env['process.env.' + key] = JSON.stringify(process.env[key]);
256-
return env;
257-
}, {
258-
'process.env.NODE_ENV': NODE_ENV
259-
});
251+
// Grab NODE_ENV and REACT_APP_* environment variables and prepare them to be
252+
// injected into the application via DefinePlugin in Webpack configuration.
253+
const REACT_APP = /^REACT_APP_/i;
254+
// ...
255+
function getClientEnvironment(publicUrl) {
256+
const raw = Object.keys(process.env)
257+
.filter(key => REACT_APP.test(key))
258+
.reduce(
259+
(env, key) => {
260+
env[key] = process.env[key];
261+
return env;
262+
},
263+
{
264+
// Useful for determining whether we’re running in production mode.
265+
// Most importantly, it switches React into the correct mode.
266+
NODE_ENV: process.env.NODE_ENV || "development",
267+
// Useful for resolving the correct path to static assets in `public`.
268+
// For example, <img src={process.env.PUBLIC_URL + '/img/logo.png'} />.
269+
// This should only be used as an escape hatch. Normally you would put
270+
// images into the `src` and `import` them in code to get their paths.
271+
PUBLIC_URL: publicUrl,
272+
}
273+
);
274+
// Stringify all values so we can feed into Webpack DefinePlugin
275+
const stringified = {
276+
"process.env": Object.keys(raw).reduce((env, key) => {
277+
env[key] = JSON.stringify(raw[key]);
278+
return env;
279+
}, {})
280+
};
281+
282+
return { raw, stringified };
283+
}
284+
285+
module.exports = getClientEnvironment;
260286
```
261287

262288
We can skip all the complex part of that operation as we'll only need to modify the second argument to the reduce function, in other words, we'll update the object:
@@ -313,9 +339,14 @@ const envDotEnv = dotenv.config({
313339
Next, let's concatenate all these variables together as well as include our `NODE_ENV` option in this object. The `Object.assign()` method creates a _new_ object and merges each object from right to left. This way, the environment config variable
314340

315341
```javascript
316-
const allVars = Object.assign({}, {
317-
'NODE_ENV': NODE_ENV
318-
}, globalDotEnv, envDotEnv);
342+
const allVars = Object.assign(
343+
{},
344+
{
345+
NODE_ENV: NODE_ENV
346+
},
347+
globalDotEnv.parsed,
348+
envDotEnv.parsed
349+
);
319350
```
320351

321352
With our current setup, the `allVars` variable will look like:
@@ -327,39 +358,34 @@ With our current setup, the `allVars` variable will look like:
327358
}
328359
```
329360

330-
Finally, let's create an object that puts these variables on `process.env` and ensures they are valid strings (using `JSON.stringify`).
331-
332-
```javascript
333-
const initialVariableObject =
334-
Object.keys(allVars)
335-
.reduce((memo, key) => {
336-
memo['process.env.' + key.toUpperCase()] =
337-
JSON.stringify(allVars[key]);
338-
return memo;
339-
}, {});
340-
```
341-
342-
With our current setup (with the `.env` file in the root), this creates the `initialVariableObject` to be the following object:
361+
Now we can add this `allVars` as an argument to the reduce function initial value called in the `raw` variable in the `getClientEnvironment` function. Let's update it to use this object:
343362

344363
```javascript
345-
{
346-
'process.env.NODE_ENV': '"development"',
347-
'process.env.APP_NAME': '"30days"'
364+
function getClientEnvironment(publicUrl) {
365+
// ...
366+
const raw = Object.keys(process.env)
367+
.filter(key => REACT_APP.test(key))
368+
.reduce(
369+
(env, key) => {
370+
env[key] = process.env[key];
371+
return env;
372+
},
373+
{
374+
// Useful for determining whether we’re running in production mode.
375+
// Most importantly, it switches React into the correct mode.
376+
NODE_ENV: process.env.NODE_ENV || "development",
377+
// Useful for resolving the correct path to static assets in `public`.
378+
// For example, <img src={process.env.PUBLIC_URL + '/img/logo.png'} />.
379+
// This should only be used as an escape hatch. Normally you would put
380+
// images into the `src` and `import` them in code to get their paths.
381+
PUBLIC_URL: publicUrl,
382+
...allVars
383+
}
384+
);
385+
// ...
348386
}
349387
```
350388

351-
Now we can use this `initialVariableObject` as the second argument for the original `module.exports` like. Let's update it to use this object:
352-
353-
```javascript
354-
module.exports = Object
355-
.keys(process.env)
356-
.filter(key => REACT_APP.test(key))
357-
.reduce((env, key) => {
358-
env['process.env.' + key] = JSON.stringify(process.env[key]);
359-
return env;
360-
}, initialVariableObject);
361-
```
362-
363389
Now, anywhere in our code we can use the variables we set in our `.env` files.
364390

365391
Since we are making a request to an off-site server in our app, let's use our new configuration options to update this host.
@@ -381,25 +407,20 @@ TIME_SERVER='https://fullstacktime.herokuapp.com'
381407

382408
Now, when we run `npm start`, any occurrences of `process.env.TIME_SERVER` will be replaced by which ever value takes precedence.
383409

384-
Let's update our `src/redux/modules/currentTime.js` module to use the new server, rather than the hardcoded one we used previously.
410+
Let's update our `src/redux/actionCreators.js` module to use the new server, rather than the hardcoded one we used previously.
385411

386412
```javascript
387413
// ...
388-
export const reducer = (state = initialState, action) => {
389-
// ...
390-
}
391-
392414
const host = process.env.TIME_SERVER;
393-
export const actions = {
394-
updateTime: ({timezone = 'pst', str='now'}) => ({
395-
type: types.FETCH_NEW_TIME,
396-
meta: {
397-
type: 'api',
398-
url: host + '/' + timezone + '/' + str + '.json',
399-
method: 'GET'
400-
}
401-
})
402-
}
415+
export const fetchNewTime = (timezone = "pst", str = "now") => ({
416+
type: types.FETCH_NEW_TIME,
417+
payload: new Date().toString(),
418+
meta: {
419+
type: "api",
420+
url: host + "/" + timezone + "/" + str + ".json"
421+
}
422+
});
423+
403424
```
404425

405426
Now, for our production deployment, we'll use the heroku app, so let's create a copy of the `development.config.env` file as `production.config.env` in the `config/` directory:
@@ -419,18 +440,24 @@ let middleware = [
419440
loggingMiddleware,
420441
apiMiddleware
421442
];
422-
const store = createStore(reducer, applyMiddleware(...middleware));
443+
444+
export const configureStore = () => {
445+
// ...
446+
const store = createStore(rootReducer, initialState, applyMiddleware(...middleware));
447+
// ...
448+
}
449+
423450
```
424451

425452
Now that we have the `process.env.NODE_ENV` available to us in our files, we can update the `middleware` array depending upon the environment we're running in. Let's update it to only add the logging if we are in the development environment:
426453

427454
```javascript
455+
// ...
428456
let middleware = [apiMiddleware];
429457
if ("development" === process.env.NODE_ENV) {
430458
middleware.unshift(loggingMiddleware);
431459
}
432-
433-
const store = createStore(reducer, applyMiddleware(...middleware));
460+
// ...
434461
```
435462

436463
Now when we run our application in development, we'll have the `loggingMiddleware` set, while in any other environment we've disabled it.

0 commit comments

Comments
 (0)