自定义库组件在智能感知上不显示所需的道具

问题描述 投票:0回答:1

我开发了一个自定义 React 组件库,可以在私有 npm 上使用。我的所有组件都是 Typescript React 类组件,在许多组件中我使用接口来声明哪些 props 是可选的或必需的。示例:

export interface ICardLinkProps {

    Title: string;
    Description: string;
    ActionText: string;
    DestinationUrl?: string;
    ImageUrl?: string;
    Icon?: string;
    Theme: Theme;
}

export class CardLink extends React.Component<ICardLinkProps> {
   /// component Code.
}

所有组件都按预期工作,但是当我的同事安装解包时,智能感知不会显示所需的道具。示例:

No intellinse

相比之下,如果我使用 Material-UI 中的组件,智能感知会显示所有必需和可选的道具。

yes Intellinse

有人知道为什么我的组件没有获得智能感知吗?我正在使用 rollup 导出构建包,这是我的配置:

import typescript from "rollup-plugin-typescript2";
import commonjs from "rollup-plugin-commonjs";
import external from "rollup-plugin-peer-deps-external";
import resolve from "rollup-plugin-node-resolve";
import url from "rollup-plugin-url";
import PeerDepsExternalPlugin from "rollup-plugin-peer-deps-external";

import pkg from "./package.json";


export default {
  input: "src/index.ts",
  output: [
    {
      file: pkg.main,
      format: "cjs",
      exports: "named",
      sourcemap: true
    },
    {
      file: pkg.module,
      format: "es",
      exports: "named",
      sourcemap: true
    }
  ],
  plugins: [

    url({
      include: ['**/*.ttf', '**/*.png'],
      limit: Infinity
    }),
    PeerDepsExternalPlugin(),
    external(),
    resolve(),
    typescript({
      rollupCommonJSResolveHack: true,
      exclude: "**/__tests__/**",
      clean: true
    }),
    commonjs({
      include: ["node_modules/**"],
      namedExports: {
        "node_modules/react/react.js": [
          "Children",
          "Component",
          "PropTypes",
          "createElement"
        ],
        "node_modules/react-dom/index.js": ["render"],
        'node_modules/react-is/index.js': [
          'isElement',
          'isValidElementType',
          'ForwardRef',
          'Memo',
          'isFragment'
        ],
        'node_modules/prop-types/index.js': [
          'elementType'
        ]
      }
    })
  ]
};

这是我的 tsconfig.json

{
  "compilerOptions": {
    "outDir": "dist",
    "module": "esnext",
    "target": "es5",
    "lib": [
      "es6",
      "dom",
      "es2016",
      "es2017"
    ],
    "sourceMap": true,
    "allowJs": false,
    "jsx": "react",
    "declaration": true,
    "moduleResolution": "node",
    "forceConsistentCasingInFileNames": true,
    "noImplicitReturns": true,
    "noImplicitThis": true,
    "noImplicitAny": true,
    "strictNullChecks": true,
    "suppressImplicitAnyIndexErrors": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "allowSyntheticDefaultImports": true,
    "esModuleInterop": true,
    "typeRoots": [
      "src/types"
    ]
  },
  "include": [
    "src"
  ],
  "exclude": [
    "node_modules",
    "dist",
    "src/**/*.stories.tsx",
    "src/**/*.test.tsx"
  ]
}

这是运行 rollup -c 后的 dist 文件夹:

componentsDts

rootfolder

这是CardLink.d.ts的内容

import React from "react";
import { ICardLinkProps } from "./ICardLinkProps";
/**
 * CardLink Component
 * @extends {Component<ICardLinkProps,ICardLinkState>}
 */
export declare const CardLink: React.ComponentType<Pick<Pick<ICardLinkProps, "theme" | "classes"> & Partial<Pick<ICardLinkProps, "Title" | "Description" | "ActionText" | "DestinationUrl" | "ImageUrl" | "Icon" | "Secondary">> & Partial<Pick<{
    Title: string;
    Description: string;
    ActionText: string;
    DestinationUrl: string;
    ImageUrl: string;
    Icon: string;
    Secondary: boolean;
}, never>>, "Title" | "Description" | "ActionText" | "DestinationUrl" | "ImageUrl" | "Icon" | "Secondary"> & import("@material-ui/core").StyledComponentProps<"centeredIcon" | "icon" | "bellowMargin" | "paper" | "paperSecondary" | "iconSecondary" | "container" | "actionsArea">>;

提前致谢。

reactjs typescript material-ui rollupjs
1个回答
0
投票

问题没有显示最重要的事情:

  • 组件的导入
  • 组件包的package.json
  • 捆绑输出目录(假设
    dist

这两项将告诉您组件包的名称以及如何将路径导出为节点模块。特别是 package.json 中的

name
exports
字段。

我假设组件包使用桶文件从某个索引文件中导出它们,因为构建使用了捆绑器。另一种方法是简单地使用 TS 进行编译,并让使用包处理捆绑包。

对于具有从图像中给出的输出的捆绑组件包,您可以定义类型,以便可以在模块解析期间找到它们

package.json

"name": "components",
"main": "dist/index.js",
"module": "dist/index.es.js",
"types": "dist/index.d.ts",
"exports": {
  ".": {
    "types": "./dist/index.d.ts",
    "import": "./dist/index.es.js",
    "require": "./dist/index.js",
    "default": "./dist/index.js"
  },
  "./package.json": "./package.json"
}

这将允许像

这样的导入
import { CardLink } from "components"

您的编辑器可以通过包相应的 package.json 文件中的

types
字段处理类型解析。

更好的方法是不捆绑,而只编译,同时生成 ES 模块和 CommonJS 构建。理想情况下,您使用不同的文件扩展名至少可以区分 CJS 类型。另外,避免使用桶文件并使用子路径导出。这样可以通过使用包和工具生态系统来更轻松地进行树摇动。

.
├── components/
│   ├── Foo/
│   │   └── foo.tsx
│   └── Bar/
│       └── bar.tsx
├── package.json
└── tsconfig.json

现在以某种方式创建一个双重构建而不捆绑。使用 @knighted/duel 和其他选项很容易。

现在在子路径导出中使用通配符。与之前相同,但更改了

exports

"exports": {
  "./*": {
    "import": {
      "types": "./dist/*.d.ts",
      "default": "./dist/*.js"
    },
    "require": {
      "types": "./dist/*.d.cts",
      "default": "./dist/*.cjs"
    }
  }
}

现在您可以从子路径而不是桶文件导入。

import { Foo } from "components/Foo"

编辑者可以通过

Foo
字段使用
types
的类型。

© www.soinside.com 2019 - 2024. All rights reserved.