用 Loader 处理 CSS / 图片 / 资源模块

本节目标

样式是前端刚需。Webpack 处理 CSS 需要两个 loader 配合:

// webpack.config.js(片段)
module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/,
        // 先 css-loader 解析 CSS 为模块,再 style-loader 注入 <style>
        use: ['style-loader', 'css-loader'],
      },
    ],
  },
}
// src/index.js
import './style.css' // 现在 CSS 像模块一样被 import,页面会立刻有样式
console.log('样式已注入')

开发中 style-loader 把 CSS 塞进 <style> 标签最方便(改完热更新)。但生产环境更推荐把 CSS 抽成独立 .css 文件(并行加载、缓存更好),这时用 mini-css-extract-plugin 替代 style-loader:

const MiniCssExtractPlugin = require('mini-css-extract-plugin')
module.exports = {
  module: {
    rules: [
      { test: /\.css$/, use: [MiniCssExtractPlugin.loader, 'css-loader'] },
    ],
  },
  plugins: [new MiniCssExtractPlugin({ filename: 'styles.[contenthash].css' })],
}

图片 / 字体在 Webpack 5 不用再装 file-loader/url-loader,内置「资源模块(Asset Modules)」搞定:

module.exports = {
  module: {
    rules: [
      {
        test: /\.(png|jpe?g|gif|svg)$/,
        type: 'asset',          // 自动:小于 8KB 转 base64 内联,否则输出文件
        parser: { dataUrlCondition: { maxSize: 8 * 1024 } },
      },
    ],
  },
}
import logo from './logo.png' // logo 是打包后的 URL 字符串
document.querySelector('#app').innerHTML = `<img src="${logo}">`

type: 'asset' 让 Webpack 自己决定「小图内联成 base64、大图输出成文件」,一句配置替代了过去两个 loader,非常省心。

名词解释

css-loader:把 CSS 文件解析成 Webpack 能理解的模块(处理 @import、url() 等),但不负责把它显示出来。

style-loader:把 css-loader 处理完的样式,以 <style> 标签形式注入到 HTML <head>,让页面真正生效。

MiniCssExtractPlugin:生产环境用的「CSS 抽取器」,把 CSS 从 JS 里剥离、生成独立 .css 文件,利于缓存与并行加载。

资源模块(Asset Modules):Webpack 5 内置能力,type: 'asset' 自动处理图片/字体,小资源内联 base64、大资源输出文件,替代老式的 file-loader/url-loader。

课后练习

练习 1:开发环境用 style-loader、生产用 MiniCssExtractPlugin.loader,为什么分两套?

答案:开发时要「改 CSS 即时热更新」,style-loader 注入 <style> 最快;生产时要「CSS 独立成文件便于浏览器并行下载 + 长缓存」,抽取更优。两套是「开发体验 vs 线上性能」的取舍。

练习 2:type: 'asset' 里 maxSize: 8 * 1024 控制什么?

答案:控制「资源内联与否的临界值」。小于 8KB 的图片会被转成 base64 字符串内联进 JS/CSS(省一次请求),大于等于的则输出成独立文件(避免 JS 体积膨胀)。

总结

样式与图片这两类「前端日常」,本质都是「用对 loader / 模块类型把它变成可 import 的资源」:CSS 走 css-loader+style-loader(开发)或 MiniCssExtract(生产),图片走 Webpack5 的 asset 资源模块。我的建议——新手先用 style-loader 跑通,等要做生产优化了再切抽取插件,别在开发阶段就给自己加复杂度。下一节进入 Webpack 最迷人的部分:插件机制,以及你一直想学的「自己写一个插件」。