Skip to content

Commit 3795d3e

Browse files
committed
Updated Babel configs and docs, added ESLint config
1 parent c4389d4 commit 3795d3e

File tree

10 files changed

+190
-2656
lines changed

10 files changed

+190
-2656
lines changed

README.md

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,33 @@
11
# Topcoder React Utils
2-
[Topcoder](https://www.topcoder.com) collection of generic ReactJS configurations, components and utilities to be shared between all internal and external ReactJS projects developed by Topcoder community.
2+
The [Topcoder](https://www.topcoder.com) collection of generic ReactJS configurations, components and utilities to be shared between all internal and external ReactJS projects developed by the Topcoder community.
33

4-
### Documentation
5-
This package provides: various configuration files that helps to unify configuration of various applications created at Topcoder, ReactJS components and utilities (non-react classes and functions) that help to solve various typical problems in the same pattern accross all our apps.
4+
### Installation
5+
Install this package as
6+
```
7+
$ npm install --save topcoder-react-utils
8+
```
9+
10+
You are done if you will use only components and utilities provided by this package. If you are to use configurations, you must also install peer dependencies. If you like to explicitly add them to the `package.json` of your project do
11+
```
12+
$ npm install -g install-peerdeps
13+
$ install-peerdeps topcoder-react-utils
14+
```
15+
16+
Alternatively, you can do
17+
```
18+
$ npm install --save install-peerdeps
19+
```
20+
21+
then add to your `package.json` the following script:
22+
```json
23+
"postinstall": "install-peerdeps -S topcoder-react-utils"
24+
```
25+
26+
Now, in both cases, `$ npm install` will install all necessary dependencies, but in the second case they won't be stored into your `package.json`.
627

728
#### Configurations
8-
- [**Babel Configurations**](docs/babel-config.md) — Standard configurations for [Babel](https://babeljs.io/)
29+
- [**Babel Configurations**](docs/babel-config.md) — Standard configurations for [Babel](https://babeljs.io/);
30+
- [**ESLint Configurations**](docs/eslint-config.md) — Standard configurations for [ESLint](https://eslint.org/).
931

1032
#### Components
1133
*To be added*

config/babel/node-ssr.js

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/* Babel preset for NodeJS build with support of server-side JSX rendering. */
2+
3+
const _ = require('lodash');
4+
const config = _.cloneDeep(require('./webpack'));
5+
6+
const cssModulesTransformPluginOps = {
7+
extensions: ['.css', '.scss'],
8+
};
9+
10+
const transformAssetsPluginOptions = {
11+
extensions: ['gif', 'jpeg', 'jpg', 'png'],
12+
};
13+
14+
config.plugins = config.plugins.concat([
15+
'dynamic-import-node',
16+
['transform-assets', transformAssetsPluginOptions],
17+
[ 'css-modules-transform', cssModulesTransformPluginOps ],
18+
]);
19+
20+
const moduleResolverPluginOps
21+
= config.plugins.find(x => x[0] === 'module-resolver')[1];
22+
23+
moduleResolverPluginOps.transformFunctions = ['resolveWeak'];
24+
25+
switch (process.env.BABEL_ENV) {
26+
case 'development':
27+
_.pull(config.plugins, 'react-hot-loader/babel');
28+
cssModulesTransformPluginOps.generateScopedName = '[path][name]___[local]';
29+
break;
30+
case 'production':
31+
cssModulesTransformPluginOps.generateScopedName = '[hash:base64:6]';
32+
break;
33+
case 'test':
34+
cssModulesTransformPluginOps.generateScopedName = '[path][name]___[local]';
35+
break;
36+
}
37+
38+
module.exports = (apt, ops) => {
39+
const baseAssetsOutputPath = ops.baseAssetsOutputPath || '';
40+
transformAssetsPluginOptions.name
41+
= `${baseAssetsOutputPath}/images/[hash].[ext]`;
42+
return config;
43+
};

config/babel/node-ssr.json

Lines changed: 0 additions & 47 deletions
This file was deleted.

config/babel/webpack.js

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/* Babel preset for the Webpack build. */
2+
3+
const envPresetOps = {};
4+
5+
const reactCssModulesPluginOps = {
6+
filetypes: {
7+
'.scss': {
8+
syntax: 'postcss-scss',
9+
}
10+
}
11+
};
12+
13+
const config = {
14+
presets: [
15+
['env', envPresetOps],
16+
'react',
17+
'stage-2',
18+
],
19+
plugins: [
20+
['module-resolver', {
21+
extensions: ['.js', '.jsx'],
22+
root: [
23+
'./src/shared',
24+
'./src',
25+
],
26+
}],
27+
'inline-react-svg',
28+
'transform-runtime',
29+
['react-css-modules', reactCssModulesPluginOps],
30+
],
31+
};
32+
33+
switch (process.env.BABEL_ENV) {
34+
case 'development':
35+
reactCssModulesPluginOps.generateScopedName = '[path][name]___[local]';
36+
config.plugins.push('react-hot-loader/babel');
37+
break;
38+
case 'production':
39+
reactCssModulesPluginOps.generateScopedName = '[hash:base64:6]';
40+
break;
41+
default:
42+
}
43+
44+
module.exports = config;

config/babel/webpack.json

Lines changed: 0 additions & 42 deletions
This file was deleted.

config/eslint/default.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"extends": "airbnb",
3+
"parser": "babel-eslint",
4+
"settings": {
5+
"import/resolver": {
6+
"babel-module": {}
7+
}
8+
}
9+
}

docs/babel-config.md

Lines changed: 38 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,66 @@
11
# Babel Configurations
22
Standard configurations for [Babel](https://babeljs.io/).
33

4-
**Why?** — We use Babel to support latest JavaScript specifications in our projects, and to allow for some fancy features in our code. The standard Babel configurations help to ensure that selected code patterns are supported in all of our apps.
4+
**Why?** — We use Babel to support latest JavaScript specifications in our projects, and to allow for some fancy features in our code. The standard Babel configurations ensure that the same code patterns are supported in all of our apps.
55

66
Several Babel configurations are provided by this package:
77

8-
[**config/babel/webpack.json**](#webpack) — Babel config to use for JS and JSX files compilation during the Webpack build process;
8+
- [**config/babel/node-ssr**](#node-ssr) — Babel configuration for NodeJS compilation of JS and JSX modules (server-side ReactJS rendering);
99

10-
[**config/babel/node-ssr.json**](#node-ssr) — Server-side configuration with support of server-side rendering;
10+
- [**config/babel/webpack**](#webpack) — Babel configuration for Webpack compilation of JS and JSX modules.
1111

12-
To use any of these configurations in your code use `extend` Babel option in your `.babelrc` file, or whenever you need it, e.g.
12+
Use them as presets in your `.babelrc`, e.g.
1313
```json
1414
{
15-
"extend": "topcoder-react-utils/config/babel/node-ssr.json"
15+
"presets": ["topcoder-react-utils/config/babel/node-ssr"]
1616
}
1717
```
18-
This way you can also easily tune some of Babel options in the way specific to your project; however if you feel that an option change you need is necessary for any generic react-based project, consider to submit an update to the configuration provided by `topcoder-react-utils`.
18+
19+
To set options provided by a preset:
20+
```json
21+
{
22+
"presets": [
23+
["topcoder-react-utils/config/babel/node-ssr", {
24+
"someOption": "optionValue"
25+
}]
26+
]
27+
}
28+
```
29+
30+
As the presets are JS modules, you can also wrap them into your own JS code to create a special preset that customizes Babel configuration in any necessary way. If you feel that the modification you need is useful for any generic ReactJS app, feel free to open GitHub issue ticket to discuss an update of our default configurations.
31+
32+
These presets may behave differently in different Babel environments. You can set the environment with `BABEL_ENV` environment variable, or with `forceEnv` option of the Webpack's `babel-loader`.
1933

2034
### Configuration Details
2135

22-
- <a name="webpack">**`config/babel/webpack.json`**</a> &mdash; Babel config to use for JS and JSX files compilation during the Webpack build process;
36+
- <a name="node-ssr">**`config/babel/node-ssr.json`**</a> &mdash; Babel configuration for NodeJS compilation of JS and JSX modules (server-side ReactJS rendering);
2337

2438
- Presets: [env](https://www.npmjs.com/package/babel-preset-env), [react](https://www.npmjs.com/package/babel-preset-react), [stage-2](https://www.npmjs.com/package/babel-preset-stage-2);
2539

26-
- Uses [`babel-plugin-react-css-modules`](https://www.npmjs.com/package/babel-plugin-react-css-modules) to transform `styleName` props of ReactJS components into `className` props. A style name is transformed into: (i) `.path-to-the-stylesheet-and-stylesheet-file-name___original-style-name` class in the *development* Babel environment; (ii) `.6-symbols-hash-of-the-style` in the *production* environment. The class names generated in the first cases are verbose, thus good for debugging; and in the second case they are compact which results in smaller size of JS and CSS bundles.
40+
- Uses [`babel-plugin-css-modules-transform`](https://www.npmjs.com/package/babel-plugin-css-modules-transform) to convert CSS and SCSS imports into objects with keys and values being the original and transformed class names. The transformed class names will match the class names generated by the `babel-plugin-react-css-modules` plugin, mentioned below;
2741

28-
- Uses [`babel-plugin-inline-react-svg`](https://www.npmjs.com/package/babel-plugin-inline-react-svg) to embed imported SVG files into complied JS code;
42+
- Uses [`babel-plugin-dynamic-import-node`](https://www.npmjs.com/package/babel-plugin-dynamic-import-node) to support dynamic `import(..)` statemens;
2943

30-
- Uses [`babel-plugin-transform-runtime`](https://ww.npmjs.com/package/babel-plugin-transform-runtime) to generate more optimal JS bundles;
44+
- Uses [`babel-plugin-inline-react-svg`](https://www.npmjs.com/package/babel-plugin-inline-react-svg) to embed imported SVG files into the complied JS modules;
3145

32-
- Uses [`babel-plugin-module-resolver`](https://www.npmjs.com/package/babel-plugin-module-resolver) to setup the following paths as the roots for resolution of relative imports: `./src/shared`, `./src`;
46+
- Uses [`babel-plugin-module-resolver`](https://www.npmjs.com/package/babel-plugin-module-resolver) to setup the following paths as the roots for resolution of relative imports: `./src/shared`, `./src`. It will also apply path resolution to the first argument of `resolveWeak(..)` functions encountered in the compiled code;
47+
48+
- Uses [`babel-plugin-react-css-modules`](https://www.npmjs.com/package/babel-plugin-react-css-modules) to transform `styleName` props of ReactJS components into globally unique `className` props. Generated class names are verbose in *development* and *test* Babel environment, for the ease of debugging; and they are short 6-symbols hashes in *production* Babel environment, for compactness of the compiled JS and CSS modules;
49+
50+
- Uses [`babel-plugin-tranform-assets`](https://www.npmjs.com/package/babel-plugin-transform-assets) to convert GIF, JPEG, JPG, and PNG imports into `/images/[FILE_HASH].[FILE_EXTENSION]` URL strings. Use the **`baseAssetsOutputPath`** preset option to prefix generated paths with an arbitrary path;
3351

34-
- Uses [`react-hot-loader/babel`](https://www.npmjs.com/package/react-hot-loader) to support hot module reloading in *development* environment.
52+
- Uses [`babel-plugin-transform-runtime`](https://www.npmjs.com/package/babel-plugin-transform-runtime) to optimized complied JS modules (it externalizes references to helpers and builtins, automatically polyfilling the code without polluting globals).
3553

36-
- <a name="node-ssr">**`config/babel/node-ssr.json`**</a> &mdash; Server-side configuration with support of server-side rendering. It extends [`config/babel/webpack.json`](#webpack) configuration with the following:
54+
- <a name="webpack">**`config/babel/webpack`**</a> &mdash; Babel configuration for Webpack compilation of JS and JSX modules.
3755

38-
- In the *test* Babel environment [`babel-plugin-react-css-modules`](https://www.npmjs.com/package/babel-plugin-react-css-modules) transforms a style name into `.path-to-the-stylesheet-___stylesheet-file-name__origina-style-name___5-symbols-hash-of-the-style` class. Resuling class names are verbose and good for debugging, the difference from *development* environment is for historic reasons.
56+
- Presets: [env](https://www.npmjs.com/package/babel-preset-env), [react](https://www.npmjs.com/package/babel-preset-react), [stage-2](https://www.npmjs.com/package/babel-preset-stage-2);
57+
58+
- Uses [`babel-plugin-inline-react-svg`](https://www.npmjs.com/package/babel-plugin-inline-react-svg) to embed imported SVG files into the complied JS modules;
3959

40-
- Uses [`babel-plugin-css-modules-transform`](https://www.npmjs.com/package/babel-plugin-css-modules-transform) to convert CSS and SCSS imports into objects with keys and values being the original and generated class names. The class names are generated by the same rules being used to transform style names into classes;
60+
- Uses [`babel-plugin-module-resolver`](https://www.npmjs.com/package/babel-plugin-module-resolver) to setup the following paths as the roots for resolution of relative imports: `./src/shared`, `./src`;
4161

42-
- Uses [`babel-plugin-tranform-assets`](https://www.npmjs.com/package/babel-plugin-transform-assets) to convert GIF, JPEG, JPG, and PNG imports into URL strings like `/images/hash-of-the-asset-file.original-file-extension`, where `/images/` is a fixed path prefix;
62+
- Uses [`babel-plugin-react-css-modules`](https://www.npmjs.com/package/babel-plugin-react-css-modules) to transform `styleName` props of ReactJS components into globally unique `className` props. Generated class names are verbose in *development* and *test* Babel environment, for the ease of debugging; and they are short 6-symbols hashes in *production* Babel environment, for compactness of the compiled JS and CSS modules;
4363

44-
- Uses [`babel-plugin-dynamic-import-node`](https://www.npmjs.com/package/babel-plugin-dynamic-import-node) to support dynamic `import(..)` statement;
64+
- Uses [`react-hot-loader/babel`](https://www.npmjs.com/package/react-hot-loader) to support hot module reloading in the *development* Babel environment;
4565

46-
- Avoids using [`react-hot-loader/babel`](https://www.npmjs.com/package/react-hot-loader) in the *development* Babel environment.
66+
- Uses [`babel-plugin-transform-runtime`](https://www.npmjs.com/package/babel-plugin-transform-runtime) to optimized complied JS modules (it externalizes references to helpers and builtins, automatically polyfilling the code without polluting globals).

docs/eslint-config.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# ESlint Configurations
2+
Standard configurations for [ESLint](https://eslint.org/).
3+
4+
**Why?** &mdash; We use ESLint for quality control of our code. The standard ESLint configurations ensure that we use the same rules across all our projects.
5+
6+
At the moment, a single ESLint configuration is provided by this package:
7+
- [**config/eslint/default**](#default) &mdash; Default ESLint configuration.
8+
9+
Under the hood it matches the standard [AirBnB ESLint](https://www.npmjs.com/package/eslint-config-airbnb) config, and just adds a few plugins to ensure that ESLint properly cooperates with Babel to understand JS and JSX constructs we use in our code.
10+
11+
To use it just create the following `.eslintrc`:
12+
```json
13+
{
14+
"extends": "topcoder-react-utils/config/eslint/default"
15+
}
16+
```
17+
18+
`.eslintrc` allows you to further modify ESLint configuration, but it is not recommended without a very good and special reason.

0 commit comments

Comments
 (0)