问题摘要
我在Node.js项目中专门使用ESM,并试图找到一种动态导入JSX的方法。
我正在为我的网站制作一个自定义静态站点生成器,并希望使用renderToStaticMarkup()
将React组件呈现为标记,但要实现这一点,我首先需要成功导入组件,然后运行此方法。
有没有人知道一种在ESM Node.js中动态导入JSX的方法?
也就是说,让await import("./jsxComponent.js")
工作?
我尝试过的几件事#
方法1:直接尝试
当我动态导入包含组件的.js
文件时,收到错误消息:SyntaxError: Unexpected token '<'
。似乎import()
无法解析开箱即用的JSX。
如果我将.js
文件的文件扩展名更改为.jsx
,我会毫无意外地收到错误消息Unknown file extension ".jsx"
。
方法2:巴别林
在Node.js的CommonJS全盛时期,我会在一个单独的文件中使用@babel/register
、@babel/preset-env
和@babel/preset-react
,其最后一行在另一个.js
文件中调用require()
,该文件本身就是require()
组件。但这在当时确实起到了作用,允许我将require()
组件呈现为标记。不幸的是,当在仅支持ESM的项目中使用仅支持ESM的包时,这不起作用,因为当我使用@babel/register
时,仅支持ESM的包就会抱怨并中断。
我已经尝试过在import()
中调用@babel/core
之前使用@babel/core
来转换文件,我已经使用transformFileSync
方法完成了这一操作,但是这产生了错误消息:在transformFileSync
的选项对象中,我使用babel-plugin-dynamic-import-node
作为插件,使用@babel/register
、@babel/preset-env
和@babel/preset-react
作为预设。
我也尝试过使用@babel/core
的transformSync
方法,直接传入JSX代码(而不是只传入包含JSX的文件的文件路径),这会产生错误消息:Error: ENOENT: no such file or directory, open 'import Header from "./src/components/header.js";
(注:./src/components/header.js
处有一个文件-它是导入到另一个组件中的组件之一。)
方法3:要求
其他在线方法建议使用require()
而不是import()
,但正如我所说的,这是一个仅使用ESM的项目,使用的是仅使用ESM的包,因此当我尝试使用此方法时,收到的错误消息是require is not defined
,正如人们所期望的那样。
代码示例
方法1:直接尝试
x1米32英寸
方法2:巴别林
const module = await import(
babelCore.transformFileSync("./jsxComponent.js", {
presets: [
"@babel/preset-env",
[
"@babel/preset-react",
{
runtime: "automatic",
},
],
],
plugins: ["dynamic-import-node"],
}).code
);
(Let我知道,如果你想让我张贴任何更多的代码例子,从我的测试与巴别塔)。
方法3:要求
const module = require("./jsxComponent.js")
1条答案
按热度按时间wfveoks01#
我能够通过以下方式将JSX导入到仅支持ESM的项目中:
1.正在安装
@node-loader/babel
(see GitHub repo)1.安装
@babel/core
和@babel/preset-react
1.使用以下设置在我的根目录中创建
babel.config.js
:1.然后运行我的节点构建脚本,将节点加载器设置为实验加载器:
node --experimental-loader @node-loader/babel ./lib/build.js
然后,我能够在我的节点构建脚本中成功地使用
const component = await import("./jsxComponent.js")
,并通过将其作为函数调用来将组件传递给reactDOMServer的renderToStaticMarkup(component())
方法。