使用Webpack 4构建React组件库

22

我目前正在构建一个React组件库,并使用Webpack 4进行打包。

从构建库的捆绑包到在npm注册表上发布,一切都运行良好。

但是,在另一个React应用程序中导入其中任何组件时,我无法在运行时获取以下错误消息:

元素类型无效:预期一个字符串(对于内置组件)或类/函数(对于复合组件),但实际得到的是undefined。您可能忘记从定义该组件的文件中导出组件,或者可能混淆了默认和命名导入。

这里是相关的代码:

来自我的组件库的一个蠢笨组件: button/index.js

import React from "react";

const Button = () => <button>Foobar</button>;

export { Button };

我的库的主要入口点是index.js

import { Button } from "./src/components/Button";

export { Button };

我的Webpack配置文件 webpack.config.js:

const path = require("path");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");

module.exports = {
  entry: "./index.js",
  plugins: [new CleanWebpackPlugin()],
  module: {
    rules: [
      {
        test: /\.m?js$/,
        exclude: /node_modules/,
        use: {
          loader: "babel-loader"
        }
      }
    ]
  },
  output: {
    filename: "index.js",
    path: path.resolve(__dirname, "dist"),
    libraryTarget: "commonjs",
    library: ""
  }
};
在其他应用程序中导入此组件的最后步骤:
import { Button } from "my-design-system";

我猜我在Webpack配置中漏掉了一些东西,或者某个属性可能是错误的,但是在阅读了多篇文章和教程之后,我仍然无法确定哪一个。


尝试将 export { Button }; 更改为 export Button ; - Yasser Zubair
我认为这不是一个有效的语法。我还尝试使用 export default Button 将其导出为默认值,然后使用 import Button from 'lib' 导入它,但结果相同。 - Arnaud Christ
2个回答

24

您正在将您的库导出为commonjs,并尝试通过import/export语法导入它。您应该将输出更改为

output: {
  filename: "index.js",
  path: path.resolve(__dirname, "dist"),
  libraryTarget: "umd",
  library: "my-design-system"
}

在这里找到了很多信息:https://webpack.js.org/guides/author-libraries/


谢谢,这个可行!我之前尝试过 umd 但是忘记设置 library 属性为我的库的名称了。我不太确定它在底层是什么意思... - Arnaud Christ
2
webpack的底层工作很有趣,但对于你的React库来说不会提供太多信息。还有一点要记住,你需要将Reactexternalize。这意味着你希望库的用户安装React,并且你不会将其与库捆绑在一起。此外,如果你不想担心这些配置,只想构建你的库,请查看create-react-library - maazadeeb
我已经完成了这个,但我的import仍然显示为未定义?我发现很难找到这种情况的实际示例。我错过了什么? - Tom Pietrosanti
1
@TomPietrosanti 很难说!也许你可以提出一个问题?Webpack的问题有时候很难诊断。 - maazadeeb

4
我会将您的组件默认导出,然后从index.js重新导出为具名导出:
/// Button.js
import React from "react";

const Button = () => <button>Foobar</button>;

export default Button ;

// index.js
export { default as Button } from "./src/components/Button";


那么您可以做如下操作:
import { Button } from "my-design-system";

请确保在设计系统的package.json中,已经设置了指向您的index.jsmain

此外,如果您仍然希望在一些组件中使用命名导出,您可以从该组件文件中导出所有内容:

//index.js
export * from "./src/components/ComponentWithNamedExports";

无论哪种方式,您都要确保所有组件都有一个导出点。
备注:正如Maaz Syed Adeeb所指出的那样,您的配置中libraryTarget是错误的。 我建议您从中删除libraryTargetlibrary

我使用你的解决方案仍然遇到相同的错误。此外,我真的看不出我的代码与你的代码有什么根本区别,因为我们都只是导出组件。我还尝试将“main”属性设置为“index.js”,但我认为它应该设置为“dist/index.js”,对吗? - Arnaud Christ
啊,没错,dist/index.js。你可能还需要在 package.json 中添加一个 module 属性,其值为相同的路径。 - Clarity
1
正如@maaz-syed-adeeb所提到的,我的问题来自于我的webpack配置。无论如何,还是感谢你花时间帮助我。 - Arnaud Christ
例如,有任何 Git 存储库吗? - Sivaraj-v

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接