首页 > 解决方案 > 什么不能从 NPM 包中导出 JSX

问题描述

我正在编写一个库,将一些 React 组件作为其 API 的一部分公开。

我将在这里做一些假设:

1 - 它将在反应项目中使用。

2 - 这些项目将在某个时候捆绑它们的依赖项。

3 - 那些 react 项目可以使用 JSX 作为描述 UI 的一种方式。

4 - 他们选择的打包工具,Webpack 如果它是一个 create-react-app,将使用 babel 来解析 JSX 并将其转译成 vanilla JS。

按照这个逻辑,我应该能够从外部包中导出一些 JSX,因为包的代码将与应用程序一起捆绑、转译。

但是,当我在 create-react-app 项目中这样做时,我收到以下错误:


SyntaxError:/Users/someone/Desktop/someproject/dist/esm/index.js:当前未启用对实验语法“jsx”的支持 (35:13):

将 @babel/preset-react ( https://git.io/JfeDR ) 添加到 Babel 配置的“预设”部分以启用转换。如果您想保持原样,请将 @babel/plugin-syntax-jsx ( https://git.io/vb4yA ) 添加到“插件”部分以启用解析。


是的,我可以转换 JSX,也许我会。我只是看不出有任何理由,如果它无论如何都会被捆绑。我更喜欢将转译调整和优化留给用户。

我担心的是,如果我自己编译它,我有两个选择。

在范围内导入 React,并使用 babel 转<MyComponent/>React.createElement(),但这将排除使用新 JSX 转换的可能性

我自己使用新的 JSX 转换,并确定我的代码是否与 17 之前的 React 版本兼容。并增加我自己的包大小,因为 babel 添加了很多代码来实现这一点。

在这一点上,我认为我对这个问题感到非常兴奋,因为坦率地说,我不知道为什么我不能从我的包中导出纯 JSX。我知道我可能遗漏了一些明显的东西,比如分号或其他什么,但我真的很想了解。

如果你想要一些代码/汇总 - babel configs 随时询问。

坦克!

标签: reactjsnpmbabeljsjsxrollup

解决方案


乍一看,您的逻辑似乎很有意义。但是让我们看看为什么这是一个坏主意。

JSX 是一种特殊的语法,必须将其转换为浏览器或Nodejs可以理解的最低通用恶魔。这就是捆绑器所做的,正如您所提到的,任何在节点环境中使用 react 的人几乎肯定会使用捆绑器来执行此操作。

但是,人们可能会在他们的代码中使用许多奇怪的语法。当捆绑器从 node_module 导入代码时,如果这些模块中的代码尚未转译,则捆绑器也需要转译它们。考虑到未转译的模块可能有许多奇怪的语法,每个模块都需要自己的转译指令(想想 babel 配置)。为每个 node_module 拥有唯一的转译配置将非常笨拙,更不用说必须转译每个 node_module,可能以不同的方式,对性能不利。

解决这个问题的普遍接受的最佳实践是简单地使用一个bunder来构建你的包,它将代码归结为最低的公分母。这使您的包用户的捆绑器能够“按原样”引入 node_module 中的代码。

虽然可能会想出一些疯狂的 babe/webpack/rollup 指令来将您的模块自定义解释为 JSX,但您真的希望您的库用户必须这样做吗?尤其是在使用 create-react-app 的人的情况下,本机不支持自定义 CRA 的 babel 配置,这意味着他们需要采取额外的步骤才能使您的库正常工作。此外,出于明显的性能原因,webpack 默认将 node_modules 从 js 转换中排除,CRA 遵循此约定。发布库时,您希望它们尽可能易于使用且普遍可用。

编译、调整和优化代码最好留给编写代码的人,在您尝试发布的 React 组件库的情况下,就是您自己。


推荐阅读