Skip to content

Commit d7befcd

Browse files
committed
Update to react-scripts 1.0.17. Seperate css and cssmodules .css files. Update css classnames to [path]__[name]___[local]
1 parent 3189e19 commit d7befcd

11 files changed

+253
-97
lines changed

README.md

+44
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,54 @@
22

33
Adds [CSS Modules](https://github.com/css-modules/css-modules) to [Create React App](https://github.com/facebookincubator/create-react-app).
44

5+
## How to use
56
Either create a new project using
67
`create-react-app my-app --scripts-version react-scripts-cssmodules`
78
or within your existing project uninstall `react-scripts` and install `react-scripts-cssmodules`.
89

10+
## Using CSS and CSS Modules
11+
To import as regular css, do the same as in CRA. `import mystyles.css`
12+
To import as css modules, rename the file to `[name].module.css` and the use as normal css modules.
13+
14+
## Example
15+
### `Button.module.css`
16+
17+
```css
18+
.button {
19+
padding: 20px;
20+
}
21+
```
22+
23+
### `another-stylesheet.css`
24+
25+
```css
26+
.button {
27+
color: green;
28+
}
29+
```
30+
31+
### `Button.js`
32+
33+
```js
34+
import React, { Component } from 'react';
35+
import './another-stylesheet.css'; // Import regular stylesheet
36+
import styles from './Button.module.css'; // Import css modules stylesheet as styles
37+
38+
class Button extends Component {
39+
render() {
40+
// You can use them as regular CSS styles
41+
return <div className={styles.button} />;
42+
}
43+
}
44+
```
45+
### `exported HTML`
46+
No clashes from other `.button` classnames
47+
48+
```html
49+
<div class="src__Button-module___button"></div>
50+
```
51+
52+
## Versioning
953
This package is 10:1 with Create React App. E.g. v0.9.10 of this package is the same as and interchanable with v0.9.1 of Create React App.
1054

1155
Any additional numbers are fixes for this app only. E.g. v0.9.21 is v0.9.2 of React App with a fix only for cssmodules.

config/polyfills.js

+6
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,9 @@ require('whatwg-fetch');
2222
// Object.assign() is commonly used with React.
2323
// It will use the native implementation if it's present and isn't buggy.
2424
Object.assign = require('object-assign');
25+
26+
// In tests, polyfill requestAnimationFrame since jsdom doesn't provide it yet.
27+
// We don't polyfill it in the browser--this is user's responsibility.
28+
if (process.env.NODE_ENV === 'test') {
29+
require('raf').polyfill(global);
30+
}

config/webpack.config.dev.js

+4-6
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,6 @@ module.exports = {
6161
// changing JS code would still trigger a refresh.
6262
],
6363
output: {
64-
// Next line is not used in dev but WebpackDevServer crashes without it:
65-
path: paths.appBuild,
6664
// Add /* filename */ comments to generated require()s in the output.
6765
pathinfo: true,
6866
// This does not produce a real file. It's just the virtual path that is
@@ -92,7 +90,7 @@ module.exports = {
9290
// https://github.com/facebookincubator/create-react-app/issues/290
9391
// `web` extension prefixes have been added for better support
9492
// for React Native Web.
95-
extensions: ['.web.js', '.js', '.json', '.web.jsx', '.jsx'],
93+
extensions: ['.web.js', '.mjs', '.js', '.json', '.web.jsx', '.jsx'],
9694
alias: {
9795
// @remove-on-eject-begin
9896
// Resolve Babel runtime relative to react-scripts.
@@ -126,7 +124,7 @@ module.exports = {
126124
// First, run the linter.
127125
// It's important to do this before Babel processes the JS.
128126
{
129-
test: /\.(js|jsx)$/,
127+
test: /\.(js|jsx|mjs)$/,
130128
enforce: 'pre',
131129
use: [
132130
{
@@ -164,7 +162,7 @@ module.exports = {
164162
},
165163
// Process JS with Babel.
166164
{
167-
test: /\.(js|jsx)$/,
165+
test: /\.(js|jsx|mjs)$/,
168166
include: paths.appSrc,
169167
loader: require.resolve('babel-loader'),
170168
options: {
@@ -192,7 +190,7 @@ module.exports = {
192190
options: {
193191
importLoaders: 1,
194192
modules: true,
195-
localIdentName: '[path][name]__[local]',
193+
localIdentName: '[path]__[name]___[local]',
196194
},
197195
},
198196
{

config/webpack.config.prod.js

+42-18
Original file line numberDiff line numberDiff line change
@@ -42,18 +42,34 @@ if (env.stringified['process.env'].NODE_ENV !== '"production"') {
4242
throw new Error('Production builds must have NODE_ENV=production.');
4343
}
4444

45-
// Note: defined here because it will be used more than once.
45+
// Create two seperate files for css and cssmodules this allow for
46+
// different settings to be used with ExtractTextPlugin.
4647
const cssFilename = 'static/css/[name].[contenthash:8].css';
48+
const cssModulesFilename = 'static/css/[name]-cssmodules.[contenthash:8].css';
4749

4850
// ExtractTextPlugin expects the build output to be flat.
4951
// (See https://github.com/webpack-contrib/extract-text-webpack-plugin/issues/27)
5052
// However, our output is structured with css, js and media folders.
5153
// To have this structure working with relative paths, we have to use custom options.
52-
const extractTextPluginOptions = shouldUseRelativeAssetPaths
54+
const extractTextPluginCSSOptions = shouldUseRelativeAssetPaths
5355
? // Making sure that the publicPath goes back to to build folder.
54-
{ publicPath: Array(cssFilename.split('/').length).join('../') }
56+
{ publicPath: Array(cssFilename.split('/').length).join('../') }
5557
: {};
5658

59+
const extractTextPluginCSSModulesOptions = shouldUseRelativeAssetPaths
60+
? // Making sure that the publicPath goes back to to build folder.
61+
{ publicPath: Array(cssModulesFilename.split('/').length).join('../') }
62+
: {};
63+
64+
const ExtractTextPluginCSS = new ExtractTextPlugin({
65+
filename: cssFilename,
66+
})
67+
68+
const ExtractTextPluginCSSModules = new ExtractTextPlugin({
69+
filename: cssModulesFilename,
70+
ignoreOrder: true,
71+
})
72+
5773
// This is the production configuration.
5874
// It compiles slowly and is focused on producing a fast and minimal bundle.
5975
// The development configuration is different and lives in a separate file.
@@ -96,7 +112,7 @@ module.exports = {
96112
// https://github.com/facebookincubator/create-react-app/issues/290
97113
// `web` extension prefixes have been added for better support
98114
// for React Native Web.
99-
extensions: ['.web.js', '.js', '.json', '.web.jsx', '.jsx'],
115+
extensions: ['.web.js', '.mjs', '.js', '.json', '.web.jsx', '.jsx'],
100116
alias: {
101117
// @remove-on-eject-begin
102118
// Resolve Babel runtime relative to react-scripts.
@@ -130,7 +146,7 @@ module.exports = {
130146
// First, run the linter.
131147
// It's important to do this before Babel processes the JS.
132148
{
133-
test: /\.(js|jsx)$/,
149+
test: /\.(js|jsx|mjs)$/,
134150
enforce: 'pre',
135151
use: [
136152
{
@@ -169,7 +185,7 @@ module.exports = {
169185
},
170186
// Process JS with Babel.
171187
{
172-
test: /\.(js|jsx)$/,
188+
test: /\.(js|jsx|mjs)$/,
173189
include: paths.appSrc,
174190
loader: require.resolve('babel-loader'),
175191
options: {
@@ -194,7 +210,7 @@ module.exports = {
194210
// in the main CSS file.
195211
{
196212
test: /\.module.css$/,
197-
loader: ExtractTextPlugin.extract(
213+
loader: ExtractTextPluginCSSModules.extract(
198214
Object.assign(
199215
{
200216
fallback: require.resolve('style-loader'),
@@ -204,7 +220,7 @@ module.exports = {
204220
options: {
205221
importLoaders: 1,
206222
modules: true,
207-
localIdentName: '[path][name]__[local]',
223+
localIdentName: '[path]__[name]___[local]',
208224
minimize: true,
209225
sourceMap: shouldUseSourceMap,
210226
},
@@ -231,18 +247,23 @@ module.exports = {
231247
},
232248
],
233249
},
234-
extractTextPluginOptions
250+
extractTextPluginCSSModulesOptions
235251
)
236252
),
237-
// Note: this won't work without `new ExtractTextPlugin()` in `plugins`.
253+
// Note: this won't work without `ExtractTextPluginCSSModules` in `plugins`.
238254
},
239255
{
240256
test: /\.css$/,
241257
exclude: /\.module\.css$/,
242-
loader: ExtractTextPlugin.extract(
258+
loader: ExtractTextPluginCSS.extract(
243259
Object.assign(
244260
{
245-
fallback: require.resolve('style-loader'),
261+
fallback: {
262+
loader: require.resolve('style-loader'),
263+
options: {
264+
hmr: false,
265+
},
266+
},
246267
use: [
247268
{
248269
loader: require.resolve('css-loader'),
@@ -274,10 +295,10 @@ module.exports = {
274295
},
275296
],
276297
},
277-
extractTextPluginOptions
298+
extractTextPluginCSSOptions
278299
)
279300
),
280-
// Note: this won't work without `new ExtractTextPlugin()` in `plugins`.
301+
// Note: this won't work without `ExtractTextPluginCSS` in `plugins`.
281302
},
282303
// "file" loader makes sure assets end up in the `build` folder.
283304
// When you `import` an asset, you get its filename.
@@ -339,6 +360,9 @@ module.exports = {
339360
// https://github.com/mishoo/UglifyJS2/issues/2011
340361
comparisons: false,
341362
},
363+
mangle: {
364+
safari10: true,
365+
},
342366
output: {
343367
comments: false,
344368
// Turned on because emoji and regex is not minified properly using default
@@ -348,10 +372,10 @@ module.exports = {
348372
sourceMap: shouldUseSourceMap,
349373
}),
350374
// Note: this won't work without ExtractTextPlugin.extract(..) in `loaders`.
351-
new ExtractTextPlugin({
352-
filename: cssFilename,
353-
ignoreOrder: true,
354-
}),
375+
// We have two ExtractTextPlugins to allow for different settings for
376+
// cssmodules and regular css
377+
ExtractTextPluginCSS,
378+
ExtractTextPluginCSSModules,
355379
// Generate a manifest file which contains a mapping of all asset filenames
356380
// to their corresponding output file so that tools can pick it up without
357381
// having to parse `index.html`.

config/webpackDevServer.config.js

+10-2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
const errorOverlayMiddleware = require('react-dev-utils/errorOverlayMiddleware');
1212
const noopServiceWorkerMiddleware = require('react-dev-utils/noopServiceWorkerMiddleware');
13+
const path = require('path');
1314
const config = require('./webpack.config.dev');
1415
const paths = require('./paths');
1516

@@ -72,8 +73,15 @@ module.exports = function(proxy, allowedHost) {
7273
quiet: true,
7374
// Reportedly, this avoids CPU overload on some systems.
7475
// https://github.com/facebookincubator/create-react-app/issues/293
76+
// src/node_modules is not ignored to support absolute imports
77+
// https://github.com/facebookincubator/create-react-app/issues/1065
7578
watchOptions: {
76-
ignored: /node_modules/,
79+
ignored: new RegExp(
80+
`^(?!${path
81+
.normalize(paths.appSrc + '/')
82+
.replace(/[\\]+/g, '\\\\')}).+[\\\\/]node_modules[\\\\/]`,
83+
'g'
84+
),
7785
},
7886
// Enable HTTPS if the HTTPS environment variable is set to 'true'
7987
https: protocol === 'https',
@@ -86,7 +94,7 @@ module.exports = function(proxy, allowedHost) {
8694
},
8795
public: allowedHost,
8896
proxy,
89-
setup(app) {
97+
before(app) {
9098
// This lets us open files from the runtime error overlay.
9199
app.use(errorOverlayMiddleware());
92100
// This service worker file is effectively a 'no-op' that will reset any

package.json

+23-22
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
{
22
"name": "react-scripts-cssmodules",
3-
"version": "1.0.142",
3+
"version": "1.0.171",
44
"description": "Configuration and scripts for Create React App - With CSS Modules",
55
"repository": "ro-savage/react-scripts-cssmodules",
6-
"license": "BSD-3-Clause",
6+
"license": "MIT",
77
"engines": {
88
"node": ">=6"
99
},
@@ -21,45 +21,46 @@
2121
"react-scripts": "./bin/react-scripts.js"
2222
},
2323
"dependencies": {
24-
"autoprefixer": "7.1.2",
25-
"babel-core": "6.25.0",
24+
"autoprefixer": "7.1.6",
25+
"babel-core": "6.26.0",
2626
"babel-eslint": "7.2.3",
2727
"babel-jest": "20.0.3",
28-
"babel-loader": "7.1.1",
29-
"babel-preset-react-app": "^3.0.3",
28+
"babel-loader": "7.1.2",
29+
"babel-preset-react-app": "^3.1.0",
3030
"babel-runtime": "6.26.0",
3131
"case-sensitive-paths-webpack-plugin": "2.1.1",
3232
"chalk": "1.1.3",
33-
"css-loader": "0.28.4",
33+
"css-loader": "0.28.7",
3434
"dotenv": "4.0.0",
35-
"eslint": "4.4.1",
35+
"eslint": "4.10.0",
3636
"eslint-config-react-app": "^2.0.1",
3737
"eslint-loader": "1.9.0",
38-
"eslint-plugin-flowtype": "2.35.0",
39-
"eslint-plugin-import": "2.7.0",
38+
"eslint-plugin-flowtype": "2.39.1",
39+
"eslint-plugin-import": "2.8.0",
4040
"eslint-plugin-jsx-a11y": "5.1.1",
41-
"eslint-plugin-react": "7.1.0",
42-
"extract-text-webpack-plugin": "3.0.0",
43-
"file-loader": "0.11.2",
41+
"eslint-plugin-react": "7.4.0",
42+
"extract-text-webpack-plugin": "3.0.2",
43+
"file-loader": "1.1.5",
4444
"fs-extra": "3.0.1",
4545
"html-webpack-plugin": "2.29.0",
4646
"jest": "20.0.4",
4747
"object-assign": "4.1.1",
4848
"postcss-flexbugs-fixes": "3.2.0",
49-
"postcss-loader": "2.0.6",
49+
"postcss-loader": "2.0.8",
5050
"promise": "8.0.1",
51-
"react-dev-utils": "^4.1.0",
52-
"style-loader": "0.18.2",
51+
"raf": "3.4.0",
52+
"react-dev-utils": "^4.2.1",
53+
"style-loader": "0.19.0",
5354
"sw-precache-webpack-plugin": "0.11.4",
54-
"url-loader": "0.5.9",
55-
"webpack": "3.5.1",
56-
"webpack-dev-server": "2.8.2",
57-
"webpack-manifest-plugin": "1.2.1",
55+
"url-loader": "0.6.2",
56+
"webpack": "3.8.1",
57+
"webpack-dev-server": "2.9.4",
58+
"webpack-manifest-plugin": "1.3.2",
5859
"whatwg-fetch": "2.0.3"
5960
},
6061
"devDependencies": {
61-
"react": "^15.5.4",
62-
"react-dom": "^15.5.4"
62+
"react": "^16.0.0",
63+
"react-dom": "^16.0.0"
6364
},
6465
"optionalDependencies": {
6566
"fsevents": "1.1.2"

0 commit comments

Comments
 (0)