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

React+Vite设计系统作为Git子模块导入时interface解析错误求助

解决Git子模块中React+Vite设计系统的TypeScript转译错误

问题描述

将基于React+Vite开发的设计系统作为Git子模块导入其他项目后,使用组件时抛出如下错误:

ERROR in ./packages/MightZord-DS/src/components/Switch/index.tsx 9:0

Module parse failed: The keyword 'interface' is reserved (9:0)
File was processed with these loaders:
 * ./node_modules/@pmmmwh/react-refresh-webpack-plugin/loader/index.js
 * ./node_modules/source-map-loader/dist/cjs.js
You may need an additional loader to handle the result of these loaders.
| import { FieldRow } from "../Field/styles";
| 
> interface SwitchFieldProps {
|     id: string;
|     label: string;

原因分析

当前设计系统的配置仅适用于本地开发预览:

  • tsconfig.json中noEmit: true,不会生成编译后的JS文件
  • Vite默认构建产物是面向浏览器的应用包,而非可被其他项目引用的库文件
  • 宿主项目(此处为Webpack环境)直接读取了未转译的TypeScript源码,但未配置处理该子模块目录下的TS/TSX文件,导致无法识别interface等TS语法

解决方案

方案1:调整设计系统配置,输出可引用的库产物

这是更规范的做法,让设计系统输出编译后的JS和类型文件,避免宿主项目处理TS源码。

  1. 修改tsconfig.json
    更新编译配置,开启类型声明生成,指定输出目录:
{
  "compilerOptions": {
    "target": "ESNext",
    "useDefineForClassFields": true,
    "lib": ["DOM", "DOM.Iterable", "ESNext"],
    "allowJs": false,
    "skipLibCheck": true,
    "esModuleInterop": false,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "module": "ESNext",
    "moduleResolution": "Node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": false, // 改为false,允许生成编译文件
    "declaration": true, // 生成.d.ts类型文件
    "declarationDir": "./dist", // 类型文件输出目录
    "outDir": "./dist", // JS文件输出目录
    "rootDir": "./src", // 源码根目录
    "jsx": "react"
  },
  "include": ["src"],
  "references": [{ "path": "./tsconfig.node.json" }]
}
  1. 修改vite.config.ts配置为库模式
    让Vite构建出适合被其他项目引用的库产物:
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'

export default defineConfig({
  plugins: [react()],
  build: {
    lib: {
      entry: './index.ts', // 入口文件
      name: 'MightZordDS',
      fileName: (format) => `mightzord-ds.${format}.js`,
    },
    rollupOptions: {
      // 排除宿主项目已有的依赖,避免重复打包
      external: ['react', 'react-dom', 'styled-components', '@radix-ui/react-switch', 'polished'],
      output: {
        // 为外部依赖指定全局变量(UMD格式需要)
        globals: {
          react: 'React',
          'react-dom': 'ReactDOM',
          'styled-components': 'styled',
          '@radix-ui/react-switch': 'RadixUISwitch',
          polished: 'Polished'
        },
      },
    },
  },
})
  1. 更新package.json
    添加入口字段,让其他项目能找到编译后的产物,同时取消私有限制:
{
  "name": "@magazord/mightzord-ds",
  "private": false, // 修改为false,允许外部引用
  "version": "0.0.1", // 更新版本号
  "type": "module",
  "main": "./dist/mightzord-ds.umd.js", // UMD格式入口
  "module": "./dist/mightzord-ds.es.js", // ES模块入口
  "types": "./dist/index.d.ts", // 类型声明入口
  "scripts": {
    "dev": "vite",
    "build": "tsc && vite build",
    "preview": "vite preview"
  },
  // ... 依赖部分保持不变
}
  1. 构建并提交产物
    执行npm run build生成dist目录,将dist目录提交到Git子模块仓库。之后宿主项目即可通过import { Switch } from '@magazord/mightzord-ds'引用组件,无需处理TS源码。

方案2:调整宿主项目Webpack配置(临时方案)

如果不想修改设计系统的构建流程,可让宿主项目的Webpack处理子模块中的TS/TSX文件:

  1. 安装依赖:
npm install typescript ts-loader --save-dev
  1. 修改宿主项目的webpack.config.js:
const path = require('path');

module.exports = {
  // ... 其他配置
  module: {
    rules: [
      // 新增处理TS/TSX的规则,包含子模块目录
      {
        test: /\.(ts|tsx)$/,
        include: [
          path.resolve(__dirname, 'src'),
          path.resolve(__dirname, 'packages/MightZord-DS') // 子模块路径
        ],
        use: 'ts-loader',
      },
    ],
  },
  resolve: {
    extensions: ['.ts', '.tsx', '.js', '.jsx'], // 添加TS扩展名
  },
};

内容的提问来源于stack exchange,提问作者Gabriel Schmidt Cordeiro

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 08:07:52