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

时间:2019-09-02 19:25:27

标签: javascript reactjs webpack babeljs create-react-app

我正在尝试在我的react项目上使用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);

2 个答案:

答案 0 :(得分:3)

Create React App(CRA)将仅从node_modules转换有效的JavaScript语法,其中不包括JSX编译。 react-scratchblocks npm软件包包含untranspiled JSX,它说明了错误的根本原因。您可以在CRA语句here上阅读更多内容。

作者将原始未编译的源文件src/index.js用作其主要入口点npm软件包文件。 index.js导入Scratchblocks.js,其中包括未转换的JSX语法。我个人不使用该程序包,也无法说明其原因。但是我想,作者可以通过babel反应预先设置好自己来移植JSX,这与CRA的上述声明一致。因此,应该通过请求构建修复来解决问题。

要更改构建过程,您必须退出CRA才能调整Webpack配置(如果您尚未这样做,那么仅出于此目的肯定不是一个好主意)。一种替代方法是手动将Babel React预设应用于react-scratchblocks中的node_modules作为临时解决方法,例如通过adding overridesproject wide babel.config.js使用Babel CLI:

transpile-react-scratchblocks-jsx.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-react-scratchblocks-jsx.js

或与@babel/preset-react内联,省略配置:

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

您还需要调整软件包main中的package.json字段,例如:

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

请记住,您要深入研究外部软件包,这只能是一种解决方法(请参见上文)。

Code sample

希望,会有所帮助。

答案 1 :(得分:0)

我个人建议您使用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'),
        ],
      },
    },
  ],
}

您可以更改许多其他配置,我建议您看一下craco npm package page

Credtis:https://stackoverflow.com/a/58603207/4277948