mirror of
https://github.com/zhigang1992/create-react-app.git
synced 2026-04-30 18:32:33 +08:00
Update CSS Modules localIndetName (#4192)
* Update CSS Modules localIndetName * Add missing file to package * Correct regex * plz plz plz
This commit is contained in:
@@ -326,3 +326,40 @@ module.exports = {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
#### `getCSSModuleLocalIdent(context: Object, localIdentName: String, localName: String, options: Object): string`
|
||||
|
||||
Creates a class name for CSS Modules that uses either the filename or folder name if named `index.module.css`.
|
||||
|
||||
For `MyFolder/MyComponent.module.css` and class `MyClass` the output will be `MyComponent.module_MyClass__[hash]`
|
||||
For `MyFolder/index.module.css` and class `MyClass` the output will be `MyFolder_MyClass__[hash]`
|
||||
|
||||
```js
|
||||
const getCSSModuleLocalIdent = require('react-dev-utils/getCSSModuleLocalIdent');
|
||||
|
||||
// In your webpack config:
|
||||
// ...
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.module\.css$/,
|
||||
use: [
|
||||
require.resolve('style-loader'),
|
||||
{
|
||||
loader: require.resolve('css-loader'),
|
||||
options: {
|
||||
importLoaders: 1,
|
||||
modules: true,
|
||||
getLocalIdent: getCSSModuleLocalIdent,
|
||||
},
|
||||
},
|
||||
{
|
||||
loader: require.resolve('postcss-loader'),
|
||||
options: postCSSLoaderOptions,
|
||||
},
|
||||
],
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
37
packages/react-dev-utils/getCSSModuleLocalIdent.js
vendored
Normal file
37
packages/react-dev-utils/getCSSModuleLocalIdent.js
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const loaderUtils = require('loader-utils');
|
||||
|
||||
module.exports = function getLocalIdent(
|
||||
context,
|
||||
localIdentName,
|
||||
localName,
|
||||
options
|
||||
) {
|
||||
// Use the filename or folder name, based on some uses the index.js / index.module.css project style
|
||||
const fileNameOrFolder = context.resourcePath.endsWith('index.module.css')
|
||||
? '[folder]'
|
||||
: '[name]';
|
||||
// Create a hash based on a the file location and class name. Will be unique across a project, and close to globally unique.
|
||||
const hash = loaderUtils.getHashDigest(
|
||||
context.resourcePath + localName,
|
||||
'md5',
|
||||
'base64',
|
||||
5
|
||||
);
|
||||
// Use loaderUtils to find the file or folder name
|
||||
const className = loaderUtils.interpolateName(
|
||||
context,
|
||||
fileNameOrFolder + '_' + localName + '__' + hash,
|
||||
options
|
||||
);
|
||||
// remove the .module that appears in every classname when based on the file.
|
||||
return className.replace('.module_', '_');
|
||||
};
|
||||
@@ -19,6 +19,7 @@
|
||||
"eslintFormatter.js",
|
||||
"FileSizeReporter.js",
|
||||
"formatWebpackMessages.js",
|
||||
"getCSSModuleLocalIdent.js",
|
||||
"getProcessForPort.js",
|
||||
"ignoredFiles.js",
|
||||
"inquirer.js",
|
||||
|
||||
@@ -17,6 +17,7 @@ const InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin');
|
||||
const WatchMissingNodeModulesPlugin = require('react-dev-utils/WatchMissingNodeModulesPlugin');
|
||||
const eslintFormatter = require('react-dev-utils/eslintFormatter');
|
||||
const ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin');
|
||||
const getCSSModuleLocalIdent = require('react-dev-utils/getCSSModuleLocalIdent');
|
||||
const getClientEnvironment = require('./env');
|
||||
const paths = require('./paths');
|
||||
|
||||
@@ -269,7 +270,7 @@ module.exports = {
|
||||
options: {
|
||||
importLoaders: 1,
|
||||
modules: true,
|
||||
localIdentName: '[path]__[name]___[local]',
|
||||
getLocalIdent: getCSSModuleLocalIdent,
|
||||
},
|
||||
},
|
||||
{
|
||||
|
||||
@@ -19,6 +19,7 @@ const InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin');
|
||||
const SWPrecacheWebpackPlugin = require('sw-precache-webpack-plugin');
|
||||
const eslintFormatter = require('react-dev-utils/eslintFormatter');
|
||||
const ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin');
|
||||
const getCSSModuleLocalIdent = require('react-dev-utils/getCSSModuleLocalIdent');
|
||||
const paths = require('./paths');
|
||||
const getClientEnvironment = require('./env');
|
||||
|
||||
@@ -306,7 +307,7 @@ module.exports = {
|
||||
minimize: true,
|
||||
sourceMap: shouldUseSourceMap,
|
||||
modules: true,
|
||||
localIdentName: '[path]__[name]___[local]',
|
||||
getLocalIdent: getCSSModuleLocalIdent,
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -422,7 +423,7 @@ module.exports = {
|
||||
// having to parse `index.html`.
|
||||
new ManifestPlugin({
|
||||
fileName: 'asset-manifest.json',
|
||||
publicPath: publicPath
|
||||
publicPath: publicPath,
|
||||
}),
|
||||
// Generate a service worker script that will precache, and keep up to date,
|
||||
// the HTML & assets that are part of the Webpack build.
|
||||
|
||||
@@ -26,8 +26,11 @@ describe('Integration', () => {
|
||||
|
||||
expect(
|
||||
doc.getElementsByTagName('style')[0].textContent.replace(/\s/g, '')
|
||||
).to.match(/.+style_cssModulesInclusion__.+\{background:.+;color:.+}/);
|
||||
expect(
|
||||
doc.getElementsByTagName('style')[1].textContent.replace(/\s/g, '')
|
||||
).to.match(
|
||||
/.+__style-module___cssModulesInclusion+\{background:.+;color:.+}/
|
||||
/.+assets_cssModulesIndexInclusion__.+\{background:.+;color:.+}/
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@@ -7,7 +7,13 @@
|
||||
|
||||
import React from 'react';
|
||||
import styles from './assets/style.module.css';
|
||||
import indexStyles from './assets/index.module.css';
|
||||
|
||||
export default () => (
|
||||
<p className={styles.cssModulesInclusion}>CSS Modules are working!</p>
|
||||
<div>
|
||||
<p className={styles.cssModulesInclusion}>CSS Modules are working!</p>
|
||||
<p className={indexStyles.cssModulesInclusion}>
|
||||
CSS Modules with index are working!
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
.cssModulesIndexInclusion {
|
||||
background: darkblue;
|
||||
color: lightblue;
|
||||
}
|
||||
@@ -50,6 +50,7 @@
|
||||
"html-webpack-plugin": "2.30.1",
|
||||
"identity-obj-proxy": "3.0.0",
|
||||
"jest": "22.1.2",
|
||||
"loader-utils": "^1.1.0",
|
||||
"object-assign": "4.1.1",
|
||||
"postcss-flexbugs-fixes": "3.2.0",
|
||||
"postcss-loader": "2.0.10",
|
||||
|
||||
@@ -518,23 +518,23 @@ If you are concerned about using Webpack-specific semantics, you can put all you
|
||||
<!---
|
||||
## Adding a CSS Modules stylesheet
|
||||
|
||||
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 creating a unique classname of the format **[dir]\_\_[filename]___[classname]**.
|
||||
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 creating a unique classname of the format **[filename]\_[classname]\_\_[hash]**.
|
||||
|
||||
An advantage of this is the ability to repeat the same classname within many CSS files without worrying about a clash.
|
||||
|
||||
### `Button.module.css`
|
||||
|
||||
```css
|
||||
.button {
|
||||
padding: 20px;
|
||||
.error {
|
||||
background-color: red;
|
||||
}
|
||||
```
|
||||
|
||||
### `another-stylesheet.css`
|
||||
|
||||
```css
|
||||
.button {
|
||||
color: green;
|
||||
.error {
|
||||
color: red;
|
||||
}
|
||||
```
|
||||
|
||||
@@ -542,25 +542,27 @@ An advantage of this is the ability to repeat the same classname within many CSS
|
||||
|
||||
```js
|
||||
import React, { Component } from 'react';
|
||||
import './another-stylesheet.css'; // Import regular stylesheet
|
||||
import styles from './Button.module.css'; // Import css modules stylesheet as styles
|
||||
import './another-stylesheet.css'; // Import regular stylesheet
|
||||
|
||||
|
||||
class Button extends Component {
|
||||
render() {
|
||||
// You can use them as regular CSS styles
|
||||
return <div className={styles.button} />;
|
||||
// reference as a js object
|
||||
return <button className={styles.error}>Error Button</button>;
|
||||
}
|
||||
}
|
||||
```
|
||||
### `exported HTML`
|
||||
No clashes from other `.button` classnames
|
||||
No clashes from other `.error` class names
|
||||
|
||||
```html
|
||||
<div class="src__Button-module___button"></div>
|
||||
<!-- This button has red background but not red text -->
|
||||
<button class="Button_error_ax7yz"></div>
|
||||
```
|
||||
|
||||
**This is an optional feature.** Regular html stylesheets and js imported stylesheets are fully supported. CSS Modules are only added when explictly named as a css module stylesheet using the extension `.module.css`.
|
||||
--->
|
||||
-->
|
||||
|
||||
## Post-Processing CSS
|
||||
|
||||
|
||||
Reference in New Issue
Block a user