Skip to content

Commit 782961c

Browse files
committed
Merge branch 'local-2285' into chores/cra-1.0.7
2 parents c52a370 + a15df83 commit 782961c

File tree

11 files changed

+192
-29
lines changed

11 files changed

+192
-29
lines changed

packages/react-scripts/config/webpack.config.dev.js

Lines changed: 39 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,24 @@ const publicUrl = '';
3232
// Get environment variables to inject into our app.
3333
const env = getClientEnvironment(publicUrl);
3434

35+
// Options for PostCSS as we reference these options twice
36+
// Adds vendor prefixing to support IE9 and above
37+
const postCSSLoaderOptions = {
38+
ident: 'postcss', // https://webpack.js.org/guides/migrating/#complex-options
39+
plugins: () => [
40+
require('postcss-flexbugs-fixes'),
41+
autoprefixer({
42+
browsers: [
43+
'>1%',
44+
'last 4 versions',
45+
'Firefox ESR',
46+
'not ie < 9', // React doesn't support IE8 anyway
47+
],
48+
flexbox: 'no-2009',
49+
}),
50+
],
51+
};
52+
3553
// This is the development configuration.
3654
// It is focused on developer experience and fast rebuilds.
3755
// The production configuration is different and lives in a separate file.
@@ -215,8 +233,10 @@ module.exports = {
215233
// "style" loader turns CSS into JS modules that inject <style> tags.
216234
// In production, we use a plugin to extract that CSS to a file, but
217235
// in development "style" loader enables hot editing of CSS.
236+
// By default we support CSS Modules with the extension .modules.css
218237
{
219238
test: /\.css$/,
239+
exclude: /\.module\.css$/,
220240
use: [
221241
require.resolve('style-loader'),
222242
{
@@ -227,22 +247,28 @@ module.exports = {
227247
},
228248
{
229249
loader: require.resolve('postcss-loader'),
250+
options: postCSSLoaderOptions,
251+
},
252+
],
253+
},
254+
// Adds support for CSS Modules (https://github.com/css-modules/css-modules)
255+
// using the extension .module.css
256+
{
257+
test: /\.module\.css$/,
258+
use: [
259+
require.resolve('style-loader'),
260+
{
261+
loader: require.resolve('css-loader'),
230262
options: {
231-
ident: 'postcss', // https://webpack.js.org/guides/migrating/#complex-options
232-
plugins: () => [
233-
require('postcss-flexbugs-fixes'),
234-
autoprefixer({
235-
browsers: [
236-
'>1%',
237-
'last 4 versions',
238-
'Firefox ESR',
239-
'not ie < 9', // React doesn't support IE8 anyway
240-
],
241-
flexbox: 'no-2009',
242-
}),
243-
],
263+
importLoaders: 1,
264+
modules: true,
265+
localIdentName: '[name]__[local]___[hash:base64:5]',
244266
},
245267
},
268+
{
269+
loader: require.resolve('postcss-loader'),
270+
options: postCSSLoaderOptions,
271+
},
246272
],
247273
},
248274
// ** STOP ** Are you adding a new loader?

packages/react-scripts/config/webpack.config.prod.js

Lines changed: 49 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,24 @@ const extractTextPluginOptions = shouldUseRelativeAssetPaths
5454
{ publicPath: Array(cssFilename.split('/').length).join('../') }
5555
: {};
5656

57+
// Options for PostCSS as we reference these options twice
58+
// Adds vendor prefixing to support IE9 and above
59+
const postCSSLoaderOptions = {
60+
ident: 'postcss', // https://webpack.js.org/guides/migrating/#complex-options
61+
plugins: () => [
62+
require('postcss-flexbugs-fixes'),
63+
autoprefixer({
64+
browsers: [
65+
'>1%',
66+
'last 4 versions',
67+
'Firefox ESR',
68+
'not ie < 9', // React doesn't support IE8 anyway
69+
],
70+
flexbox: 'no-2009',
71+
}),
72+
],
73+
};
74+
5775
// This is the production configuration.
5876
// It compiles slowly and is focused on producing a fast and minimal bundle.
5977
// The development configuration is different and lives in a separate file.
@@ -210,8 +228,10 @@ module.exports = {
210228
// tags. If you use code splitting, however, any async bundles will still
211229
// use the "style" loader inside the async code so CSS from them won't be
212230
// in the main CSS file.
231+
// By default we support CSS Modules with the extension .modules.css
213232
{
214233
test: /\.css$/,
234+
exclude: /\.module\.css$/,
215235
loader: ExtractTextPlugin.extract(
216236
Object.assign(
217237
{
@@ -227,22 +247,38 @@ module.exports = {
227247
},
228248
{
229249
loader: require.resolve('postcss-loader'),
250+
options: postCSSLoaderOptions,
251+
},
252+
],
253+
},
254+
extractTextPluginOptions
255+
)
256+
),
257+
// Note: this won't work without `new ExtractTextPlugin()` in `plugins`.
258+
},
259+
// Adds support for CSS Modules (https://github.com/css-modules/css-modules)
260+
// using the extension .module.css
261+
{
262+
test: /\.module\.css$/,
263+
loader: ExtractTextPlugin.extract(
264+
Object.assign(
265+
{
266+
fallback: require.resolve('style-loader'),
267+
use: [
268+
{
269+
loader: require.resolve('css-loader'),
230270
options: {
231-
ident: 'postcss', // https://webpack.js.org/guides/migrating/#complex-options
232-
plugins: () => [
233-
require('postcss-flexbugs-fixes'),
234-
autoprefixer({
235-
browsers: [
236-
'>1%',
237-
'last 4 versions',
238-
'Firefox ESR',
239-
'not ie < 9', // React doesn't support IE8 anyway
240-
],
241-
flexbox: 'no-2009',
242-
}),
243-
],
271+
importLoaders: 1,
272+
minimize: true,
273+
sourceMap: true,
274+
modules: true,
275+
localIdentName: '[name]__[local]___[hash:base64:5]',
244276
},
245277
},
278+
{
279+
loader: require.resolve('postcss-loader'),
280+
options: postCSSLoaderOptions,
281+
},
246282
],
247283
},
248284
extractTextPluginOptions

packages/react-scripts/fixtures/kitchensink/integration/webpack.test.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,16 @@ describe('Integration', () => {
2020
).to.match(/#feature-css-inclusion\{background:.+;color:.+}/);
2121
});
2222

23+
it('css modules inclusion', async () => {
24+
const doc = await initDOM('css-modules-inclusion');
25+
26+
expect(
27+
doc.getElementsByTagName('style')[0].textContent.replace(/\s/g, '')
28+
).to.match(
29+
/\.style-module__cssModulesInclusion___.+\{background:.+;color:.+}/
30+
);
31+
});
32+
2333
it('image inclusion', async () => {
2434
const doc = await initDOM('image-inclusion');
2535

packages/react-scripts/fixtures/kitchensink/src/App.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,11 @@ class App extends Component {
8282
import('./features/webpack/CssInclusion').then(f =>
8383
this.setFeature(f.default));
8484
break;
85+
case 'css-modules-inclusion':
86+
import(
87+
'./features/webpack/CssModulesInclusion'
88+
).then(f => this.setFeature(f.default));
89+
break;
8590
case 'custom-interpolation':
8691
import(
8792
'./features/syntax/CustomInterpolation'
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/**
2+
* Copyright (c) 2015-present, Facebook, Inc.
3+
* All rights reserved.
4+
*
5+
* This source code is licensed under the BSD-style license found in the
6+
* LICENSE file in the root directory of this source tree. An additional grant
7+
* of patent rights can be found in the PATENTS file in the same directory.
8+
*/
9+
10+
import React from 'react';
11+
import styles from './assets/style.module.css';
12+
13+
export default () => (
14+
<p className={styles.cssModulesInclusion}>CSS Modules are working!</p>
15+
);
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/**
2+
* Copyright (c) 2015-present, Facebook, Inc.
3+
* All rights reserved.
4+
*
5+
* This source code is licensed under the BSD-style license found in the
6+
* LICENSE file in the root directory of this source tree. An additional grant
7+
* of patent rights can be found in the PATENTS file in the same directory.
8+
*/
9+
10+
import React from 'react';
11+
import ReactDOM from 'react-dom';
12+
import CssModulesInclusion from './CssModulesInclusion';
13+
14+
describe('css modules inclusion', () => {
15+
it('renders without crashing', () => {
16+
const div = document.createElement('div');
17+
ReactDOM.render(<CssModulesInclusion />, div);
18+
});
19+
});
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
.cssModulesInclusion {
2+
background: darkblue;
3+
color: lightblue;
4+
}

packages/react-scripts/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
"file-loader": "0.11.1",
4545
"fs-extra": "3.0.1",
4646
"html-webpack-plugin": "2.28.0",
47-
"identity-obj-proxy": "3.0.0",
47+
"identity-obj-proxy": "^3.0.0",
4848
"jest": "20.0.3",
4949
"json-loader": "0.5.4",
5050
"node-sass": "3.13.1",

packages/react-scripts/scripts/utils/createJestConfig.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,13 @@ module.exports = (resolve, rootDir, isEjecting) => {
4242
'^.+\\.css$': resolve('config/jest/cssTransform.js'),
4343
'^(?!.*\\.(js|jsx|css|json)$)': resolve('config/jest/fileTransform.js'),
4444
},
45-
transformIgnorePatterns: ['[/\\\\]node_modules[/\\\\].+\\.(js|jsx)$'],
45+
transformIgnorePatterns: [
46+
'[/\\\\]node_modules[/\\\\].+\\.(js|jsx)$',
47+
'^.+\\.module\\.css$',
48+
],
4649
moduleNameMapper: {
4750
'^react-native$': 'react-native-web',
51+
'^.+\\.module\\.css$': 'identity-obj-proxy',
4852
},
4953
};
5054
if (rootDir) {

packages/react-scripts/template/README.md

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,50 @@ In development, expressing dependencies this way allows your styles to be reload
409409

410410
If you are concerned about using Webpack-specific semantics, you can put all your CSS right into `src/index.css`. It would still be imported from `src/index.js`, but you could always remove that import if you later migrate to a different build tool.
411411

412+
## Adding a CSS Modules based stylesheet.
413+
414+
This project supports [CSS Modules](https://github.com/css-modules/css-modules) alongside regular stylesheets using the **[name].module.css** file naming convention. CSS Modules allows the scoping of CSS by automatically prefixing class names with a unique name and hash.
415+
416+
An advantge of this,is the ability to repeat the same classname within many CSS files without worrying about a clash.
417+
418+
### `Button.module.css`
419+
420+
```css
421+
.button {
422+
padding: 20px;
423+
}
424+
```
425+
426+
### `another-stylesheet.css`
427+
428+
```css
429+
.button {
430+
color: green;
431+
}
432+
```
433+
434+
### `Button.js`
435+
436+
```js
437+
import React, { Component } from 'react';
438+
import styles from './Button.module.css'; // Import stylesheet as styles
439+
440+
class Button extends Component {
441+
render() {
442+
// You can use them as regular CSS styles
443+
return <div className={styles.button} />;
444+
}
445+
}
446+
```
447+
### `exported HTML`
448+
No clashes from other `.button` classnames
449+
450+
```html
451+
<div class="Button-module__button___1o1Ru"></div>
452+
```
453+
454+
**This is an optional feature.** Regular stylesheets and imported stylesheets are fully supported. CSS Modules are only added when explicted named as a css module stylesheet.
455+
412456
## Post-Processing CSS
413457

414458
This project setup minifies your CSS and adds vendor prefixes to it automatically through [Autoprefixer](https://github.com/postcss/autoprefixer) so you don’t need to worry about it.

0 commit comments

Comments
 (0)