样式隔离
要实现CSS样式隔离,可以采用以下几种方法。下面是每种方法的详细使用方式:
1. BEM(Block Element Modifier)
BEM是一种命名规范,通过给类名添加前缀和后缀来实现样式隔离。BEM的结构如下:
- Block:代表独立的功能块,例如
.button
- Element:代表块的组成部分,例如
.button__text
- Modifier:代表块或元素的不同状态或版本,例如
.button--primary
使用示例
<div class="button">
<span class="button__text">按钮</span>
</div>
.button {
background-color: blue;
color: white;
}
.button__text {
font-size: 16px;
}
.button--primary {
background-color: green;
}
2. CSS Modules
CSS Modules通过将每个CSS文件作为一个模块来实现样式隔离,每个类名在编译时会被转换成唯一的标识符。Rsbuild 中使用 css module
使用示例
- 创建CSS文件并命名为
styles.module.css
:
/* styles.module.css */
.button {
background-color: blue;
color: white;
}
- 在React组件中引入并使用:
import React from 'react';
import styles from './styles.module.css';
function App() {
return <button className={styles.button}>按钮</button>;
}
export default App;
3. CSS-in-JS
CSS-in-JS将样式直接写在JavaScript文件中,常用的库有 styled-components 、emotion 等。Rsbuild 中使用 css-in-js
使用示例
- 安装styled-components:
npm install styled-components
- 在React组件中使用:
import React from 'react';
import styled from 'styled-components';
const Button = styled.button`
background: blue;
color: white;
`;
function App() {
return <Button>按钮</Button>;
}
export default App;
4. Shadow DOM
Shadow DOM是 Web 组件技术的一部分,通过创建独立的DOM树来实现样式隔离。React 可以通过 react-shadow 使用 ShadowDOM。
使用示例
- 创建一个HTML模板:
<template id="my-component">
<style>
.button {
background: blue;
color: white;
}
</style>
<button class="button">按钮</button>
</template>
- 定义自定义元素并附加Shadow DOM:
class MyComponent extends HTMLElement {
constructor() {
super();
const shadow = this.attachShadow({ mode: 'open' });
const template = document.getElementById('my-component').content;
shadow.appendChild(template.cloneNode(true));
}
}
customElements.define('my-component', MyComponent);
- 在HTML中使用自定义元素:
<my-component></my-component>
5. Vue Scoped Styles
在Vue中,可以使用scoped
属性来实现组件级别的样式隔离。
使用示例
- 在Vue组件中定义样式:
<template>
<button class="button">按钮</button>
</template>
<style scoped>
.button {
background: blue;
color: white;
}
</style>
每种方法都有其适用场景和限制,开发者可以根据项目需求选择合适的样式隔离方案。
FAQ
为什么 Module Federation 不直接处理 css 样式隔离?
之所以目前未选择直接将 CSS 隔离放到 Module Federation 中主要有以下几个原因:
建议处理方式:
- 在模块或者子应用的生产者就将 CSS 进行处理,这样可以保证模块或者应用在任意环境运行执行结果都不会不符合预期
- 通过 CSS module、组件库前缀、统一组件库版本,来解决该问题
- 直接导出 shadowDOM 的组件给到其他业务使用