当前位置: 首页 > 工具软件 > css-loader > 使用案例 >

窥探css-loader与style-loader的作用

朱俊雅
2023-12-01

前言

大家伙都清楚在使用webpack构建前端项目时都会使用到sass-loader、less-loader、postcss-loader、css-loader、style-loader,但这些loader在其中起到什么作用呢?本篇主要阐述css-loaderstyle-loader的作用和实现,加深对loader的理解。

css-loader

css-loader 会对 @import 和 url() 进行处理,就像 js 解析 import/require() 一样,默认生成一个数组存放存放处理后的样式字符串,并将其导出。

假如有三个样式文件:a.module.scssb.module.scssc.module.scss,它们之间的依赖关系是这样的:

// a.module.scss
@import './b.module.scss';

.container {
  width: 200px;
  height: 200px;
  background-color: antiquewhite;
}

// b.module.scss
@import url('./c.module.scss');

.text {
  font-size: 16px;
  color: #da2227;
  font-weight: bold;
}

// c.module.scss
.name {
  font-size: 16px;;
  color: #da7777;
  font-weight: bold;
}

index.jsx文件中引入它们

// index.jsx
import React from 'react';

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

const Index = () => {
  return <div className={styles.container}>
    <span className={styles.text}><span className={styles.name}>xxx,</span>hello world!!!</span>
  </div>
}

export default Index;

webpack.config.js构建脚本

// webpack.config.js
const path = require('path');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const webpack = require('webpack');

module.exports = {
  entry: {
    index: './src/index.jsx'
  },
  output: {
    filename: 'js/[name].js',
    path: path.resolve(__dirname, './dist'),
    library: 'MyComponent',
    libraryTarget: 'umd',
  },
  resolve: {
    extensions: ['.js', '.jsx', '.tsx'],
  },
  module: {
    rules: [
      { 
        test: /\.(js|jsx)$/, 
        exclude: /node_modules/, 
        loader: "babel-loader" 
      },
      {
        test: /\.(sa|sc|c)ss$/,
        use: [
          'style-loader',
          {
            loader: 'css-loader',
            options: {
              modules: false, // 禁止css modules
            }
          },
          'sass-loader'
        ]
      },
      { 
        test: /\.(jpg|jpeg|png|gif)$/, 
        use: ['url-loader'] 
      }
    ]
  },
  plugins: [
    new webpack.ProgressPlugin(),
    new CleanWebpackPlugin({
      cleanOnceBeforeBuildPatterns: ['dist']
    }),
  ],
}

.babelrc配置

// .babelrc
{
  "presets": [
      "@babel/preset-env",
      "@babel/preset-react"
  ],
  "plugins": [
      "@babel/plugin-proposal-class-properties"
  ]
}

package.json配置构建命令"build:dev": "webpack --mode none"。为了方便分析构建之后的代码,这里将mode设置为none

执行yarn build:dev构建,分析生成的文件

(1)a.module.scss使用@import引入了b.module.scss,被处理放入同一个模块的数组___CSS_LOADER_EXPORT___中并导出

(2)b.module.scss使用@import url()引入了c.module.scss,但c.module.scss被单独处理放入另一个模块的数组___CSS_LOADER_EXPORT___中并导出

(3)a.module.scssb.module.scss被处理放入一个模块数组,c.module.scss被单独处理放入另一个模块的数组,但是b.module.scssc.module.scss是由引入关系的,这个在构建后怎么关联依赖的呢?

a.module.scssb.module.scss被处理放入模块id12的数组,c.module.scss被处理放入模块id15的数组,模块id12的模块中导入了模块id15中的样式数组,并将其追加到模块id12的数组中,最后统一以数组__WEBPACK_DEFAULT_EXPORT__导出,css-loader处理到这一步就结束了

另外css-loader还提供其他的功能,比如css modules

css-loader导出方式

上面说到引入的样式都被转化成样式字符串放入模块数组中,这是默认的处理方式,其实还有另外两种。

配置项exportType允许导出样式为'array'、'string'或者 'css-style-sheet'可构造样式(即 CSSStyleSheet), 默认值:'array'

CSSStyleSheet 接口代表一个 CSS 样式表,并允许检查和编辑样式表中的规则列表。它从父类型 StyleSheet 继承属性和方法。

一个 CSS 样式表包含了一组表示规则的 CSSRule 对象。每条 CSS 规则可以通过与之相关联的对象进行操作,这些规则被包含在 CSSRuleList 内,可以通过样式表的 cssRules (en-US) 属性获取。

例如,CSSStyleRule 对象中的一条规则可能包含这样的样式:

h1, h2 {
  font-size: 16pt;
}

style-loader

style-loader的作用是把 CSS 插入到 DOM 中,就是处理css-loader导出的模块数组,然后将样式通过style标签或者其他形式插入到DOM中。

配置项injectType可配置把 styles 插入到 DOM 中的方式。

如果你想开发小程序或者了解更多小程序的内容,可以通过专业开发公司,来帮助你实现开发需求:厦门在乎科技-专注厦门小程序开发、APP开发、网站开发、H5小游戏开发

 类似资料: