StencilJS构建Angular独立组件库时遇TS2307模块找不到错误
问题背景
基于Angular16+开发仅使用独立组件的项目,计划通过StencilJS的Web Components库构建可复用的Angular独立组件库。按照官方文档配置,将outputType设为'standalone'、outputTargets设为'dist-custom-elements'后,执行StencilJS构建时,生成的components.ts文件出现TypeScript错误TS2307: Cannot find module 'stencil-library/components' or its corresponding type declarations.,导致构建失败。
错误日志
Building entry point 'component-library' ------------------------------------------------------------------------------ ✖ Compiling with Angular sources in Ivy partial compilation mode. projects/component-library/src/lib/stencil-generated/components.ts:7:33 - error TS2307: Cannot find module 'stencil-library/components' or its corresponding type declarations. 7 import type { Components } from 'stencil-library/components'; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ projects/component-library/src/lib/stencil-generated/components.ts:9:58 - error TS2307: Cannot find module 'stencil-library/components/my-component.js' or its corresponding type declarations. 9 import { defineCustomElement as defineMyComponent } from 'stencil-library/components/my-component.js'; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ npm ERR! Lifecycle script `build` failed with error: npm ERR! Error: command failed
使用的依赖版本
"@stencil/angular-output-target": "^0.8.4", "@stencil/core": "^4.7.0", "@types/jest": "^29.5.6", "@types/node": "^16.18.11",
Stencil配置文件(stencil.config.ts)
import { Config } from '@stencil/core'; import { angularOutputTarget } from '@stencil/angular-output-target'; export const config: Config = { namespace: 'stencil-library', outputTargets: [ { type: 'dist-custom-elements', customElementsExportBehavior: 'single-export-module', }, angularOutputTarget({ componentCorePackage: 'stencil-library', outputType: 'standalone', directivesProxyFile: '../angular-workspace/projects/component-library/src/lib/stencil-generated/components.ts', directivesArrayFile: '../angular-workspace/projects/component-library/src/lib/stencil-generated/index.ts', }), ], };
生成的components.ts内容
/* tslint:disable */ /* auto-generated angular directive proxies */ import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, NgZone } from '@angular/core'; import { ProxyCmp } from './angular-component-lib/utils'; import type { Components } from 'stencil-library/components'; import { defineCustomElement as defineMyComponent } from 'stencil-library/components/my-component.js'; @ProxyCmp({ defineCustomElementFn: defineMyComponent, inputs: ['first', 'last', 'middle'] }) @Component({ selector: 'my-component', changeDetection: ChangeDetectionStrategy.OnPush, template: '<ng-content></ng-content>', // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property inputs: ['first', 'last', 'middle'], standalone: true }) export class MyComponent { protected el: HTMLElement; constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) { c.detach(); this.el = r.nativeElement; } } export declare interface MyComponent extends Components.MyComponent {}
补充说明
Angular库基于Angular18,Angular16版本也存在相同问题。文件结构包含独立的Stencil项目和Angular工作区,Stencil生成的组件代理文件位于Angular库的src/lib/stencil-generated目录下。
解决方案
1. 配置TypeScript路径映射
在Angular库的tsconfig.lib.json中添加路径映射,引导TypeScript找到Stencil生成的模块:
{ "compilerOptions": { // 保留原有配置 "paths": { "stencil-library/*": ["../../../../stencil-project/dist/custom-elements/*"] } } }
注意:路径需根据实际项目层级调整,确保指向Stencil项目dist/custom-elements目录。
2. 验证Stencil构建产物
确认Stencil构建后,dist/custom-elements目录下生成了components.d.ts类型文件及对应组件的JS文件。若未生成,检查dist-custom-elements输出目标的配置是否正确。
3. 调整componentCorePackage为本地路径(可选)
若Stencil库未发布至npm,仅本地使用,可将componentCorePackage设为相对路径:
angularOutputTarget({ componentCorePackage: '../../stencil-project/dist/custom-elements', // 保留其他配置 })
生成的代理文件会使用相对路径导入,避免模块解析错误。
4. 建立本地依赖链接
在Angular库的package.json中添加本地依赖,链接Stencil项目:
{ "dependencies": { "stencil-library": "file:../../stencil-project" } }
执行npm install让npm建立本地链接,确保TypeScript能正确解析模块。
内容的提问来源于stack exchange,提问作者Tisma

