Skip to content

Commit 1181ff3

Browse files
committed
Refactoring + fixes
1 parent 736f2ce commit 1181ff3

File tree

25 files changed

+244
-101
lines changed

25 files changed

+244
-101
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# Topcoder React Utils Changelog
22

3+
### v0.3.0
4+
- Added the standard, configurable server setup;
5+
- Jest utils are now exposed in a different way;
6+
- Config / isomorphy / webpack utils added;
7+
- Updated dependencies.
8+
39
### v0.2.0
410
- Webpack configs for apps updated to emulate `process.env.BABEL_ENV` instead of
511
`process.env.NODE_ENV`. The original intent behind emulation of that constant

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ only need to call `adopt-dev-deps` again if you update
7676
with standard configuration, that serves a ReactJS application with or without
7777
server-side rendering, supports development tools (Hop Module Reloading), and
7878
can be further configured for the needs of specific projects.
79+
- [**Webpack**](docs/webpack-utils.md) — Various utils related to the
80+
Webpack bundling process.
7981

8082
### <a name="development">Development</a>
8183
For convenient development you can link this package into your host package:

__tests__/.babelrc

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"presets": [
3+
"../config/babel/node-ssr"
4+
],
5+
"plugins": [
6+
["module-resolver", {
7+
"alias": {
8+
"topcoder-react-utils/dist": "./src"
9+
}
10+
}]
11+
]
12+
}

__tests__/__snapshots__/index.js.snap

Lines changed: 97 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,106 @@ exports[`Exports expected stuff 1`] = `
44
Object {
55
"Avatar": [Function],
66
"Button": [Function],
7+
"JU": Object {
8+
"findInDomByClass": [Function],
9+
"render": [Function],
10+
"renderDom": [Function],
11+
"shallowRender": [Function],
12+
"shallowSnapshot": [Function],
13+
"simulate": Object {
14+
"abort": [Function],
15+
"animationEnd": [Function],
16+
"animationIteration": [Function],
17+
"animationStart": [Function],
18+
"beforeInput": [Function],
19+
"blur": [Function],
20+
"canPlay": [Function],
21+
"canPlayThrough": [Function],
22+
"cancel": [Function],
23+
"change": [Function],
24+
"click": [Function],
25+
"close": [Function],
26+
"compositionEnd": [Function],
27+
"compositionStart": [Function],
28+
"compositionUpdate": [Function],
29+
"contextMenu": [Function],
30+
"copy": [Function],
31+
"cut": [Function],
32+
"doubleClick": [Function],
33+
"drag": [Function],
34+
"dragEnd": [Function],
35+
"dragEnter": [Function],
36+
"dragExit": [Function],
37+
"dragLeave": [Function],
38+
"dragOver": [Function],
39+
"dragStart": [Function],
40+
"drop": [Function],
41+
"durationChange": [Function],
42+
"emptied": [Function],
43+
"encrypted": [Function],
44+
"ended": [Function],
45+
"error": [Function],
46+
"focus": [Function],
47+
"input": [Function],
48+
"invalid": [Function],
49+
"keyDown": [Function],
50+
"keyPress": [Function],
51+
"keyUp": [Function],
52+
"load": [Function],
53+
"loadStart": [Function],
54+
"loadedData": [Function],
55+
"loadedMetadata": [Function],
56+
"mouseDown": [Function],
57+
"mouseEnter": [Function],
58+
"mouseLeave": [Function],
59+
"mouseMove": [Function],
60+
"mouseOut": [Function],
61+
"mouseOver": [Function],
62+
"mouseUp": [Function],
63+
"paste": [Function],
64+
"pause": [Function],
65+
"play": [Function],
66+
"playing": [Function],
67+
"progress": [Function],
68+
"rateChange": [Function],
69+
"reset": [Function],
70+
"scroll": [Function],
71+
"seeked": [Function],
72+
"seeking": [Function],
73+
"select": [Function],
74+
"stalled": [Function],
75+
"submit": [Function],
76+
"suspend": [Function],
77+
"timeUpdate": [Function],
78+
"toggle": [Function],
79+
"touchCancel": [Function],
80+
"touchEnd": [Function],
81+
"touchMove": [Function],
82+
"touchStart": [Function],
83+
"transitionEnd": [Function],
84+
"volumeChange": [Function],
85+
"waiting": [Function],
86+
"wheel": [Function],
87+
},
88+
"snapshot": [Function],
89+
},
790
"Link": [Function],
891
"NavLink": [Function],
992
"ScalableRect": [Function],
10-
"utils": Object {
11-
"config": Config {},
12-
"isomorphy": Object {
13-
"buildTimestamp": [Function],
14-
"isClientSide": [Function],
15-
"isDevBuild": [Function],
16-
"isProdBuild": [Function],
17-
"isServerSide": [Function],
18-
},
93+
"config": Config {
94+
"dummyConfigKey": "Dummy config value",
95+
},
96+
"isomorphy": Object {
97+
"buildTimestamp": [Function],
98+
"isClientSide": [Function],
99+
"isDevBuild": [Function],
100+
"isProdBuild": [Function],
101+
"isServerSide": [Function],
102+
},
103+
"server": [Function],
104+
"webpack": Object {
105+
"default": undefined,
106+
"requireWeak": [Function],
19107
},
20108
}
21109
`;

__tests__/index.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
import * as exports from '../src';
1+
jest.mock('utils/isomorphy');
2+
3+
const exports = require('../src');
24

35
test('Exports expected stuff', () => {
46
expect(exports).toMatchSnapshot();

__tests__/shared/utils/config.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,10 @@ beforeEach(() => {
1818
window.CONFIG = _.clone(CLIENT_SIDE_CONFIG);
1919
});
2020

21-
afterEach(() => delete global.FRONT_END);
21+
afterEach(() => delete window.TRU_FRONT_END);
2222

2323
test('Serves injected config at the client side', () => {
24-
global.FRONT_END = true;
24+
window.TRU_FRONT_END = true;
2525
expect(isClientSide()).toBe(true);
2626
expect(require('utils/config')).toEqual(CLIENT_SIDE_CONFIG);
2727
});

__tests__/shared/utils/isomorphy.js

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,65 @@
11
/* Helper for loading of tested module. */
2+
3+
/* global window */
4+
25
const m = () => require('utils/isomorphy');
36

47
afterEach(() => {
5-
delete global.BUILD_INFO;
6-
delete global.BUILD_TIMESTAMP;
7-
delete global.FRONT_END;
8+
delete global.TRU_BUILD_INFO;
9+
delete window.TRU_BUILD_INFO;
10+
delete window.TRU_FRONT_END;
811
delete process.env.BABEL_ENV;
9-
process.env.NODE_ENV = 'test';
1012
});
1113

1214
beforeEach(() => jest.resetModules());
1315

1416
test('Client-side detection', () => {
15-
global.FRONT_END = 'true';
17+
window.TRU_FRONT_END = true;
1618
expect(m().isClientSide()).toBe(true);
1719
expect(m().isServerSide()).toBe(false);
1820
});
1921

2022
test('Server-side detection', () => {
21-
expect(global.FRONT_END).toBeUndefined();
2223
expect(m().isClientSide()).toBe(false);
2324
expect(m().isServerSide()).toBe(true);
2425
});
2526

26-
test('Dev code build detection', () => {
27+
test('Dev mode detection - client side', () => {
28+
window.TRU_BUILD_INFO = { mode: 'development' };
29+
window.TRU_FRONT_END = true;
30+
expect(m().isDevBuild()).toBe(true);
31+
expect(m().isProdBuild()).toBe(false);
32+
});
33+
34+
test('Dev mode detection - server side', () => {
2735
process.env.BABEL_ENV = 'development';
2836
expect(m().isDevBuild()).toBe(true);
2937
expect(m().isProdBuild()).toBe(false);
38+
delete process.env.BABEL_ENV;
39+
});
40+
41+
test('Prod mode - client side', () => {
42+
window.TRU_BUILD_INFO = { mode: 'production' };
43+
window.TRU_FRONT_END = true;
44+
expect(m().isDevBuild()).toBe(false);
45+
expect(m().isProdBuild()).toBe(true);
3046
});
3147

32-
test('Prod code build detection', () => {
48+
test('Prod mode - server side', () => {
3349
process.env.BABEL_ENV = 'production';
3450
expect(m().isDevBuild()).toBe(false);
3551
expect(m().isProdBuild()).toBe(true);
52+
delete process.env.BABEL_ENV;
3653
});
3754

38-
test('Build timestamp on client-side', () => {
39-
global.BUILD_TIMESTAMP = 'DUMMY_TIMESTAMP';
40-
global.FRONT_END = true;
41-
expect(m().buildTimestamp()).toBe('DUMMY_TIMESTAMP');
55+
test('Build timestamp - client-side', () => {
56+
window.TRU_BUILD_INFO = { timestamp: 'Test build timestamp' };
57+
window.TRU_FRONT_END = true;
58+
expect(m().buildTimestamp()).toBe('Test build timestamp');
4259
});
4360

44-
test('Build timestamp on server-side', () => {
45-
global.BUILD_INFO = { timestamp: 'DUMMY_TIMESTAMP' };
46-
expect(global.FRONT_END).toBeUndefined();
47-
expect(m().buildTimestamp()).toBe('DUMMY_TIMESTAMP');
61+
test('Build timestamp - server-side', () => {
62+
global.TRU_BUILD_INFO = { timestamp: 'Test build timestamp' };
63+
expect(window.FRONT_END).toBeUndefined();
64+
expect(m().buildTimestamp()).toBe('Test build timestamp');
4865
});

config/test.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module.exports = {
2+
dummyConfigKey: 'Dummy config value',
3+
};

config/webpack/lib-base.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ module.exports = function configFactory(ops) {
3535
entry: ops.entry,
3636
externals: [
3737
'babel-runtime',
38-
'config',
3938
'lodash',
4039
'moment',
4140
'prop-types',

docs/config-utils.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ both at server- and client-side.
88

99
Use it this way:
1010
```js
11-
import { utils } from 'topcoder-react-utils';
11+
import { config } from 'topcoder-react-utils';
1212

13-
const config = utils.config;
13+
// Some code relying on the config.
1414
```
1515

1616
Keep in mind that config still can be different at client- and server-side, due

docs/isomorphy-utils.md

Lines changed: 29 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2,37 +2,30 @@
22
Collection of helpers to deal with isomorphic aspects of the code.
33

44
**Why?** &mdash; Most of our ReactJS code should be isomorphic, i.e. it should
5-
be functional both when executed at client-side (in browser), and when executed
6-
at server-side (in NodeJS), without extra care of the caller. In some cases, it
7-
demands to explicitely check, where the code is executed, and proceed depending
8-
on that. This module provides functions that allow to do such checks, and to get
9-
some additional information about the currently running code.
5+
be functional both when executed at the client-side (in browser), and when
6+
executed at the server-side (in NodeJS), without extra care of the caller.
7+
In some cases, it demands to explicitely check, where the code is executed, and
8+
proceed depending on that. This module provides functions that allow to do such
9+
checks, and to get some additional information about the currently running code.
1010

11-
All functions provided by this module should be imported and used like:
12-
```js
13-
import { utils } from 'topcoder-react-utils';
14-
15-
utils.isomorphy.isClientSide();
16-
```
17-
18-
Note that `isClientSide()` and `isServerSide()` functions rely on the global
19-
`FRONT_END` variable being defined only inside JS bundle build for the frontend
20-
execution by our standard Wepback config for apps. It is assumed that this
21-
variable won't be present in NodeJS environment.
11+
**Important Notes:**
12+
- All functionality of this module relies on `topcoder-react-utils`
13+
configuration / client initialization / server code beign used in your
14+
project;
15+
- `isDevBuild()` and `isProdBuild()` functions return dev/prod mode of the
16+
currently executed code. While the server launched in dev mode always serve
17+
dev version of the frontend code, the server launched in prod mode can serve
18+
either prod, or dev versions of the code, depending on which of them was build
19+
before by the caller. Note that the mode depends on the value `BABEL_ENV`
20+
environment variable (at the build time, for the front-end code; or at
21+
the present time, for the server-side code). `NODE_ENV` variable, in turn,
22+
defines the runtime environment, which can be configured via
23+
[`config`](./config-utils.md).
2224

23-
`isDevBuild()` and `isProdBuild()` functions rely on `BABEL_ENV` environment
24-
variable, and they tell about the build-time configuration of the code, which
25-
should be the same at the client- and server-side to ensure proper server-side
26-
rendering. This is independent of `NODE_ENV` environment variable, which sets
27-
the runtime configuration of the app, e.g. the API keys and endpoints to call
28-
for development and production, etc.
25+
[Example](#example)
2926

30-
`buildTimestamp()` function relies on the global `BUILD_TIMESTAMP` variable
31-
defined in the frontend JS bundle build by our standard Webpack congif for app;
32-
at the server-side it relies on our standard server to expose, via the global
33-
`BUILD_INFO` object, the build info about the bundle served by the server.
27+
### Reference
3428

35-
### Provided Functions
3629
- **`buildTimestamp()`** &mdash; Returns build timestamp of the frontend JS
3730
bundle, in form of ISO date/time string. At the server-side it will be the
3831
timestamp of bundle being served by the server.
@@ -42,6 +35,14 @@ at the server-side it relies on our standard server to expose, via the global
4235
is running; `false` otherwise.
4336
- **`isProdBuild()`** &mdash; Returns `true` if the production version of the
4437
code is running; `false` otherwise.
45-
variable (`NODE_ENV`, in turns, determines runtime configuration of the app).
4638
- **`isServerSide()`** &mdash; Returns `true` if executed at the server-side
4739
(in NodeJS); `false` otherwise.
40+
41+
### Example
42+
```js
43+
import { isomorphy } from 'topcoder-react-utils';
44+
45+
if (isomorphy.isClientSide()) {
46+
// Do some useful staff here, if executed at the client-side.
47+
}
48+
```

0 commit comments

Comments
 (0)