首页 > 解决方案 > 创建 React 应用程序:在 node_modules 中转换外部包的 JSX

问题描述

我正在尝试在我的反应项目中使用react-scratchblocks包。

我已经使用 create-app-react 命令创建了我的项目。

导入包后出现以下错误:

编译失败。

./node_modules/react-scratchblocks/src/Scratchblocks.js
SyntaxError: /Users/jorge/Documents/React/elimu-analyzer-frontend/node_modules/react-scratchblocks/src/Scratchblocks.js: Unexpected token (45:6)

  43 |     const scripts = this.parseScripts(this.props.code);
  44 |     return (
> 45 |       <div className={this.classNames()}>
     |       ^
  46 |         {scripts.map((script,i) => (
  47 |           <Scratchblock key={i} className="script" script={script}/>
  48 |         ))}

我知道它的 jsx 未被识别,但我应该怎么做才能使这个包工作?请记住:我使用 create-rect-app 来创建我的 React 项目。

谢谢。

更新 1:

module.exports = function () {

return {
    overrides: [{
        test: ["./node_modules/react-scratchblocks"],
        presets: ["@babel/preset-react"]
    }],
};
}

更新 2:我导入 react-scratchblocks 的组件。

import React, { useState } from 'react';
import { withRouter } from 'react-router-dom';
import './styles.css';
import Fire from '../../config/Fire';
import Realtime from '../Realtime';
import Scratchblocks from 'react-scratchblocks'

function Content(props) {

const [menuOption, setMenuOption] = useState(1);

async function logout() {
    await Fire.logout();
    props.history.push('/');
    console.log('oi');
}

if (menuOption === 0) {
    return (
        <div class='content'>
            <Realtime />
        </div>
    );
}
else if (menuOption === 1) {
    return (
        <div class="content">
            <button onClick={logout}> OUTRA OPÇÃO </button>
        </div>
    );
}
}

export default withRouter(Content);

标签: javascriptreactjswebpackbabeljscreate-react-app

解决方案


Create React App (CRA)node_modules.

这不包括JSX 编译。由于未编译的JSX导致打包 react-scratchblocks 错误:

SyntaxError: .../Scratchblocks.js: 意外令牌 (45:6)

维护者声明(链接):

我们只在 node_modules 中编译有效的 JavaScript 语法。JSX 不是有效的 JavaScript。你在那里使用 JSX。

我们采取这种立场的原因是因为编译非标准语法将库与构建工具紧密结合在一起。

一旦你允许实验性的东西,也很难划清界限。大多数人不仅想使用 JSX,还想使用类属性等实验性转换。或者装饰师。现在我们必须与每个库维护者争论我们想要支持哪些转换,哪些不支持。

因此,包作者需要在分发之前自行编译 JSX。

要手动编译 JSX 1,您可以将Babel React 预设应用到react-scratchblocksinside node_modules

babel node_modules/react-scratchblocks \
  -d node_modules/react-scratchblocks/dist \
  --presets=@babel/preset-react

构建步骤可能会外包到它自己的配置文件( transpile.js) 中:

module.exports = {
  ...
  overrides: [
    {
      test: ["./node_modules/react-scratchblocks"],
      presets: ["@babel/preset-react"]
    }
  ]
};
babel node_modules/react-scratchblocks \
  -d node_modules/react-scratchblocks/dist \
  --config-file ./transpile.js

然后调整main里面的条目node_modules/react-scratchblocks/package.json以指向之前转译的版本dist

"main": "dist/index.js",

patch-package可以进一步自动化修复损坏包的过程。

请记住,这只是一种解决方法 - 包开发人员有责任分发具有标准 JavaScript 功能的 npm 包。

1另一种选择是调整 Webpack 配置(仅适用于弹出的 CRA)。


推荐阅读