You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Rollup修改字体路径以适配打包后的目录结构?

Rollup字体资源路径解析问题

项目目录结构

src -
    |_...other dirs..
    |_styles
       |_fonts
          |_notosans.scss (字体导入位置)
          |_woff
             |_....my font assets..      

SCSS中的字体引用

@font-face {
  font-family: 'NotoSansKR';
  font-weight: 900;
  font-display: swap;
  src: local('NotoSansKR Black'),
    url('./woff/NotoSansKR-Black.woff') format('woff');
}

当前Rollup配置

import commonjs from '@rollup/plugin-commonjs';
import typescript from '@rollup/plugin-typescript';
import dts from 'rollup-plugin-dts';
import json from '@rollup/plugin-json';
import postcss from 'rollup-plugin-postcss';
import copy from 'rollup-plugin-copy';
import peerDepsExternal from 'rollup-plugin-peer-deps-external';
import alias from '@rollup/plugin-alias'
import pkg from './package.json';

export default [
  {
    input : "src/index.ts",
    output: [
      {
        file: pkg.main,
        format: 'cjs',
        sourcemap: true
      },
      {
        file: pkg.module,
        format: 'esm',
        sourcemap: true
      }
    ],
    plugins: [
      peerDepsExternal(['react', 'react-dom', 'styled-components' ,'lottie-web']),
      commonjs({
        include: ['./src/index.ts', 'node_modules/**']
      }),

      typescript({ tsconfig: './tsconfig.json' }),
      alias({
        entries: [
          {
            find : '@assets',
            replacement: './src/assets'
          }
        ]
      }),
      json(),
      copy({
        targets: [
            // 复制字体资源到目标目录
            { src: "src/styles/fonts/woff", dest: "dist/assets" },
        ],
      }),
      postcss(),
    ]
  },
  {
    input: "dist/esm/types/index.d.ts",
    output: [{file : "dist/index.d.ts" , format: "esm"}],
    plugins: [dts()],
    external : [/\.(scss|css)$/]
  }
]

期望的dist结构

dist
  |_assets - woff - my fonts..
  |_cjs 
  |_esm
  ...

问题

字体资源已成功复制到dist/assets/woff,但SCSS编译后的字体引用路径未自动更新,导致路径错误。需要通过Rollup配置解决,不使用CDN或link标签方案。


解决方案

核心是通过配置rollup-plugin-postcss的路径重写能力,自动调整字体引用路径以匹配打包后的目录结构。

步骤1:安装postcss-url插件

该插件用于处理CSS中的资源路径转换:

npm install postcss-url --save-dev

步骤2:修改Rollup中的postcss配置

更新rollup-plugin-postcss的配置,添加postcss-url并设置路径转换规则:

// 导入postcss-url
import postcssUrl from 'postcss-url';

// 在plugins数组中修改postcss配置
postcss({
  plugins: [
    postcssUrl({
      url: (asset) => {
        // 匹配字体文件路径并转换
        if (asset.url.includes('./woff/')) {
          // 转换为相对于打包后文件的路径:../assets/woff/[字体文件名]
          // 适配cjs/esm目录到assets目录的层级关系
          return `../assets/woff/${asset.url.split('./woff/')[1]}`;
        }
        return asset.url;
      }
    })
  ],
  // 可选:若需将CSS提取为单独文件,打开下方注释
  // extract: true,
}),

完整修改后的Rollup配置片段

// ...其他导入
import postcssUrl from 'postcss-url';

export default [
  {
    input : "src/index.ts",
    output: [
      {
        file: pkg.main,
        format: 'cjs',
        sourcemap: true
      },
      {
        file: pkg.module,
        format: 'esm',
        sourcemap: true
      }
    ],
    plugins: [
      peerDepsExternal(['react', 'react-dom', 'styled-components' ,'lottie-web']),
      commonjs({
        include: ['./src/index.ts', 'node_modules/**']
      }),
      typescript({ tsconfig: './tsconfig.json' }),
      alias({
        entries: [
          {
            find : '@assets',
            replacement: './src/assets'
          }
        ]
      }),
      json(),
      copy({
        targets: [
            { src: "src/styles/fonts/woff", dest: "dist/assets" },
        ],
      }),
      postcss({
        plugins: [
          postcssUrl({
            url: (asset) => {
              if (asset.url.includes('./woff/')) {
                return `../assets/woff/${asset.url.split('./woff/')[1]}`;
              }
              return asset.url;
            }
          })
        ],
        // 若项目需提取独立CSS文件,打开此注释
        // extract: true,
      }),
    ]
  },
  // ...dts配置部分保持不变
]

原理说明

postcss-url会遍历CSS中所有url()引用,将原路径./woff/xxx.woff转换为../assets/woff/xxx.woff,该路径相对于打包后cjs/esm目录下的样式文件(或注入到JS中的样式字符串),可正确指向dist/assets/woff中的字体资源。

内容的提问来源于stack exchange,提问作者Justin Seo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 10:53:17