如何在CRA中允许名称空间?

时间:2020-04-16 00:14:03

标签: typescript webpack babeljs react-scripts

我使用以下方法创建了TypeScript React应用程序:

<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Add icon library -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">

</head>
<body>


<button class="btn1"><i class="fa fa-circle pull-right"></i>Active</button>

</body>

通过这种方式,我的项目使用Babel进行编译,然后通过webpack进行捆绑。现在,我想使用TypeScript namespaces,默认情况下Babel不支持TypeScript can be enabled。我安装了所有必需的软件包:

yarn create react-app my-app --template typescript 中,我将package.json更改为react-scripts start

最后,我创建了一个react-app-rewired start文件:

config-overrides.js

但是,编译仍然会引发语法错误,就像没有启用任何插件一样:

SyntaxError:/home/m93a/my-app/script.ts:未标记命名空间的仅声明类型。非声明性名称空间仅在Babel中受实验支持。要启用和查看注意事项,请参见:https://babeljs.io/docs/en/babel-plugin-transform-typescript

如何正确设置项目,以便甚至编译非声明性名称空间?


编辑:我的项目无法正常运行的原因实际上与我的想法完全不同。查看我自己的答案以获取更多详细信息。

3 个答案:

答案 0 :(得分:2)

您必须使用addBabelPlugin而不是addExternalBabelPlugin

tl; dr

如果我们查看文档,则会看到:

addExternalBabelPlugin(plugin)

create-react-app实际上在webpack的{​​{1}}配置中有两个规则:一个规则用于babel-loader中的代码(默认为addSrc),另一个规则用于代码src/到该文件夹​​(如external)。您可以像使用node_modules一样,使用external将插件添加到addExternalBabelPlugin加载程序中。

如果我们在react-scripts/config/webpack.config.js内进行检查,我们会看到以下两个addBabelPlugin条目:

  1. webpack.config.js#L396处有babel-loaderbabel-loader的{​​{1}},addBabelPlugin为此添加了插件,并带有注释:

    include: paths.appSrc
  2. webpack.config.js#L452处是\.(js|mjs|jsx|ts|tsx)$/的{​​{1}},addExternalBabelPlugin为此添加了插件,并带有注释:

    // Process application JS with Babel.
    // The preset includes JSX, Flow, TypeScript, and some ESnext features.
    

我们希望@babel/plugin-transform-typescript应用于与应用程序babel-loader文件夹有关的第一个/\.(js|mjs)$/,因此我们必须使用适用于该// Process any JS outside of the app with Babel. // Unlike the application JS, we only compile the standard ES features. 配置的addBabelPlugin。 / p>

最后但并非最不重要的一点,请确保已将babel-loader脚本更新为从src运行:

babel-loader

您可以使用命名空间中的类检查非常简单的CRA Typescript项目:https://github.com/clytras/cra-ts-namespaces

答案 1 :(得分:1)

使用脚本覆盖Babel配置 因此,请按照以下步骤操作:

  1. 使用create-react-app my-app --template=typescript创建新应用或使用现有应用
  2. 使用npm i -D @rescripts/cli安装rescripts
  3. rescripts docs中那样用package.json中的脚本替换react-scripts
  4. 为babel config @rescripts/rescript-use-babel-config安装rescript插件
  5. 将此侦听器添加到您的package.json文件中
"rescripts": [
    [
        "use-babel-config",
            {
                "presets": [
                    "react-app",
                    [
                        "@babel/preset-typescript",
                        {
                            "allowNamespaces": true
                        }
                    ]
                ]
            }
        ]
    ]

脚本将使用插件,它将扩展babel的配置。我们扩展了默认的react-app babel配置,因此我们不会破坏任何内容。然后,我们覆盖预设(已经由react-app安装),但是我们设置了allowNamespaces标志。

答案 2 :(得分:1)

在我的特定情况下,即使遵从他人的建议,我也无法使其正常工作的原因如下:Babel中存在一个错误,阻止其合并enum和{{ 1}}。例如,此代码不起作用:

namespace

但是出于某些奇怪的原因,Babel在遇到以下代码时会引发一个非常误导性的错误:

SyntaxError:script.ts:命名空间未标记为仅声明类型。非声明性名称空间仅在Babel中受实验支持。要启用和查看注意事项,请参见:https://babeljs.io/docs/en/babel-plugin-transform-typescript

我提交了an issue,因此希望此错误能尽快得到解决,或者至少会收到不错的错误消息。同时,可以使用漫游解决方案:

export enum Foo
{
    a, b, c, d
}

export namespace Foo
{
  export function bar()
  {
    return "bar"
  }
}