React 输出目标出现 StencilJS 错误 - 您可能需要一个额外的加载器来处理这些加载器的结果

StencilJS error with React output target - You may need an additional loader to handle the result of these loaders

我正在 Stencil 中为自定义设计系统创建一些基本元素。我创建了一些基本组件,它们可以作为自定义元素单独使用,但在用作 React 组件时会抛出错误。

我通过在 stencil.config.ts 中包含 @stencil/react-output-target 通过 Stencil 生成了 React 组件。

reactOutputTarget({
      componentCorePackage: '@sr-design-system/simple-stencil-demo',
      proxiesFile: './react/src/components/index.ts',
      includeImportCustomElements: true
    }),

然后我将所有组件(自定义元素和 React)上传到私有 npm 包并将它们安装在一个单独的项目中。自定义元素似乎工作正常,但使用 React 元素时出现以下错误。

ERROR in ./node_modules/@sr-design-system/simple-stencil-demo/react/src/index.ts 6:12
Module parse failed: Unexpected token (6:12)
File was processed with these loaders:
 * ./node_modules/source-map-loader/dist/cjs.js
You may need an additional loader to handle the result of these loaders.
| import { createReactComponent } from './react-component-lib';
|
> import type { JSX } from '@sr-design-system/simple-stencil-demo/';
|
| import { defineCustomElement as defineSrText } from '@sr-design-system/simple-stencil-demo/dist/components/sr-text';
 @ ./src/App.jsx 7:0-73
 @ ./src/index.jsx 7:0-24 12:33-36

webpack 5.65.0 compiled with 1 error and 1 warning in 63 ms

几天来我一直被这个问题困扰。知道解决方案是什么吗?

===tsconfig.json===

{
  "compilerOptions": {
    "allowSyntheticDefaultImports": true,
    "allowUnreachableCode": false,
    "declaration": true,
    "experimentalDecorators": true,
    "forceConsistentCasingInFileNames": true,
    "lib": ["dom", "es2017"],
    "module": "es2015",
    "moduleResolution": "node",
    "pretty": true,
    "removeComments": false,
    "strictPropertyInitialization": false,
    "target": "es2017",
    "baseUrl": ".",
    "paths": {
      "@srds/react": ["./react"]
    },
    "jsx": "react",
    "jsxFactory": "h"
  },
  "include": ["src"]
}

===stencil.config.ts===

import { Config } from '@stencil/core';
import { reactOutputTarget } from '@stencil/react-output-target';

export const config: Config = {
  namespace: 'simple-stencil-demo',
  bundles: [{ components: ['sr-text'] }, { components: ['text-demo'] }],
  outputTargets: [
    reactOutputTarget({
      componentCorePackage: '@sr-design-system/simple-stencil-demo',
      proxiesFile: './react/src/components/index.ts',
      includeImportCustomElements: true,
    }),
    {
      type: 'dist',
      esmLoaderPath: './loader',
    },
    {
      type: 'dist-custom-elements',
    },
    {
      type: 'docs-readme',
    },
    {
      type: 'www',
      serviceWorker: null, // disable service workers
    },
  ],
  buildEs5: 'prod',
};

我明白是什么问题了。出于某种原因,每次 运行 npm run build.

时都没有为我生成 dist 文件夹

有时会生成,有时不会。我相信这是由于我的组件代码中的一些错误导致的,这些错误无声地失败了。所以现在我每次构建库时都会检查 dist 文件夹。

在我最后的工作尝试中,我按照 Stencil 团队在 documentation.

中的建议采用了 monorepo 方法

以下是我为带有 React 输出的基本 Stencil 库执行的所有步骤:

  • 创建单一仓库
  • 创建模板库
    • 使用 npx stencil generate
    • 生成组件
    • 将 package.json 中的名称更新为 MY_LIBRARY
    • npm i @stencil/react-output-target
    • 将 React Wrapper 功能添加到 stencil.config.ts
    react({
       componentCorePackage: 'MY_LIBRARY',
       proxiesFile: '../MY_REACT_LIBRARY/src/components/stencil-generated/index.ts',
       includeDefineCustomElements: true,
     }),
    
  • 移回 monorepo 的根级别
  • 创建 React 库
  • 在模板库中
    • 运行 npm run build
    • 检查 dist 文件夹是否包含所有子文件夹(cjs、collection、components、esm、types、web-components,index.cjs.js、index.js)
    • 运行 npm link 生成全局符号链接
  • 在 React 库中
    • 运行 npm link MY_LIBRARY
    • 运行 npm i
    • 运行 npm run build(不确定是否需要此步骤,因为没有记录,但我还是做了)
    • 运行 npm link
  • 移回 monorepo 的根级别
  • 创建 React 演示
    • npx create-react-app MY_REACT_DEMO --template typescript
    • npm link MY_REACT_LIBRARY
    • 从库中导入组件并在App.tsx
    • 中使用
    • npm run start

当我确认一切正常后,我为 npm 包管理添加了一个基本的 lerna.jsonconfig。使用此配置,Lerna 将自动为我们的包处理 symver。

{
  "version": "independent",
  "npmClient": "npm",
  "command": {
    "publish": {
      "allowBranch": ["master", "react-generation"],
      "ignoreChanges": ["*.md", "build.js", "config.json"],
      "message": "(auto) Lerna publish",
      "registry": "URL_TO_MY_PACKAGE_REGISTRY"
    },
    "bootstrap": {
      "ignore": "component-*",
      "npmClientArgs": ["--no-package-lock"]
    }
  },
  "packages": ["MY_LIBRARY", "MY_REACT_LIBRARY"]
}

配置 Lerna 后,我按照他们的发布向导使用命令 npx lerna publish 进行发布。

发布后,可以使用 npm i MY_REACT_LIBRARY 在任何 React 项目中安装该包,它应该可以工作。