【问题标题】:Cannot use JSX with nodejs ESM module loader无法将 JSX 与 nodejs ESM 模块加载器一起使用
【发布时间】:2020-10-01 09:36:20
【问题描述】:

我试图运行一段带有 React “render” 方法的简单代码块,但浏览器没有显示文本。

import React from 'react';
import ReactDOM from 'react-dom';

ReactDOM.render(<h1>Hello World</h1>,document.getElementById('root'));

我使用 VS Code 作为编辑器,因此我输入了“运行和调试 Node.js”命令。它提出了以下警告

(node:3004) Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.

在 package.json 文件中设置 "type:module" 解决了问题,但另一方面又出现了另一个问题

(node:18968) ExperimentalWarning: The ESM module loader is experimental.    
warning.js:32
SyntaxError: Unexpected token '<'
 at Loader.moduleStrategy (internal/modules/esm/translators.js:81:18)
 at async link (internal/modules/esm/module_job.js:37:21)

那不允许我写任何标签。我错过了什么,我该如何解决?下面是index.html文件和文件结构

<html>
    <head>
        <title> React Test</title>
    </head>

    <body>
        <div id="root"></div>
    </body>
</html>

【问题讨论】:

  • 您是否使用create-react-app 设置了您的项目?
  • 是的,我已经成功加载了它附带的标准 React 项目
  • 我猜缺少 JSX 支持。尝试React.createElement('h1', null, 'Hello World') 而不是&lt;h1&gt;Hello World&lt;/h1&gt; 来确认。见reactjs.org/docs/add-react-to-a-website.html#quickly-try-jsx
  • 也许您想在 vs 代码中下载 debugger for Chrome,设置 launch.json 文件并以这种方式运行 react 应用程序? More about it here
  • @XHOxha 里面的.vscode 文件夹是什么src 以及里面有什么index.htmlindex.js

标签: node.js reactjs node-modules


【解决方案1】:

JSX 不是有效的 JavaScript 语法,目前也不属于任何 ECMAScript 规范。 NodeJS 支持 ESM 并不意味着它原生支持 JSX。

JSX are expected to be transpiled into a valid JavaScript on build/compile time using tools like babel。如果你使用 React,最简单的方法是使用带有 @babel/preset-react 的 babel,它将所有 JSX 转换为 React.createElement() 调用。然后就可以使用node运行babel生成的代码了。

为了让你看得更清楚,这里有一个Babel online REPL,你可以用它来看看你的代码是如何被 babel 转译的。

将在浏览器上运行的 React 应用程序的常见设置如下:

  1. 使用 webpack 打包您的应用
  2. 将 webpack 配置为使用 babel-loader,以便将您的代码转换为浏览器可以运行的内容
  3. 在浏览器上使用生成的 javascript 包

【讨论】:

  • 这不是Node.js环境的解决方案,编译代码然后运行它是一个很好的解决方案。 Nodejs 原生 esm 需要 JSX 的加载器。
  • 这个概念与节点环境大体相似。使用 JSX 的代码仍然需要进行转译才能在 Node 环境中运行。如果你使用 webpack 打包,不同的是你只需要将目标设置为“node”而不是默认的“web”。
  • 再说一次,这不是 nodejs 原生 esm 加载器的解决方案。见nodejs.org/api/esm.html#esm_experimental_loaders
【解决方案2】:

我不明白为什么您的src 文件夹中有.vscode 文件夹,它包含index.htmlindex.js 文件。

我认为您需要将 index.js 文件从 .vscode 文件夹移动到 src 并删除 .vscode 文件夹。或者只是使用 npm 创建一个新应用。

【讨论】:

    【解决方案3】:

    那个文件夹结构是在使用 create-react-app 之后出来的?

    顺便说一句,尝试使用 React.createElement() 返回组件

    return React.createElement('div', {className: 'shopping-list'},
      React.createElement('h1', /* ... h1 children ... */),
      React.createElement('ul', /* ... ul children ... */)
    );
    

    正如文档所说,“render 方法返回您想在屏幕上看到的内容的描述。React 获取描述并显示结果。特别是,render 返回一个 React 元素,它是对要呈现的内容的轻量级描述. 大多数 React 开发人员使用一种称为“JSX”的特殊语法,这使得这些结构更易于编写。语法在构建时转换为 React.createElement('div')。"

    看看这个 https://reactjs.org/docs/react-api.html#createelement

    ----- 补充 您现在可以在节点 v12.x 中导入 .js 文件,分两步:

    • 在您的package.json 文件中添加以下行之后:
      // package.json
      {
        "type": "module"
      }
      
    • 启动脚本时需要添加--experimental-modules标志:
      node --experimental-modules index.js
      

    https://nodejs.org/api/esm.html#esm_commonjs_json_and_native_modules

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-05-08
      • 2021-10-29
      • 2021-08-08
      • 1970-01-01
      • 2021-10-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多