什么我不能从 NPM 包中导出 JSX
What can't I export JSX from a NPM Package
我正在编写一个库,它公开了一些 React 组件作为其 API 的一部分。
我将在这里做一些假设:
1 - It is going to be used inside react projects.
2 - Those projects will bundle their dependencies at some point.
3 - Those react projects can use JSX as a way of describing the UI.
4 - Their bundler of choice, Webpack if it's a create-react-app, will use babel in order to parse and transpile that JSX into 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 配置的 'presets' 部分以启用转换。
如果您想保持原样,请将 @babel/plugin-syntax-jsx (https://git.io/vb4yA) 添加到 'plugins' 部分以启用解析。
是的,我可以转译 JSX,也许我会。我只是看不出有任何理由这样做,如果它无论如何都会被捆绑。我更喜欢将转译调整和优化留给用户。
我担心的是,如果我自己转译它,我有 2 个选择。
import React in scope, and using babel to turn <MyComponent/>
into React.createElement()
, but this will rule out the possibility to use the new JSX transform
use the new JSX transform myself, and figure out whether or not my code will be compatible with react versions prior to 17. And increase my own bundle size because there is a lot of code added by babel to make that work.
在这一点上,我想我对这个问题感到非常兴奋,因为坦率地说,我不知道为什么我不能从我的包中导出纯 JSX。我知道我可能遗漏了一些明显的东西,例如分号或其他内容,但我真的很想了解。
如果你想要一些代码/汇总 - babel 配置请随时询问。
坦克!
乍一看你的逻辑似乎很有道理。但是让我们来看看为什么这是个坏主意。
JSX 是一种特殊的语法,必须将其转换为浏览器可以理解的最低通用恶魔,或 by Nodejs。这就是捆绑器所做的,正如您所提到的,任何在节点环境中使用 React 的人几乎肯定会使用捆绑器来执行此操作。
但是,人们可能会在他们的代码中使用许多奇怪的语法。当打包器从 node_module 导入代码时,如果这些模块中的代码尚未转译,则打包器需要转译它们 以及 。考虑到未转译的模块可能有许多奇怪的语法,每个模块都需要自己的转译指令(想想 babel 配置)。为每个 node_module 设置独特的转译配置将非常笨重,更不用说必须对每个 node_module 进行转译,可能以不同的方式对性能不利。
普遍接受的解决此问题的最佳做法是使用 bunder 简单地构建您的程序包,该 bunder 将代码简化为最低公分母。这使您的包用户的捆绑器能够按 node_module “原样”引入代码。
虽然可能会想出一些疯狂的 babe/webpack/rollup 指令来将您的模块自定义解释为 JSX,但您真的希望您的库用户必须这样做吗?特别是在使用 create-react-app 的人的情况下,自定义 CRA 的 babel 配置不受原生支持,这意味着他们需要 extra-steps 才能让你的库工作。此外,出于明显的性能原因,webpack 默认从 js 转换中排除 node_modules,并且 CRA 遵循此约定。发布库时,您希望它们可以普遍使用并尽可能易于使用。
转译、调整和优化代码最好留给编写它的人,对于您要发布的 React 组件库,就是您本人。
我正在编写一个库,它公开了一些 React 组件作为其 API 的一部分。
我将在这里做一些假设:
1 - It is going to be used inside react projects.
2 - Those projects will bundle their dependencies at some point.
3 - Those react projects can use JSX as a way of describing the UI.
4 - Their bundler of choice, Webpack if it's a create-react-app, will use babel in order to parse and transpile that JSX into 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 配置的 'presets' 部分以启用转换。 如果您想保持原样,请将 @babel/plugin-syntax-jsx (https://git.io/vb4yA) 添加到 'plugins' 部分以启用解析。
是的,我可以转译 JSX,也许我会。我只是看不出有任何理由这样做,如果它无论如何都会被捆绑。我更喜欢将转译调整和优化留给用户。
我担心的是,如果我自己转译它,我有 2 个选择。
import React in scope, and using babel to turn
<MyComponent/>
intoReact.createElement()
, but this will rule out the possibility to use the new JSX transform
use the new JSX transform myself, and figure out whether or not my code will be compatible with react versions prior to 17. And increase my own bundle size because there is a lot of code added by babel to make that work.
在这一点上,我想我对这个问题感到非常兴奋,因为坦率地说,我不知道为什么我不能从我的包中导出纯 JSX。我知道我可能遗漏了一些明显的东西,例如分号或其他内容,但我真的很想了解。
如果你想要一些代码/汇总 - babel 配置请随时询问。
坦克!
乍一看你的逻辑似乎很有道理。但是让我们来看看为什么这是个坏主意。
JSX 是一种特殊的语法,必须将其转换为浏览器可以理解的最低通用恶魔,或 by Nodejs。这就是捆绑器所做的,正如您所提到的,任何在节点环境中使用 React 的人几乎肯定会使用捆绑器来执行此操作。
但是,人们可能会在他们的代码中使用许多奇怪的语法。当打包器从 node_module 导入代码时,如果这些模块中的代码尚未转译,则打包器需要转译它们 以及 。考虑到未转译的模块可能有许多奇怪的语法,每个模块都需要自己的转译指令(想想 babel 配置)。为每个 node_module 设置独特的转译配置将非常笨重,更不用说必须对每个 node_module 进行转译,可能以不同的方式对性能不利。
普遍接受的解决此问题的最佳做法是使用 bunder 简单地构建您的程序包,该 bunder 将代码简化为最低公分母。这使您的包用户的捆绑器能够按 node_module “原样”引入代码。
虽然可能会想出一些疯狂的 babe/webpack/rollup 指令来将您的模块自定义解释为 JSX,但您真的希望您的库用户必须这样做吗?特别是在使用 create-react-app 的人的情况下,自定义 CRA 的 babel 配置不受原生支持,这意味着他们需要 extra-steps 才能让你的库工作。此外,出于明显的性能原因,webpack 默认从 js 转换中排除 node_modules,并且 CRA 遵循此约定。发布库时,您希望它们可以普遍使用并尽可能易于使用。
转译、调整和优化代码最好留给编写它的人,对于您要发布的 React 组件库,就是您本人。