babel-preset-react-scope-style
v0.0.13
Published
A babel plugin that scope style for style files in react component
Downloads
181
Maintainers
Readme
babel-preset-react-scope-style
A babel plugin that scope style for style files in react component
中文说明
Installtion
npm install --save-dev babel-preset-react-scope-style
// or
yarn add -D babel-preset-react-scope-style
Config
babel.config.js:
module.exports = {
presets: [
...
['babel-preset-react-scope-style']
],
plugins: [
...
]
};
webpack.config.js:
{
module: {
rules: [
{
test: /\.css$/,
use: [
'css-loader',
'babel-preset-react-scope-style/loader',
...
]
},
{
test: /\.scss$/,
use: [
'css-loader',
'babel-preset-react-scope-style/loader',
...
]
},
{
test: /\.less$/,
use: [
'css-loader',
'babel-preset-react-scope-style/loader',
...
]
}
]
}
}
Supported Options
scopeRegx
Type: RegExp
Default: /(.(?:le|sc|sa|c)ss)(?[a-z]+)?$/
Description: A regular expression used to match style files that need to be processed. By default, it matches .less, .scss, .sass, and .css files and supports query parameters (e.g., ?scoped).
scope
Type: Boolean
Default: true
Description: Whether to enable scoped styling. If set to false, scoped styles will not be generated.
scopeFn
Type: (ext: string, query: string, options: { filename, source, scopeId, global, pkg }) => string
Default: null
Description: A custom function to modify the suffix and query parameters of imported style files.
scopePrefix
- Type: String
- Default: ''
- Description: The prefix for the generated scope hash string. For example, if set to 'v-', the generated hash string will look like v-xxxxxxxx.
scopeAttrs
- Type: Boolean
- Default: true
- Description: Whether to add scope attributes (e.g., data-v-xxxxxxxx) to the generated HTML elements. This helps with debugging and style overriding.
scopeAll
- Type: Boolean
- Default: false
- Description: Whether to generate scoped styles for all style files, not just those with the ?scoped query parameter.
scopeVersion
- Type: Boolean
- Default: false
- Description: Whether to include a version number in the generated scope hash string. This helps distinguish styles between different versions.
pkg
- Type: Object
- Default: null
- Description: A package information object, typically read from package.json. It provides additional information for generating the scope hash string.
classAttrs
- Type: Array
- Default: ['className']
- Description: The class attribute names used in the generated scoped styles. By default, the plugin processes the className attribute.
Example Configuration
module.exports = {
presets: [
[
'babel-preset-react-scope-style',
{
scopeRegx: /(\.(?:le|sc|sa|c)ss)(\?scoped)?$/,
scope: true,
// Change the suffix of imported .scss/.less files to .css
scopeFn: (filename, pkgName) => '.css',
scopePrefix: 'v-',
scopeAttrs: true,
scopeAll: false,
scopeVersion: true,
pkg: require('./package.json'),
classAttrs: ['className', 'dropdownClassName']
}
]
]
};
Usage
If a js/jsx file imports a style file with the ?scoped suffix, it means that scoped styles are enabled for that file. For example:
// test.js
import React from 'react';
import './test.scss?scoped';
class Test extends React.Component {
renderSome() {
return <div>
<button>button</button>
</div>
}
render() {
return <div className="a">
<a className="b">link</a>
{ this.renderSome() }
</div>
}
}
// test.scss
.a {
color: red;
}
.a .b {
color: green;
}
During the build process, a hash string v-xxxxxxxx
is automatically generated based on the project name (package.json -> name
) and file path, and applied to all className
attributes in the JSX. For example:
// test.js
import React from 'react';
import { Button } from 'antd';
import './test.scss?scoped';
class Test extends React.Component {
renderSome() {
return <div className="v-xxxxxxxx">
<Button className="v-xxxxxxxx">button1</Button>
</div>
}
render() {
return <div className="v-xxxxxxxx a">
<a className="v-xxxxxxxx b">link</a>
</div>
}
}
// test.scss
.a.v-xxxxxxxx {
color: red;
}
.a .b.v-xxxxxxxx {
color: green;
}
Recommendation
It is recommended that the scoped style
file name and the corresponding JS file name maintain a 'one-to-one' relationship. That is, if the JS file name istest.js
, the style file name istest.scss
。
Customize the hash generation location
By default, the hash string is generated for the last selector in the style file. If you want to customize the hash generation location, you can use the :scope
pseudo-class or >>>
. For example, if the style file is as follows:
// test.scss
.a {
color: red;
}
.a:scope .b {
color: green;
}
.a >>> .c {
color: blue;
}
The resulting style file will be:
// test.scss
.a.v-xxxxxxxx {
color: red;
}
.a.v-xxxxxxxx .b {
color: green;
}
.a.v-xxxxxxxx .c {
color: blue;
}
Partial Styles Without Generating Hash
In some usage scenarios, if you do not want to generate a hash scope for some styles, you can use the :global
pseudo-class. For example, if the style file is as follows:
// test.scss
.a {
color: red;
}
.a:scope .b {
color: green;
}
:global {
.a {
background: blue;
}
}
The generated style file will be:
// test.scss
.a.v-xxxxxxxx {
color: red;
}
.a.v-xxxxxxxx .b {
color: green;
}
.a {
background: blue;
}
Global Styles
A project generally contains some global style files that usually contain settings or utility style classes affecting the entire project. In cross-project integration, these global styles can easily lead to conflicts between projects. ?global-style
is designed to minimize this issue.
Usage
- Modify
babel.config.js
:
...
[
'babel-preset-react-scope-style',
{
scopeNamespace: 'demo' // configure the scope style namespace, such as `demo`
}
],
...
In the above configuration, scopeNamespace
is set to demo. The generated hash string will now be v-demo-xxxxxxxx
instead of v-xxxxxxxx
.
- Add
?global
to theimport
statement that references the global style:
// index.js
import '~/assets/styles/global.css?global';
....
Assume the global.css
file looks like this:
.something-class * {
box-sizing: border-box;
}
.something-class.fl {
float: left;
}
.something-class .fr {
float: right;
}
.something-class .fr:scope .dd {
color: red;
}
The final generated style file will look like this:
.something-class *[class*=v-demo-] {
box-sizing: border-box;
}
.something-class.fl[class*=v-demo-] {
float: left;
}
.something-class .fr[class*=v-demo-] {
float: right;
}
.something-class .fr[class*=v-demo-] .dd {
color: red;
}