如何将prop类型捆绑在可重用的React组件库中

时间:2019-11-22 16:00:40

标签: javascript reactjs typescript webpack

我正在尝试使用Typescript和Storybook制作一个简单的React组件库,以使其有趣,而我的第一个愚蠢的Button组件似乎可以正常工作。我还有另一个CRA演示应用程序,在该应用程序中,我以最终用户的身份尝试使用该库。

不过,我仍然陷入困境:我无法使prop-types组件的Button在演示应用程序中工作。它只是不打印警告。

一些其他详细信息:

该库的文件和文件夹的当前组织方式如下:

src/
  index.ts
  controls/
    index.ts
    Button.tsx
babelconfig.js
tsconfig.ts
webpack.config.js

(+ other configuration files and folder for jest and storybook)

我有一个src/index.ts文件,这是我的库的入口,它仅导出来自controls文件夹的所有内容。

// src/index.ts
export * from './controls'

在我的src/controls文件夹中,有一个index.ts文件,它从Button组件中导出所有内容。

// src/controls/index.ts
export * from './Button'

目前Button组件很简单:

import React from 'react'
import t, { InferProps } from 'prop-types'

const propTypes = {
  text: t.string.isRequired
}

const Button = ({ text }: InferProps<typeof propTypes>) => (
  <button>
    { text }
  </button>
)

Button.propTypes = propTypes

export { Button }

所有与此文件捆绑在一起的webpack 4.41

// webpack.config.js

const path = require('path')

module.exports = {
  mode: 'production',
  entry: './src/index.ts',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'index.js',
    library: 'sads-ui',
    libraryTarget: 'umd'
  },
  externals: [
    'react'
  ],
  resolve: {
    extensions: [ '.ts', '.tsx', '.js' ]
  },
  module: {
    rules: [
      {
        test: /\.tsx?$/,
        use: 'ts-loader',
        exclude: /node_modules/
      }
    ]
  }
}

我的babel配置是这样的:

// babel.config.js

module.exports = {
  presets: [
    '@babel/preset-env',
    '@babel/preset-react',
    '@babel/preset-typescript'
  ],
  env: {
    test: {
      plugins: [ 'require-context-hook' ]
    }
  }
}

我不确定这是否重要,但这是我的typescript 3.7配置文件:

// tsconfig.json

{
  "compilerOptions": {
    "target": "es5",
    "module": "es6",
    "jsx": "react",
    "declaration": true,
    "outDir": "./dist",
    "downlevelIteration": true,
    "strict": true,
    "noImplicitAny": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": true,
    "baseUrl": ".",
    "typeRoots": [ "node_modules/@types" ],
    "esModuleInterop": true
  }
}

我的package.json文件的主要属性如下:

// other properties

"main": "dist/index.js",
"files": [
  "dist/*",
  "!dist/**/*.stories.d.ts"
],
"scripts": {
  "prebuild": "rimraf ./dist ./*.tgz",
  "build": "webpack",
  "prepack": "npm run build",
  "test": "jest",
  "storybook": "start-storybook"
},

// other properties

期望

在使用npx create-react-app sadsui-demo创建的演示应用程序中,我将软件包安装在package.json中,并具有以下依赖性:

// package.json

"sads-ui": "file:../sads-ui/sads-ui-0.1.0.tgz"

我在Button中使用App.js如下:

import React from 'react'

import { Button } from 'sads-ui'

const App = () => (
  <div className="App">
    <Button />
  </div>
)

export default App

我希望收到警告,告诉我text的{​​{1}}道具是必需的,但我什么也没得到。不过,正确显示了一个空按钮。

我的推理

我在某种程度上处于黑暗中,但我有一些想法,不确定是否有意义,也因为它似乎也不起作用。

我认为以Button webpack模式构建库可能会从库包中剥离production,因此在最终应用程序中使用组件时,它们不可用。

我尝试以prop-types模式捆绑,在development中看到了dist/index.js代码,但是无论如何它们都不起作用...:(

1 个答案:

答案 0 :(得分:0)

在构建库时,您的Webpack正在将javascript(与* .tsx匹配的所有内容)编译为javascript,并且当您将其导入到create-react-app中时,它只是javascript(您应该在自己的from tkinter import * from tkinter import ttk root_window = Tk() style = ttk.Style() photo = """ R0lGODlhDQAQAPQAAFw1Zl42Z2A6amE6amI7a2I8a2I8bKeHqK6BqbSLsLWLsLuV t7ufu7yfu72hvL6ivb6ivr+jvsKgvsWlwseow8iqxcmrxs+1zNC2zdO70dS90tW9 0tW+0wAAAAAAAAAAACH5BAEAAB0ALAAAAAANABAAAAVMYCd2QFmOKJltGZCOwMZt 7kvKtH3P9RvzutgmZ4tdiL6NBUkyGTaSjMHkEjgyGcuiwnIIRoWIJUG2eFPhCYJy fhUkmLbNcPjqRL1RCAA7 """ photo = PhotoImage(data=photo) l = ttk.Label(root_window, image=photo).grid() style.layout( 'Mystyle.TCombobox', [( 'Combobox.field', { 'sticky': NSEW, 'children': [( 'Combobox.downarrow', { 'side': 'right', 'sticky': NS } ), ( 'Combobox.padding', { 'expand': '1', 'sticky': NSEW, 'children': [( 'Combobox.textarea', { 'sticky': NSEW } )] } )] } )] ) style.element_create('Mystyle.TCombobox.downarrow', 'image', photo) cbo = ttk.Combobox(root_window, values=('one', 'two', 'three'), style='Mystyle.TCombobox') cbo.grid() root_window.mainloop() 中进入create-react-app,然后自己看看图书馆的样子

在您的库中,可以为未编译为消费者可以导入的JS的组件导出单独的/node_modules/(或index.d.ts或其他任何文件)文件 (总要看看其他项目,看看它们是如何做的。Here is material ui's Button.d.ts,通过将Button.d.ts导入到索引中,您可能比这更清洁。 d.ts,然后导出为一个大型库打字稿模块