天天看點

Webpack: CSS 到 Sass/Scss 與 CSS ModuleWebpack: CSS 到 Sass/Scss 與 CSS Module前言正文結語其他資源

Webpack: CSS 到 Sass/Scss 與 CSS Module

文章目錄

  • Webpack: CSS 到 Sass/Scss 與 CSS Module
  • 前言
  • 正文
    • 1. 在 JS 中引入 CSS:style-loader、css-lodaer
    • 2. 從 CSS 進階到 SCSS:sass-loader + node-sass
    • 3. CSS Module 實作命名空間隔離:css-loader
      • 3.1 Typescript 場景下使用 CSS Module
    • Bonus: 踩坑記錄
  • 結語
  • 其他資源
    • 參考連接配接
    • 完整代碼示例

前言

今天給大家分享的是關于在 webpack 場景下使用 SCSS 并加上 CSS Module 的配置方法

正文

之前有過幾篇關于 webpack 的介紹,這裡就預設大家都對 webpack 有初步的了解了(本篇主要會用到 loader 的部分)

1. 在 JS 中引入 CSS:style-loader、css-lodaer

第一部分先從基本的來,在不直接将 css 寫入 html 的場景下,我們就需要将 css 檔案作為一個獨立的 module 由 webpack 解析并插入,這時候就需要

style-loader

css-loader

  • 安裝依賴
$ yarn add style-loader css-lodaer -D
           
  • webpack.config.js

const config = {
  // ...
  module: {
    rules: [
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader'],
      },
    ]
  },
  // ...
}
           

接下來我們就可以直接在 JS 檔案内引入(以 React 為例)

  • /src/layouts/Test1/index.css

.test1 h2::before {
  content: '<t1>';
}
           
  • /src/layouts/Test1/index.tsx

import React from 'react';

import './index.css';

const Test1 = () => {
  return (
    <div className="test1">
      <h2>Test1</h2>
    </div>
  );
};

export default Test1;
           

效果如下

Webpack: CSS 到 Sass/Scss 與 CSS ModuleWebpack: CSS 到 Sass/Scss 與 CSS Module前言正文結語其他資源

2. 從 CSS 進階到 SCSS:sass-loader + node-sass

接下來 css 越寫越多,可能就有點不太好用了,是以接下來我們選擇上 Sass/Scss(當然你比較喜歡 Less 也是差不多的)

  • 安裝依賴
$ yarn add sass-loader node-sass -D
           
  • webpack.config.js

const config = {
  // ...
  module: {
    rules: [
      {
        test: /\.scss$/,
        use: ['style-loader', 'css-loader', 'sass-loader'],
      },
    ]
  },
  // ...
}
           
  • /src/layouts/Test2/index.scss

.test2 h2::before {
  content: '<t2>';
}
           
  • /src/layouts/Test2/index.tsx

import React from 'react';

import './index.scss';

const Test2 = () => {
  return (
    <div className="test2">
      <h2>Test2</h2>
    </div>
  );
};

export default Test2;
           

效果如下

Webpack: CSS 到 Sass/Scss 與 CSS ModuleWebpack: CSS 到 Sass/Scss 與 CSS Module前言正文結語其他資源

3. CSS Module 實作命名空間隔離:css-loader

然而 scss 實際上隻是一種 css 文法上的增強,但是依舊會産生命名沖突的問題,這時候我們就可以選擇使用 CSS Module 的特性(實際上 css-loader 已經給出相關的配置屬性,是以并不需要額外的 loader)

  • webpack.config.js

const config = {
  // ...
  module: {
    rules: [
      {
        test: /(\.module)?.(sass|scss)$/,
        use: [
          'style-loader',
          {
            loader: 'css-loader',
            options: {
              modules: {
                localIdentName: '[path][name]__[local]--[hash:base64:5]',
              },
              sourceMap: true,
            },
          },
          'sass-loader',
        ],
      },
    ]
  },
  // ...
}
           
  • /src/layouts/Test3/index.scss

.test3 h2::before {
  content: '<t3>';
}
           
  • /src/layouts/Test3/index.tsx

import React from 'react';

import styles from './index.module.scss';

console.log('styles', styles);

const Test3 = () => {
  return (
    <div className={styles.test3}>
      <h2>Test3</h2>
    </div>
  );
};

export default Test3;
           
Webpack: CSS 到 Sass/Scss 與 CSS ModuleWebpack: CSS 到 Sass/Scss 與 CSS Module前言正文結語其他資源

這時候我們可以看到,css 的名字被加上了目錄資訊甚至還有 hash 值,使得多個檔案之間的 css 幾乎不可能重名

3.1 Typescript 場景下使用 CSS Module

由于使用 CSS Module 之後,我們需要使用

才能擷取正确的樣式名稱,但是 ts 是看不懂 .scss 字尾的檔案的,這時候我們就可以在 src 目錄下建立一個

styles.d.ts

的類型聲明檔案

  • styles.d.ts

declare module '*.css' {
  const styles: { readonly [key: string]: string };
  export default styles;
}

declare module '*.scss' {
  const styles: { readonly [key: string]: string };
  export default styles;
}
           

如此一來 TS 就不會再報錯了

Bonus: 踩坑記錄

如果你在配置的過程中遇到一堆奇奇怪怪的報錯,以下是我踩過的幾個坑可以檢查一下是不是有相同的問題:

  • 沒有安裝

    node-sass

    :要解析 sass/scss 除了 sass-loader 之外,還需要 node-sass 解析器才能正确解析内容
  • loader 順序:老生常談了,由後向前
  • 多個相似配置:有一個問題是 scss 不能在同一個項目内重複定義規則,也就是 不可以決定一些用 CSS loader,一些不用,不然可能會産生一堆看不懂的報錯
  • node-sass 下載下傳有夠慢:參考連結裡面有關于配置 yarn 源倉庫的方法

結語

本篇就到此結束,其實就是一些關于 webpack 的配置手段,供大家參考。

其他資源

參考連接配接

Title Link
css-loader - Webpack 官方 https://webpack.js.org/loaders/css-loader/
devtool - Webpack 官方 https://webpack.js.org/configuration/devtool/
CSS Modules 用法教程 - 阮一峰 http://www.ruanyifeng.com/blog/2016/06/css_modules.html
Webpack基于baseUrl和paths引入子產品 https://juejin.cn/post/6901081123078537224
typescript項目css modules https://segmentfault.com/a/1190000021684206
yarn配置阿裡源 https://blog.csdn.net/qq_19107011/article/details/97992167

完整代碼示例

https://github.com/superfreeeee/Blog-code/tree/main/front_end/webpack/webpack_scss_css_module