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

如何让Vite通过脚本生成嵌套模块并正确处理外部依赖?

解决Vite脚本批量构建库的两个问题

1. 保留嵌套目录结构生成产物

当前代码里entryFileNames: '[name].mjs'会丢失路径前缀——因为Rollup的[name]占位符默认只提取文件名(不含目录层级)。要生成build/parent/lib.mjs这种嵌套结构,只需修改entryFileNames,直接用原始模块名替换后缀即可:

entryFileNames: `${name.replace('.ts', '.mjs')}`

这样入口parent/lib.ts就会生成releases/tmp/parent/lib.mjs,自动保留原有的目录层级。

2. 让external正确识别嵌套依赖

Rollup的external默认匹配的是模块ID而非文件路径,直接传入libs数组可能无法匹配代码中的导入路径。可以改用函数形式的external,对导入路径做归一化处理后再判断:

首先把libs转换成绝对路径集合,方便后续匹配:

const libPaths = new Set(libs.map(name => path.resolve(__dirname, '..', name)))

然后在rollupOptions.external中使用匹配函数:

external: (source) => {
  // 将导入路径转为绝对路径,再判断是否属于外部依赖集合
  const resolvedSource = path.resolve(process.cwd(), source)
  return libPaths.has(resolvedSource)
}

修改后的完整代码

import path from 'path'
import { build } from 'vite'

// libs
const libs = ['parent/lib.ts']
// 转换为绝对路径集合,用于external匹配
const libPaths = new Set(libs.map(name => path.resolve(__dirname, '..', name)))

libs
  .map(name => [name, path.resolve(__dirname, '..', name)])
  .forEach(async ([name, entry]) => {
    await build({
      configFile: false,
      build: {
        target: "esnext",
        emptyOutDir: false,
        minify: false,
        lib: {
          entry,
          name,
          formats: ['es']
        },
        rollupOptions: {
          external: (source) => {
            const resolvedSource = path.resolve(process.cwd(), source)
            return libPaths.has(resolvedSource)
          },
          output: {
            entryFileNames: `${name.replace('.ts', '.mjs')}`,
            dir: 'releases/tmp'
          }
        }
      }
    })
  })

补充说明

如果代码中使用相对路径导入(比如import '../parent/lib.ts'),path.resolve(process.cwd(), source)会自动解析为绝对路径,和libPaths中的路径完成匹配;若需支持不带后缀的导入,可在匹配函数中给resolvedSource补充.ts等后缀后再判断。

内容的提问来源于stack exchange,提问作者Alex Craft

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 05:25:00