创建 React App:在 node_modules 中转译外部包的 JSX

Jor*_*all 4 javascript reactjs webpack babeljs create-react-app

我正在尝试在我的反应项目中使用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 |         ))}
Run Code Online (Sandbox Code Playgroud)

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

谢谢。

更新1:

module.exports = function () {

return {
    overrides: [{
        test: ["./node_modules/react-scratchblocks"],
        presets: ["@babel/preset-react"]
    }],
};
}
Run Code Online (Sandbox Code Playgroud)

更新 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);
Run Code Online (Sandbox Code Playgroud)

70n*_*0ny 11

我个人建议你使用craco(参见@craco/craco

Craco 是一个功能强大的工具,允许您编辑内置create-react-app配置,而无需强制您弹出项目。

如何安装

  • 跑步npm install @craco/craco --save-dev
  • 跑步npm install craco-babel-loader --save-dev
  • craco.config.js在项目根文件夹中创建
  • 更新以下脚本package.json
    • react-scripts start->craco start
    • react-scripts build->craco build
    • ...
  • 这是craco配置文件的内容
const path = require('path')
const fs = require('fs')
const cracoBabelLoader = require('craco-babel-loader')

// manage relative paths to packages
const appDirectory = fs.realpathSync(process.cwd())
const resolvePackage = relativePath => path.resolve(appDirectory, relativePath)

module.exports = {
  plugins: [
    {
      plugin: cracoBabelLoader,
      options: {
        includes: [
          resolvePackage('node_modules/package-to-transpile'),
          resolvePackage('node_modules/another-package-to-transpile'),
        ],
      },
    },
  ],
}
Run Code Online (Sandbox Code Playgroud)

您可以更改很多其他配置,我建议您查看craco npm 包页面

信用:/sf/answers/4102224521/


for*_*d04 8

Create React App (CRA)node_modules.

这并没有包括JSX编译。由于未转译 JSX导致的包 react-scratchblocks 错误:

语法错误:.../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
Run Code Online (Sandbox Code Playgroud)

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

module.exports = {
  ...
  overrides: [
    {
      test: ["./node_modules/react-scratchblocks"],
      presets: ["@babel/preset-react"]
    }
  ]
};
Run Code Online (Sandbox Code Playgroud)
babel node_modules/react-scratchblocks \
  -d node_modules/react-scratchblocks/dist \
  --presets=@babel/preset-react
Run Code Online (Sandbox Code Playgroud)

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

"main": "dist/index.js",
Run Code Online (Sandbox Code Playgroud)

补丁包可以进一步自动化修复损坏的包的过程。

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

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