【问题标题】:CRA with express server.js breaks after introducing typescript引入 typescript 后,带有 express server.js 的 CRA 中断
【发布时间】:2019-12-25 02:52:13
【问题描述】:

tl;dr

我向 CRA 应用程序引入了 typescript,但在尝试为构建的应用程序提供服务时不断收到以下错误

 SyntaxError: path\to\root\server\loader.js: Unexpected token, expected "</>/<=/>=" (130:28)

  128 |       let routeMarkup = frontloadServerRender(() =>
  129 |         renderToString(
> 130 |           <Loadable.Capture report={m => modules.push(m)}>
      |                             ^
  131 |             <Provider store={store}>
  132 |               <StaticRouter location={req.url} context={context}>

全文

我有一个 React 应用程序,我不久前在 this tutorial 之后组装了一个用于设置 SSR 和代码分割而不弹出反应脚本的应用程序。

我正在尝试将 typescript 添加到项目中,我希望我可以启用它并在新组件中继续使用它。也就是说,我不想担心将每个文件从.js更改为.tsx,然后调试所有会出现的打字稿错误。

我关注了the guide to add typescript,并将src/index.js 重命名为src/index.tsx,并且仍然能够使用yarn start 运行我的应用程序。

问题是我在尝试构建和提供应用程序时遇到了一个错误,而在我修复第一个应用程序时又遇到了另一个错误。

第一个错误

我第一次尝试运行serve,我得到了这个错误

(node:20588) UnhandledPromiseRejectionWarning: path\to\project\src\app\routes\homepage\index.tsx:1
(function (exports, require, module, __filename, __dirname) { import React, { Component } from "react";
                                                                     ^^^^^
SyntaxError: Unexpected identifier

我认为这是一个 babel 问题,因为我使用的是教程中的服务器文件,它没有使用 typescript。最终我得到了这个配置,在需要 server/server.js 之前我需要 server/index.js

require("@babel/register")({
  ignore: [/\/(build|node_modules)\//],
  presets: ["@babel/preset-env", "@babel/preset-react"],
  plugins: [
    "@babel/plugin-transform-typescript",
    "@babel/plugin-syntax-dynamic-import",
    "@babel/plugin-proposal-export-default-from",
    "@babel/plugin-proposal-export-namespace-from",
    "@babel/plugin-proposal-class-properties",
    "react-loadable/babel"
  ]
});

第二个错误

这似乎解决了第一个问题,但现在我遇到了一个我无法弄清楚的不同错误

 SyntaxError: path\to\root\server\loader.js: Unexpected token, expected "</>/<=/>=" (130:28)

  128 |       let routeMarkup = frontloadServerRender(() =>
  129 |         renderToString(
> 130 |           <Loadable.Capture report={m => modules.push(m)}>
      |                             ^
  131 |             <Provider store={store}>
  132 |               <StaticRouter location={req.url} context={context}>

现在的问题是,当正确解析 import 语句时,应用程序无法识别 JSX 语法。

我尝试将文件从 .js 重命名为 .jsx,但这并没有什么不同。也没有将文件扩展名更改为 .ts.tsx

我还尝试将 React 组件移动到单独的文件 RouteMarkup.jsx 中,然后将其导入加载器,但这没有帮助。

我现在已经花了三个小时尝试调试它,但我在尝试解析这种情况时不知所措。希望有人能指出我正确的方向。

编辑 1

我没有对教程的服务器设置进行太多更改,所以如果有人想了解我的代码的更大上下文,可以查看sample project repo 以了解服务器和加载程序是如何设置的。

【问题讨论】:

  • 在不完全了解项目的情况下很难知道问题出在哪里,但我有一些怀疑.... 一个是您正在使用 CRA 的 名称语法,这显然可以'不被你的后端编译
  • 其次,这也只有在 webpack 或 babel 也在编译你的后端时才有效,如果不是这种情况,这也是一个可能的问题
  • 我用更多示例更新了我的问题。对我来说奇怪的是,如果我用let routeMarkup = frontloadServerRender(() =&gt; "NOTHING") 替换当前引发错误的代码,一切都会完美运行——除了没有发生实际的 SSR。

标签: reactjs typescript express babeljs create-react-app


【解决方案1】:

如果没有对项目的全面了解,或者除非有人之前收到过确切的错误消息,否则不可能确切地知道这个问题的根源。

可能性: 避免使用 CRA 的 语法。 Babel + Typescript 只有在您的后端 I.E 上实现时才能工作,您的后端实际上是通过 babel 编译的。

解决方案:

老实说,作为一个已经完成了 1000 多个小时配置服务器端渲染的人,到目前为止,设置和管理自己是最困难的事情,React 在他们的文档网站上的示例并不能反映任何人的实际情况——世界设置,你有 css + 代码拆分 + 动态加载资产 + 身份验证 + 需要从服务器水化 redux + 需要在后端有静态路由和在前端有动态路由。

解决方案是考虑像 NextJS9 这样的东西,它具有开箱即用的 Typescript 支持、内置服务器(/api/x 下的每个文件都成为一个路由)自动代码拆分和服务器端渲染。 (供参考https://nextjs.org/

如果此解决方案对您不起作用,请告诉我,我将使用 typescript + babel + 前端/后端 + react 构建一个演示项目。

【讨论】:

  • 是的,听起来我可能只是从根本上误解了 Typescript 如何工作以及如何与 babel 和 CRA 交互。除非有人能在第二天诊断出问题,否则我只会将此标记为答案,然后再给 NextJS 一个机会。
猜你喜欢
  • 1970-01-01
  • 2020-05-12
  • 2022-11-11
  • 2019-04-12
  • 1970-01-01
  • 1970-01-01
  • 2017-02-26
  • 2020-01-22
  • 2019-05-23
相关资源
最近更新 更多