如何将带React绑定的Stencil组件发布到NPM并解决消费报错
问题根因
报错核心原因是你发布的React绑定包包含了未编译的TypeScript源码,且配置错误导致外部项目直接引入了src/components.ts文件。默认前端脚手架(如Create React App)不会转译node_modules内的TS文件,import type等TS专属语法也无法被JS解析器识别,因此出现模块解析失败的报错。
手动复制Stencil核心包的dist、loader文件夹的方式会导致版本不一致、依赖冗余,不适合公共包发布。
正确配置&发布步骤
1. 配置Stencil核心包
先处理原生Stencil项目的stencil.config.ts,确保开启了必要的输出项:
import { Config } from '@stencil/core'; export const config: Config = { namespace: 'ccp-ui', outputTargets: [ // 输出标准dist包 { type: 'dist', esmLoaderPath: '../loader', }, // 输出类型定义 { type: 'dist-types', }, // 输出自定义元素入口 { type: 'dist-custom-elements', }, ], };
配置核心包package.json的入口字段,确保发布后可以被正确引用:
{ "name": "ccp-ui", "version": "1.0.0", "main": "dist/index.cjs.js", "module": "dist/index.js", "types": "dist/types/index.d.ts", "files": ["dist/", "loader/"] }
完成后先将核心包发布到NPM。
2. 生成可独立发布的React绑定
使用官方@stencil/react-output-target插件生成绑定,配置时指定核心包名,不要用monorepo的相对路径引用:
// stencil.config.ts 中添加react输出配置 import { reactOutputTarget } from '@stencil/react-output-target'; export const config: Config = { // ...其他配置 outputTargets: [ reactOutputTarget({ // 指定你已经发布的Stencil核心包名 componentCorePackage: 'ccp-ui', // 绑定代码输出路径 outDir: '../ccp-ui-react/src', // 自动引入自定义元素定义,不需要用户手动注册 includeImportCustomElements: true, }), // ...其他output配置 ] }
3. 编译React绑定包
生成的绑定代码都是TS/TSX源码,必须编译为JS后再发布:
- 在React绑定包根目录添加
tsconfig.json配置:
{ "compilerOptions": { "target": "ES2015", "module": "ESNext", "jsx": "react", "declaration": true, "outDir": "./dist", "strict": true, "moduleResolution": "node", "skipLibCheck": true }, "include": ["src/**/*"], "exclude": ["node_modules"] }
- 配置React绑定包的
package.json:
{ "name": "ccp-ui-react", "version": "1.0.0", "main": "dist/index.js", "types": "dist/index.d.ts", "files": ["dist/"], "peerDependencies": { "react": "^17 || ^18", "react-dom": "^17 || ^18" }, "dependencies": { "ccp-ui": "^1.0.0" // 对应你发布的核心包版本 }, "scripts": { "build": "tsc" } }
- 执行
npm run build编译绑定代码,确认dist目录生成了编译后的JS和类型文件后再发布。
验证使用
外部项目安装后直接引入即可,不需要修改webpack配置、不需要eject:
import { MyComponent } from 'ccp-ui-react'; function App() { return <MyComponent someProp="test" /> }
内容的提问来源于stack exchange,提问作者TimTheEnchanter
相关产品推荐
相关产品推荐

