>  기사  >  웹 프론트엔드  >  CSS를 모듈화해야 하는 이유에 대해 이야기해 볼까요? 모듈화를 구현하는 방법은 무엇입니까?

CSS를 모듈화해야 하는 이유에 대해 이야기해 볼까요? 모듈화를 구현하는 방법은 무엇입니까?

藏色散人
藏色散人앞으로
2021-10-25 16:37:581866검색

css "로컬" 스타일

sass를 사용하고 @import를 통해 CSS 모듈화 문제를 부분적으로 해결해야 합니다. @import ,部分解决的 css 模块化的问题。

由于 css 是全局的,在被引入的文件和当前文件出现重名的情况下,前者样式就会被后者覆盖。
在引入一些公用组件,或者多人协作开发同一页面的时候,就需要考虑样式会不会被覆盖,这很麻烦。

// file A
.name {
    color: red
}

// file B
@import "A.scss";
.name {
    color: green
}

css 全局样式的特点,导致 css 难以维护,所以需要一种 css “局部”样式的解决方案。
也就是彻底的 css 模块化,@import 进来的 css 模块,需要隐藏自己的内部作用域。

CSS Modules 原理

通过在每个 class 名后带一个独一无二 hash 值,这样就不有存在全局命名冲突的问题了。这样就相当于伪造了“局部”样式。

// 原始样式 styles.css
.title {
  color: red;
}

// 原始模板 demo.html
import styles from 'styles.css';

<h1 class={styles.title}>
  Hello World
</h1>


// 编译后的 styles.css
.title_3zyde {
  color: red;
}

// 编译后的 demo.html
<h1 class="title_3zyde">
  Hello World
</h1>

webpack 与 CSS Modules

webpack 自带的 css-loader 组件,自带了 CSS Modules,通过简单的配置即可使用。

{
    test: /\.css$/,
    loader: "css?modules&localIdentName=[name]__[local]--[hash:base64:5]"
}

命名规范是从 BEM 扩展而来。

  • Block: 对应模块名 [name]

  • Element: 对应节点名 [local]

  • Modifier: 对应节点状态 [hash:base64:5]

使用 __ 和 -- 是为了区块内单词的分割节点区分开来。
最终 class 名为 styles__title--3zyde

在生产环境中使用

在实际生产中,结合 sass 使用会更加便利。以下是结合 sass 使用的 webpack 的配置文件。

{
    test: /\.scss$/,
    loader: "style!css?modules&importLoaders=1&localIdentName=[name]__[local]--[hash:base64:5]!sass?sourceMap=true&sourceMapContents=true"
}

通常除了局部样式,还需要全局样式,比如 base.css 等基础文件。
将公用样式文件和组件样式文件分别放入到两个不同的目标下。如下。

.
├── app                      
│   ├── styles               # 公用样式
│   │     ├── app.scss       
│   │     └── base.scss      
│   │
│   └── components           # 组件
          ├── Component.jsx  # 组件模板
          └── Component.scss # 组件样式

然后通过 webpack 配置,将在 app/styles 文件夹的外的(exclude) scss 文件"局部"化。

{
    test: /\.scss$/,
    exclude: path.resolve(__dirname, 'app/styles'),
    loader: "style!css?modules&importLoaders=1&localIdentName=[name]__[local]--[hash:base64:5]!sass?sourceMap=true&sourceMapContents=true"
},
{
    test: /\.scss$/,
    include: path.resolve(__dirname, 'app/styles'),
    loader: "style!css?sass?sourceMap=true&sourceMapContents=true"
}

有时候,一个元素有多个 class 名,可以通过  join(" ")  或字符串模版的方式来给元素添加多个 class 名。

// join-react.jsx
<h1 className={[styles.title,styles.bold].join(" ")}>
  Hello World
</h1>

// stringTemp-react.jsx
<h1 className={`${styles.title} ${styles.bold}`}>
  Hello World
</h1>

如果只写一个 class 就能把样式定义好,那么最好把所有样式写在一个 class 中。
所以,如果我们使用了多个 class 定义样式,通常会带一些一些逻辑判断。这个时候写起来就会麻烦不少。

引入 classnames ,即可以解决给元素写多个 class 名的问题,也可以解决写逻辑判断的麻烦问题。

classNames('foo', 'bar'); // => 'foo bar'
classNames('foo', { bar: true }); // => 'foo bar'
classNames({ 'foo-bar': true }); // => 'foo-bar'
classNames({ 'foo-bar': false }); // => ''
classNames({ foo: true }, { bar: true }); // => 'foo bar'
classNames({ foo: true, bar: true }); // => 'foo bar'

// lots of arguments of various types
classNames('foo', { bar: true, duck: false }, 'baz', { quux: true }); // => 'foo bar baz quux'

// other falsy values are just ignored
classNames(null, false, 'bar', undefined, 0, 1, { baz: null }, ''); // => 'bar 1'

引入 CSS Modules 的样式模块,每个 class 每次都要写 styles.xxx 也是很麻烦,在《深入React技术栈》提到了 react-css-modules

CSS는 전역이므로 가져온 파일과 현재 파일의 이름이 같은 경우 전자 스타일이 후자로 덮어쓰여집니다.
일부 공개 컴포넌트를 도입할 때나 여러 사람이 협력하여 동일한 페이지를 개발할 때 스타일을 덮어쓸지 여부를 고려해야 하는데 이는 매우 번거로운 작업입니다.

rrreeeCSS 글로벌 스타일의 특성으로 인해 CSS를 유지 관리하기가 어렵기 때문에 CSS "로컬" 스타일에 대한 솔루션이 필요합니다.
즉, CSS 모듈화를 완료하려면 @import로 가져온 CSS 모듈은 자체 내부 범위를 숨겨야 합니다.

CSS 모듈의 원리
🎜각 클래스 이름 뒤에 고유한 해시 값을 추가하면 전역 이름 충돌 문제가 없습니다. 이는 "로컬" 스타일을 구축하는 것과 동일합니다. 🎜rrreee🎜webpack 및 CSS 모듈🎜🎜webpack 자체 css-loader 구성 요소에는 CSS 모듈이 포함되어 있어 간단한 구성을 통해 사용할 수 있습니다. 🎜rrreee🎜 명명 규칙은 BEM에서 확장되었습니다. 🎜
  • 🎜Block: 해당 모듈 이름 [name]🎜
  • 🎜Element: 해당 노드 이름 [local]🎜 li>
  • 🎜Modifier: 해당 노드 상태 [hash:base64:5]🎜
🎜 __ 및 --를 사용하면 블록 차별화에서 단어 노드를 분할하기 위한 것입니다. .
최종 클래스 이름은 styles__title--3zyde입니다. 🎜🎜프로덕션 환경에서 사용합니다🎜🎜실제 프로덕션에서는 sass와 함께 사용하는 것이 더 편리할 것입니다. 다음은 sass와 함께 사용되는 webpack 설정 파일입니다. 🎜rrreee🎜보통 로컬 스타일 외에도 base.css 및 기타 기본 파일과 같은 전역 스타일도 필요합니다.
공개 스타일 파일과 구성 요소 스타일 파일을 두 개의 다른 대상에 넣습니다. 다음과 같이. 🎜rrreee🎜그런 다음 webpack 구성을 사용하여 app/styles 폴더 외부의 scss 파일을 "현지화"하세요. 🎜rrreee🎜때때로 요소에 여러 클래스 이름이 있는 경우 join(" ") 또는 문자열 템플릿을 통해 요소에 여러 클래스 이름을 추가할 수 있습니다. 🎜rrreee🎜하나의 클래스만 작성하여 스타일을 정의할 수 있다면 모든 스타일을 하나의 클래스에 작성하는 것이 가장 좋습니다.
따라서 스타일을 정의하기 위해 여러 클래스를 사용하는 경우 일반적으로 논리적인 판단을 내리게 됩니다. 지금은 글을 쓰는 것이 훨씬 더 번거로울 것입니다. 🎜🎜클래스 이름을 도입하면 요소에 대해 여러 클래스 이름을 작성하는 문제와 논리적 판단을 작성하는 번거로운 문제를 해결할 수 있습니다. 🎜rrreee🎜CSS 모듈의 스타일 모듈을 소개하는데, 매번 클래스마다 styles.xxx를 작성하는 것도 매우 번거로운 작업입니다. "In-Deeps React Technology Stack"에서 react-css를 언급했습니다. -modules 라이브러리를 사용하여 코드 작성을 줄일 수 있습니다. 🎜🎜추천 학습: "🎜css 동영상 튜토리얼🎜"🎜🎜

위 내용은 CSS를 모듈화해야 하는 이유에 대해 이야기해 볼까요? 모듈화를 구현하는 방법은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 segmentfault.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제