Skip to content

Commit a0f2a74

Browse files
committed
Link, NavLink, and other updates
- Adds Link and NavLink components and related documentation; - Misc updates of other documentation; - Sets up ESLint and fixes existing errors.
1 parent 3795d3e commit a0f2a74

18 files changed

+5566
-56
lines changed

.babelrc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"presets": [
3+
"./config/babel/node-ssr"
4+
]
5+
}

.eslintignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
__coverage__
2+
dist
3+
node_modules

.eslintrc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"extends": "./config/eslint/default.json"
3+
}

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1+
dist
12
node_modules

CHANGELOG.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
# Topcoder React Utils Changelog
22

33
### v0.0.x
4-
Intial version of the package. A big journey starts here.
5-
- Standard Babel configurations for JS/JSX modules compilation during Webpack build, and for code execution in Node environment with support of server-side rendering.
4+
Pre-release drafts of the initial package version. A big journey starts here.

README.md

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,18 @@
11
# Topcoder React Utils
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.
2+
The [Topcoder](https://www.topcoder.com) collection of generic ReactJS
3+
configurations, components and utilities to be shared between all internal and
4+
external ReactJS projects developed by the Topcoder community.
35

46
### Installation
57
Install this package as
68
```
79
$ npm install --save topcoder-react-utils
810
```
911

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
12+
You are done if you will use only components and utilities provided by this
13+
package. If you are to use configurations, you must also install peer
14+
dependencies. If you like to explicitly add them to the `package.json` of your
15+
project do
1116
```
1217
$ npm install -g install-peerdeps
1318
$ install-peerdeps topcoder-react-utils
@@ -23,16 +28,19 @@ then add to your `package.json` the following script:
2328
"postinstall": "install-peerdeps -S topcoder-react-utils"
2429
```
2530

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`.
31+
Now, in both cases, `$ npm install` will install all necessary dependencies, but
32+
in the second case they won't be stored into your `package.json`.
2733

28-
#### Configurations
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/).
34+
### Configurations
35+
- [**Babel Configurations**](docs/babel-config.md) — Standard configurations
36+
for [Babel](https://babeljs.io/);
37+
- [**ESLint Configurations**](docs/eslint-config.md) — Standard
38+
configurations for [ESLint](https://eslint.org/).
3139

32-
#### Components
33-
*To be added*
40+
### Components
41+
- [**Link and NavLink**](docs/link-and-navlink.md) &mdash; Auxiliary wrappers around [React Router](https://github.com/ReactTraining/react-router)'s `<Link>` and `<NavLink>` components; they help to handle external and internal links in a single uniform manner;
3442

35-
#### Utilities
43+
### Utilities
3644
*To be added*
3745

3846
### Development

config/babel/node-ssr.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ const transformAssetsPluginOptions = {
1414
config.plugins = config.plugins.concat([
1515
'dynamic-import-node',
1616
['transform-assets', transformAssetsPluginOptions],
17-
[ 'css-modules-transform', cssModulesTransformPluginOps ],
17+
['css-modules-transform', cssModulesTransformPluginOps],
1818
]);
1919

2020
const moduleResolverPluginOps
@@ -33,9 +33,10 @@ switch (process.env.BABEL_ENV) {
3333
case 'test':
3434
cssModulesTransformPluginOps.generateScopedName = '[path][name]___[local]';
3535
break;
36+
default:
3637
}
3738

38-
module.exports = (apt, ops) => {
39+
module.exports = (apt, ops = {}) => {
3940
const baseAssetsOutputPath = ops.baseAssetsOutputPath || '';
4041
transformAssetsPluginOptions.name
4142
= `${baseAssetsOutputPath}/images/[hash].[ext]`;

config/babel/webpack.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ const reactCssModulesPluginOps = {
66
filetypes: {
77
'.scss': {
88
syntax: 'postcss-scss',
9-
}
10-
}
9+
},
10+
},
1111
};
1212

1313
const config = {

config/webpack/default.js

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
/* NOTE: At the moment this file is just a draft, thus skip by linter */
2+
/* eslint-disable */
3+
4+
const _ = require('lodash');
5+
const CopyWebpackPlugin = require('copy-webpack-plugin');
6+
const ExtractCssChunks = require('extract-css-chunks-webpack-plugin');
7+
const forge = require('node-forge');
8+
const fs = require('fs');
9+
const moment = require('moment');
10+
const path = require('path');
11+
const webpack = require('webpack');
12+
13+
/**
14+
* Creates a new Webpack config object.
15+
* @param {String} context Base URL for resolution of relative config paths.
16+
* @param {String} publicPath Base URL for the output of the build assets.
17+
* @param {Object|String|String[]} entry Entry points. If an object is passed in
18+
* the "polyfills" entry point will be extended or appended to include some
19+
* polyfills we consider obligatory. If a string or an array is passed in,
20+
* it will be turned into "main" entry point, and the "polyfills" entry point
21+
* will be added to it.
22+
*/
23+
module.exports = function newConfig(context, publicPath, entry) {
24+
/* Writes UTC timestamp of the build time into .build-timestamp file. */
25+
const buildTimestamp = moment().toISOString();
26+
fs.writeFileSync(path.resolve(context, '.build-timestamp'), buildTimestamp);
27+
28+
/* Writes a random 32-bit key into .build-key file. This key can be used for
29+
* encryption purposes. */
30+
const buildKey = forge.random.getBytesSync(32);
31+
fs.writeFileSync(path.resolve(context, '.build-key', buildKey));
32+
33+
/* Entry points normalization. */
34+
let entry2 = _.isObject(entry) ? _.cloneDeep(entry) : { main: entry };
35+
if (!entry2.polyfills) entry2.polyfills = [];
36+
else if (!_.isArray(entry2.polyfills)) entry2.polyfills = [entry2.polyfills];
37+
entry2.polyfills = _.union(entry2.polyfills, [
38+
'babel-polyfill',
39+
'nodelist-foreach-polyfill',
40+
]);
41+
42+
return {
43+
context,
44+
entry: entry2,
45+
node: {
46+
__dirname: true,
47+
fs: 'empty',
48+
},
49+
output: {
50+
chunkFilename: '[name].js',
51+
filename: '[name].js',
52+
path: path.resolve(__dirname, path.resolve(context, 'build')),
53+
publicPath: `${PUBLIC_PATH}/`,
54+
},
55+
plugins: [
56+
new ExtractCssChunks({
57+
filename: '[name].css',
58+
}),
59+
new webpack.DefinePlugin({
60+
BUILD_KEY: JSON.stringify(buildKey),
61+
'process.env': {
62+
BUILD_TIMESTAMP: JSON.stringify(buildTimestamp),
63+
FRONT_END: true,
64+
},
65+
})
66+
],
67+
resolve: {
68+
alias: {
69+
/* Aliases to JS an JSX files are handled by Babel. */
70+
assets: path.resolve(context, 'src/assets'),
71+
components: path.resolve(context, 'src/shared/components'),
72+
styles: path.resolve(context, 'src/styles'),
73+
},
74+
},
75+
rules: [{
76+
/* Loads font resources from "src/assets/fonts" folder. */
77+
test: /\.(eot|otf|svg|ttf|woff2?)$/,
78+
include: [/src[/\\]assets[/\\]fonts/],
79+
options: {
80+
outputPaths: '/fonts/',
81+
publicPath,
82+
},
83+
}, {
84+
/* Loads JS and JSX moudles, and inlines SVG assets. */
85+
test: /\.(jsx?|svg)$/,
86+
exclude: [/node_modules/],
87+
loader: 'babel-loader',
88+
options: {
89+
babelrc: false,
90+
extends: 'topcoder-react-utils/config/babel/webpack.json',
91+
forceEnv: 'production',
92+
},
93+
}, {
94+
/* Loads image assets. */
95+
test: /\.(gif|jpe?g|png|svg)$/,
96+
loader: 'file-loader',
97+
options: {
98+
outputPath: '/images/',
99+
publicPath,
100+
},
101+
}, {
102+
/* Loads CSS stylesheets. It is assumed that CSS stylesheets come only
103+
* from dependencies, as we use SCSS inside our own code. */
104+
test: /\.css$/,
105+
use: ExtractCssChunks.extract({
106+
fallback: 'style-loader',
107+
use: ['css-loader'],
108+
}),
109+
}],
110+
};
111+
};

docs/babel-config.md

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

4-
**Why?** &mdash; 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.
4+
**Why?** &mdash; We use Babel to support latest JavaScript specifications in our
5+
projects, and to allow for some fancy features in our code. The standard Babel
6+
configurations ensure that the same code patterns are supported in all of our apps.
57

68
Several Babel configurations are provided by this package:
79

8-
- [**config/babel/node-ssr**](#node-ssr) &mdash; Babel configuration for NodeJS compilation of JS and JSX modules (server-side ReactJS rendering);
10+
- [**config/babel/node-ssr**](#node-ssr) &mdash; Babel configuration for NodeJS
11+
compilation of JS and JSX modules (server-side ReactJS rendering);
912

10-
- [**config/babel/webpack**](#webpack) &mdash; Babel configuration for Webpack compilation of JS and JSX modules.
13+
- [**config/babel/webpack**](#webpack) &mdash; Babel configuration for Webpack
14+
compilation of JS and JSX modules.
1115

1216
Use them as presets in your `.babelrc`, e.g.
1317
```json
@@ -27,40 +31,84 @@ To set options provided by a preset:
2731
}
2832
```
2933

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.
34+
As the presets are JS modules, you can also wrap them into your own JS code to
35+
create a special preset that customizes Babel configuration in any necessary
36+
way. If you feel that the modification you need is useful for any generic
37+
ReactJS app, feel free to open GitHub issue ticket to discuss an update of our
38+
default configurations.
3139

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`.
40+
These presets may behave differently in different Babel environments. You can
41+
set the environment with `BABEL_ENV` environment variable, or with `forceEnv`
42+
option of the Webpack's `babel-loader`.
3343

3444
### Configuration Details
3545

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);
37-
38-
- 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);
39-
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;
41-
42-
- Uses [`babel-plugin-dynamic-import-node`](https://www.npmjs.com/package/babel-plugin-dynamic-import-node) to support dynamic `import(..)` statemens;
43-
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;
45-
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;
51-
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).
53-
54-
- <a name="webpack">**`config/babel/webpack`**</a> &mdash; Babel configuration for Webpack compilation of JS and JSX modules.
55-
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;
59-
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`;
61-
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;
63-
64-
- Uses [`react-hot-loader/babel`](https://www.npmjs.com/package/react-hot-loader) to support hot module reloading in the *development* Babel environment;
65-
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).
46+
- <a name="node-ssr">**`config/babel/node-ssr.json`**</a> &mdash; Babel
47+
configuration for NodeJS compilation of JS and JSX modules (server-side ReactJS
48+
rendering);
49+
50+
- Presets: [env](https://www.npmjs.com/package/babel-preset-env),
51+
[react](https://www.npmjs.com/package/babel-preset-react),
52+
[stage-2](https://www.npmjs.com/package/babel-preset-stage-2);
53+
54+
- Uses [`babel-plugin-css-modules-transform`](https://www.npmjs.com/package/babel-plugin-css-modules-transform)
55+
to convertCSS and SCSS imports into objects with keys and values being the
56+
original and transformed class names. The transformed class names will match
57+
the class names generated by the `babel-plugin-react-css-modules` plugin,
58+
mentioned below;
59+
60+
- Uses [`babel-plugin-dynamic-import-node`](https://www.npmjs.com/package/babel-plugin-dynamic-import-node)
61+
to support dynamic `import(..)` statemens;
62+
63+
- Uses [`babel-plugin-inline-react-svg`](https://www.npmjs.com/package/babel-plugin-inline-react-svg)
64+
to embed imported SVG files into the complied JS modules;
65+
66+
- Uses [`babel-plugin-module-resolver`](https://www.npmjs.com/package/babel-plugin-module-resolver)
67+
to setup the following paths as the roots for resolution of relative imports:
68+
`./src/shared`, `./src`. It will also apply path resolution to the first
69+
argument of `resolveWeak(..)` functions encountered in the compiled code;
70+
71+
- Uses [`babel-plugin-react-css-modules`](https://www.npmjs.com/package/babel-plugin-react-css-modules)
72+
to transform `styleName` props of ReactJS components into globally unique
73+
`className` props. Generated class names are verbose in *development* and
74+
*test* Babel environments, for the ease of debugging; and they are short
75+
6-symbols hashes in the *production* Babel environment, for compactness of the
76+
compiled JS and CSS modules;
77+
78+
- Uses [`babel-plugin-tranform-assets`](https://www.npmjs.com/package/babel-plugin-transform-assets)
79+
to convert GIF, JPEG, JPG, and PNG imports into
80+
`/images/[FILE_HASH].[FILE_EXTENSION]` URL strings. Use the
81+
**`baseAssetsOutputPath`** preset option to prefix generated paths with an
82+
arbitrary path;
83+
84+
- Uses [`babel-plugin-transform-runtime`](https://www.npmjs.com/package/babel-plugin-transform-runtime)
85+
to optimize complied JS modules (it externalizes references to helpers and
86+
builtins, automatically polyfilling the code without polluting globals).
87+
88+
- <a name="webpack">**`config/babel/webpack`**</a> &mdash; Babel configuration
89+
for Webpack compilation of JS and JSX modules.
90+
91+
- Presets: [env](https://www.npmjs.com/package/babel-preset-env),
92+
[react](https://www.npmjs.com/package/babel-preset-react),
93+
[stage-2](https://www.npmjs.com/package/babel-preset-stage-2);
94+
95+
- Uses [`babel-plugin-inline-react-svg`](https://www.npmjs.com/package/babel-plugin-inline-react-svg)
96+
to embed imported SVG files into the complied JS modules;
97+
98+
- Uses [`babel-plugin-module-resolver`](https://www.npmjs.com/package/babel-plugin-module-resolver)
99+
to setup the following paths as the roots for resolution of relative imports:
100+
`./src/shared`, `./src`;
101+
102+
- Uses [`babel-plugin-react-css-modules`](https://www.npmjs.com/package/babel-plugin-react-css-modules)
103+
to transform `styleName` props of ReactJS components into globally unique
104+
`className` props. Generated class names are verbose in *development* and
105+
*test* Babel environments, for the ease of debugging; and they are short
106+
6-symbols hashes in the *production* Babel environment, for compactness of the
107+
compiled JS and CSS modules;
108+
109+
- Uses [`react-hot-loader/babel`](https://www.npmjs.com/package/react-hot-loader)
110+
to support hot module reloading in the *development* Babel environment;
111+
112+
- Uses [`babel-plugin-transform-runtime`](https://www.npmjs.com/package/babel-plugin-transform-runtime)
113+
to optimize complied JS modules (it externalizes references to helpers and
114+
builtins, automatically polyfilling the code without polluting globals).

docs/eslint-config.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ Under the hood it matches the standard [AirBnB ESLint](https://www.npmjs.com/pac
1111
To use it just create the following `.eslintrc`:
1212
```json
1313
{
14-
"extends": "topcoder-react-utils/config/eslint/default"
14+
"extends": "./node_modules/topcoder-react-utils/config/eslint/default.json"
1515
}
1616
```
1717

0 commit comments

Comments
 (0)