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

Vite+TS项目中Module Federation集成Lit Element报错求助

Vite+TypeScript+Module Federation集成Lit Element时的导入错误

我在Vite+TypeScript项目中使用@originjs/vite-plugin-federation实现Module Federation与Lit Element的集成,但将远程组件导入宿主元素时遇到错误:

Cannot find module 'remoteApp/RemoteElement' or its corresponding type declarations.ts(2307)

以下是远程端和宿主端的相关代码:


远程端代码

组件文件:remote-element.ts

import { LitElement, html } from "lit";
import { customElement } from "lit/decorators.js";

@customElement("remote-element")
export class RemoteElement extends LitElement {
  render() {
    return html`<p>Remote Element</p>`;
  }
}

declare global {
  interface HTMLElementTagNameMap {
    "remote-element": RemoteElement;
  }
}

Vite配置:vite.config.ts

import federation from "@originjs/vite-plugin-federation";

export default {
  server: {
    port: 4300,
    strictPort: true,
  },
  preview: {
    port: 4300,
    strictPort: true,
  },
  plugins: [
    federation({
      name: "remote-app",
      filename: "remoteEntry.js",
      exposes: {
        "./remote-element": "./src/remote-element.ts",
      },
      shared: [],
    }),
  ],
};

TypeScript配置:tsconfig.json

{
  "compilerOptions": {
    "target": "ES2020",
    "experimentalDecorators": true,
    "useDefineForClassFields": false,
    "module": "ESNext",
    "lib": ["ES2020", "DOM", "DOM.Iterable"],
    "skipLibCheck": true,

    /* Bundler mode */
    "moduleResolution": "Bundler",
    "allowImportingTsExtensions": true,
    "isolatedModules": true,
    "moduleDetection": "force",
    "noEmit": true,

    /* Linting */
    "strict": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "noFallthroughCasesInSwitch": true,
    "noUncheckedSideEffectImports": true
  },
  "include": ["src"]
}

依赖配置:package.json

{
  "name": "remote",
  "private": true,
  "version": "0.0.0",
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "tsc && vite build",
    "preview": "vite preview"
  },
  "dependencies": {
    "lit": "^3.2.1"
  },
  "devDependencies": {
    "@originjs/vite-plugin-federation": "^1.3.6",
    "typescript": "~5.6.2",
    "vite": "^5.4.10"
  }
}

宿主端代码

组件文件:host-element.ts

import { LitElement, html } from "lit";
import { customElement } from "lit/decorators.js";

import RemoteElement from "remoteApp/RemoteElement";

@customElement("host-element")
export class HostElement extends LitElement {
  render() {
    return html` <RemoteElement></RemoteElement> `;
  }
}

declare global {
  interface HTMLElementTagNameMap {
    "host-element": HostElement;
  }
}

Vite配置:vite.config.ts

import federation from "@originjs/vite-plugin-federation";

export default {
  server: {
    port: 4200,
    strictPort: true,
  },
  plugins: [
    federation({
      name: "host-app",
      remotes: {
        remote_app: "http://localhost:4300/assets/remoteEntry.js",
      },
      shared: [],
    }),
  ],
};

TypeScript配置:tsconfig.json

{
  "compilerOptions": {
    "target": "ES2020",
    "experimentalDecorators": true,
    "useDefineForClassFields": false,
    "module": "ESNext",
    "lib": ["ES2020", "DOM", "DOM.Iterable"],
    "skipLibCheck": true,

    /* Bundler mode */
    "moduleResolution": "Bundler",
    "allowImportingTsExtensions": true,
    "isolatedModules": true,
    "moduleDetection": "force",
    "noEmit": true,

    /* Linting */
    "strict": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "noFallthroughCasesInSwitch": true,
    "noUncheckedSideEffectImports": true,
    "skipDefaultLibCheck": false
  },
  "include": ["src"]
}

依赖配置:package.json

{
  "name": "host",
  "private": true,
  "version": "0.0.0",
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "tsc && vite build",
    "preview": "vite preview"
  },
  "dependencies": {
    "lit": "^3.2.1"
  },
  "devDependencies": {
    "@originjs/vite-plugin-federation": "^1.3.6",
    "typescript": "~5.6.2",
    "vite": "^5.4.10"
  }
}

解决方案

1. 修正导入路径与Vite配置的一致性

  • 宿主端vite.config.ts中,remotes的键名要和导入的模块名一致,将remote_app改为remoteApp:
    remotes: {
      remoteApp: "http://localhost:4300/assets/remoteEntry.js",
    },
    
  • 远程端暴露的路径是./remote-element,宿主端只需导入模块触发自定义元素注册,无需导入类:
    // 替换原导入语句
    import "remoteApp/remote-element";
    

2. 修正模板中的自定义元素标签

自定义元素必须遵循小写加中划线的命名规范,模板中替换为:

<remote-element></remote-element>

3. 添加TypeScript类型声明

在宿主端创建类型声明文件(如src/types/remote-app.d.ts),补充远程模块类型:

declare module "remoteApp/remote-element" {
  import { LitElement } from "lit";
  export class RemoteElement extends LitElement {}

  declare global {
    interface HTMLElementTagNameMap {
      "remote-element": RemoteElement;
    }
  }
}

然后在tsconfig.json的include中添加类型文件目录:

"include": ["src", "src/types"]

4. 确认远程组件导出正确性

远程组件通过@customElement已完成全局注册,保持现有代码即可,无需额外默认导出。


内容的提问来源于stack exchange,提问作者S. DANIEL DEEPAK

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 06:23:09