css-loader常用配置项

1、importLoaders

:::info 用于配置「css-loader 作用于 @import 的资源之前」有多少个 loader。
这个什么意思呢?
importLoaders / 0 => 无 loader(默认); 1 => sass-loader; 2 => postcss-loader, sass-loader ::: 看个例子
image.png

  1. body {
  2. .abc {
  3. background: red;
  4. }
  5. }
  1. @import './avatar.scss';
  2. body {
  3. .avatar {
  4. width:150px;
  5. height: 150px;
  6. transform:translate(100px,100px);
  7. }
  8. }
  1. import avatar from './avatar.jpg'
  2. import './index.scss'
  3. var img = new Image();
  4. img.src = avatar;
  5. img.classList.add('avatar');
  6. var root = document.getElementById('root');
  7. root.append(img)
  1. const path = require('path')
  2. module.exports = {
  3. mode: 'development',
  4. entry: {
  5. main: './src/index.js'
  6. },
  7. module: {
  8. rules:[
  9. {
  10. test: /\.(jpg|png|gif)$/,
  11. use:{
  12. loader: 'url-loader',
  13. options: {
  14. name:'[name]_[hash].[ext]',
  15. outputPath: 'images/',
  16. limit: 2048 // 2kb
  17. }
  18. }
  19. },
  20. {
  21. test: /\.scss$/,
  22. use:[
  23. 'style-loader',
  24. // 如果要使用一个loader的配置项,可以换成对象的写法
  25. {
  26. loader:'css-loader',
  27. options: {
  28. importLoaders: 2
  29. }
  30. },
  31. 'sass-loader',
  32. 'postcss-loader'
  33. ]
  34. }
  35. ]
  36. },
  37. output: {
  38. filename: 'bundle.js',
  39. path: path.resolve(__dirname, 'dist')
  40. }
  41. }

我们通过上面的代码谈谈importLoaders的作用

  1. 首先,我们的index.js 引入了index.scss文件。
  2. 那么webpack打包的时候,js里面引入的scss文件,会依次调用postcss-loader、sass-loader、css-loader和style-loader.
  3. 但是,他打包index.scss文件的时候,发现他额外又引入了avatar.scss. 那么有可能在打包的时候就不再走postcss-loader和sass-loader了。而是直接走css-loader。
  4. 如果我们希望在index.scss文件,引入的avatar.scss文件也调用postcss-loader、sass-loader,那就使用importLoaders:2

2、css打包的模块化

:::info 什么意思?
在我们写css的时候,有时我们会希望样式是只能在当前页面或者说模块生效,而不是全局生效。
那么就需要css模块化 :::

首先看一个例子
结构
新增一个createAvatar.js,用来创建图片
image.png

import avatar from './avatar.jpg'

function createAvatar(){
  var img = new Image();
  img.src = avatar;
  img.classList.add('avatar');

  var root = document.getElementById('root');
  root.append(img)
}

export default createAvatar

这里的代码可以创建两个图片

import avatar from './avatar.jpg'
import './index.scss'
import createAvatar from "./createAvatar";

createAvatar();

var img = new Image();
img.src = avatar;
img.classList.add('avatar');

var root = document.getElementById('root');
root.append(img)

const path = require('path')
module.exports = {
  mode: 'development',
  entry: {
    main: './src/index.js'
  },
  module: {
    rules:[
      {
        test: /\.(jpg|png|gif)$/,
        use:{
          loader: 'url-loader',
          options: {
            name:'[name]_[hash].[ext]',
            outputPath: 'images/',
            limit: 2048 // 2kb
          }
        }
      },
      {
        test: /\.scss$/,
        use:[
          'style-loader', 
          // 如果要使用一个loader的配置项,可以换成对象的写法
          {
            loader:'css-loader',
            options: {
              importLoaders: 2
            }
          },
          'sass-loader',
          'postcss-loader'
        ]
      }
    ]
  },
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist')
  }
}

我们看看结果,两张照片都出来,而且样式都应用上了 :::warning 这就说明了一个问题,我们当前的样式是全局的。 ::: image.png

那么如何修改成局部样式

:::info 参数 modules 会启用 CSS 模块规范 :::

import avatar from './avatar.jpg'
// 修改
// import './index.scss'
import style from './index.scss'
import createAvatar from "./createAvatar";

createAvatar();

var img = new Image();
img.src = avatar;
// 修改这里的类
img.classList.add(style.avatar);

var root = document.getElementById('root');
root.append(img)

const path = require('path')
module.exports = {
  mode: 'development',
  entry: {
    main: './src/index.js'
  },
  module: {
    rules:[
      {
        test: /\.(jpg|png|gif)$/,
        use:{
          loader: 'url-loader',
          options: {
            name:'[name]_[hash].[ext]',
            outputPath: 'images/',
            limit: 2048 // 2kb
          }
        }
      },
      {
        test: /\.scss$/,
        use:[
          'style-loader', 
          // 如果要使用一个loader的配置项,可以换成对象的写法
          {
            loader:'css-loader',
            options: {
              importLoaders: 2,
              // 开启css的模块化打包
              modules: true
            }
          },
          'sass-loader',
          'postcss-loader'
        ]
      }
    ]
  },
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist')
  }
}

这时候我们可以发现,createAvatar.js中的图片并没有添加到样式。
证明现在的样式已经是模块化了。
image.png

3、如何打包字体文件

:::info webpack5 已经内部解析了结尾是ttf, woff, woff2等图标文件, 即使没有对些文件做打包配置, 也可以正常的去打包 :::

结构
iconfont.ttf、 iconfont.woff、 iconfont.woff2是从阿里图标下载下来的文件
image.png

@font-face {
  font-family: "iconfont"; /* Project id 2281304 */
  // 稍微修改这里的地址
  src: url('./font/iconfont.woff2?t=1655369441508') format('woff2'),
       url('./font/iconfont.woff?t=1655369441508') format('woff'),
       url('./font/iconfont.ttf?t=1655369441508') format('truetype');
}

.iconfont {
  font-family: "iconfont" !important;
  font-size: 16px;
  font-style: normal;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

.iconxinheart118:before {
  content: "\e755";
}

index.js使用图标

var root = document.getElementById('root');
import './index.scss'

root.innerHTML = '<div class="iconfont iconxinheart118"></div>'

就可以直接打包了
image.png
打包后的这些文件它可以直接识别。
image.png

:::info 但是,在旧的webpack版本中,他是不识别的,我们就需要使用file-loader进行打包 :::


const path = require('path')
module.exports = {
  mode: 'development',
  entry: {
    main: './src/index.js'
  },
  module: {
    rules:[
      {
        test: /\.(jpg|png|gif)$/,
        use:{
          loader: 'url-loader',
          options: {
            name:'[name]_[hash].[ext]',
            outputPath: 'images/',
            limit: 2048 // 2kb
          }
        }
      },
      {
        test: /\.(woff2|woff|ttf)$/,
        use:{
          loader: 'flie-loader',
        }
      },
      {
        test: /\.scss$/,
        use:[
          'style-loader', 
          // 如果要使用一个loader的配置项,可以换成对象的写法
          {
            loader:'css-loader',
            options: {
              importLoaders: 2,
              // 开启css的模块化打包
              modules: true
            }
          },
          'sass-loader',
          'postcss-loader'
        ]
      }
    ]
  },
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist')
  }
}

知识补充

管理资源
css-loader
scss-loader
style-loader
postcss-loader