3

是否可以将 Material UI 作为 peerDependency 但将其类型保持为 DevDependency?

我正在使用 React + Typescript 构建一个组件库,这些组件基于 Material UI 库,其中 Rollup 作为模块捆绑器。

这是我的IInputProps类型扩展 Material UITextFieldProps类型的示例。

import { TextFieldProps } from "@material-ui/core";

export type IInputProps = TextFieldProps & {...}

我的目标是将 Material UI 包设置为 peerDependency,因此它将使用安装在目标项目上的 material-ui 包。我将 Material UI 作为 peerDependency 插入并rollup使用peerDepsExternal插件进行设置。当我尝试构建包时,它会引发以下错误:

Cannot find module '@material-ui/core' or its corresponding type declarations.

原因与这个答案有关(@material-ui/core 和 @types/material-ui 有什么关系?)。Material-UI 包包含它自己的类型定义 ( *.d.ts files),因此当我将其设置为 peerDependency 时,类型/接口丢失了。为了解决这个问题,我遵循了这个解决方案(https://github.com/ezolenko/rollup-plugin-typescript2/issues/198)在 src/@types/material-ui/index.d.ts 文件中声明每个模块,但它引发了另一个问题:我不能再使用 material-ui 类型/接口了。

@material-ui/core我的src/@types/material-ui/index.d.ts文件中声明后,代码在下面指出了这个错误。

Cannot use namespace 'TextFieldProps' as a type.ts(2709)

Exported type alias 'IInputProps' has or is using private name 'TextFieldProps'.ts(4081)

现在,我只能看到这两个解决方案:

  1. 将整个材料 ui 包保存在我的库中并丢失包大小:
Library with Material UI packages as peerDependency
npm notice package size:  101.0 kB
npm notice unpacked size: 493.6 kB

Library with Material UI packages
npm notice package size:  1.2 MB
npm notice unpacked size: 6.0 MB
  1. 将 Material UI 用作 peerDependency,但会丢失 Material UI 类型/接口和 lint(通过向我的类型/接口添加一个接受任何道具的属性 -允许其他属性的 TypeScript 接口)。
[x:string]:any

所以,我想知道是否有任何方法可以将 Material UI 作为 peerDependency 但将其类型保留为 devDependencies,所以我可以将它与 Material UI 捆绑为 peerDependency 并在我的包中使用它的类型?

我的配置如下:

src/@types/material-ui/index.d.ts

declare module "@material-ui/core";

rollup.config.js

import peerDepsExternal from "rollup-plugin-peer-deps-external";
import resolve from "@rollup/plugin-node-resolve";
import commonjs from "@rollup/plugin-commonjs";
import image from "@rollup/plugin-image";
import typescript from "rollup-plugin-typescript2";

const packageJson = require("./package.json");

export default {
  input: "src/index.ts",
  output: [
    {
      file: packageJson.main,
      format: "cjs",
      sourcemap: true
    },
    {
      file: packageJson.module,
      format: "esm",
      sourcemap: true
    }
  ],
  plugins: [
    peerDepsExternal(),
    resolve(),
    commonjs(),
    image(),
    typescript({ useTsconfigDeclarationDir: true })
  ]
};

tsconfig.json

{
  "compilerOptions": {
    "rootDir": "src",
    "declaration": true,
    "declarationDir": "build",
    "module": "esnext",
    "target": "es5",
    "lib": ["es6", "dom", "es2016", "es2017"],
    "sourceMap": true,
    "jsx": "react",
    "moduleResolution": "node",
    "allowSyntheticDefaultImports": true,
    "esModuleInterop": true,
    "typeRoots": ["./src/@types"]
  },
  "include": ["src/**/*"],
  "exclude": [
    "node_modules",
    "build",
    "storybook-static",
    "src/**/*.stories.tsx",
    "src/**/*.test.tsx"
  ]
}

包.json

...
"main": "build/index.js",
  "module": "build/index.esm.js",
...
,
  "peerDependencies": {
    "@material-ui/core": "^4.11.4",
    "react": "^16.8.0",
    "react-dom": "^16.8.0",
  },
...
4

2 回答 2

2

如果您希望使用“外部” @material-ui/core(即不是汇总的一部分),您应该这样指定它。

Rollup 实际上有关于对等依赖项的文档,它确实指定使用externals,例如lodash

// rollup.config.js
import resolve from '@rollup/plugin-node-resolve';

export default {
  input: 'src/main.js',
  output: {
    file: 'bundle.js',
    format: 'cjs'
  },
  plugins: [resolve({
    // pass custom options to the resolve plugin
    customResolveOptions: {
      moduleDirectory: 'node_modules'
    }
  })],
  // indicate which modules should be treated as external
  external: ['lodash']
};
于 2021-07-29T18:25:22.200 回答
0

我通过将所有 peerDependencies设置为我的 devDependencies 解决了这个问题。

所以,我的包 json 设置如下:

"peerDependencies": {
    "@material-ui/core": "^4.11.4",
    "react": "^16.8.0",
    "react-dom": "^16.8.0",
},
"devDependencies": {
    "@material-ui/core": "^4.11.4",
    "react": "^16.8.0",
    "react-dom": "^16.8.0",
...

然后我可以摆脱一些配置:

  1. 我删除了我的“ src/@types/material-ui/index.d.ts
  2. 我从 tsconfig.json 中删除了 ' "typeRoots": ["./src/@types"] '

所有其他配置保持不变。

参考:https ://github.com/HarveyD/react-component-library/issues/40

于 2021-08-05T22:23:51.133 回答