如何调试由 create-react-app 创建的应用程序使用的本地打字稿模块

How do I debug a local typescript module used by an app created from create-react-app

我正在创建一个 Web 应用程序,它使用 express 作为后端 (webapp/server),使用 React 作为前端 (webapp/client)(项目结构见下文)。 我使用 create-react-app 创建了我的 React 应用程序。 我需要一个服务器和客户端都使用的通用模块。所以我创建了一个名为 "common" 的本地模块,并使用 "npm link" 使其可供我的客户端和服务器使用

common 文件夹在 /src 中有一个 class,在构建它时,我在 /dist 文件夹中得到编译的 js、类型和源映射。

我的项目结构

webapp
|
|--common
   |--src
      |--Service.ts
   |--dist
      |--Service.js
      |--Service.d.ts
      |--Service.js.map
|
|--client
   |--src
      |--App.ts
|--server

App.ts

import {Service} from "common"
...
var _service:Service = new Service();
_service.doStuff();
...

我在导入服务、构建和 运行 React 应用程序时没有遇到任何问题。

问题

问题是,当我尝试从 React 应用调试服务时,我得到的是编译后的 Service.js 而不是原始的 Service.ts。

调试在服务器端代码上按预期进行。

我认为问题的根源在于 create-react-app 使用 webpack 构建应用程序,并且在解决模块依赖关系时,它忽略了原始源映射并在其最终包中添加了 .js 文件(main.chunk.js 和 main.chunk.js.map)

实际

main.chunk.js.map --> has path to common/dist/Service.js

预期

main.chunk.js.map --> has path to common/src/Service.ts

我想通了如何通过我的 React 应用程序进行调试。

关键不是在react app中使用内置的js文件,而是在react项目中引用ts文件本身。我终于使用 react-app-rewired 为 react 项目重新配置我的 webpack 配置。有两件事必须完成。

  • 在 tsconfig
  • 中为通用模块添加了一个别名
{
  "compilerOptions": {
   ...
    "paths": {
      "@common": ["my-common-module/src/index.ts"]
    }
  }
}

更新的 webpack 配置有以下更改(使用 config-overrides.js 用于 react-app-rewired)

  • 使用 awesome-typescript-loader 加载上述 ts 文件
  • 删除了 ModuleScopePlugin 以从 /src 目录外导入通用模块
  • 添加了别名以便 webpack 可以知道 @common 别名用于

最终的配置覆盖文件应如下所示:

/* config-overrides.js */
const rewireAliases = require("react-app-rewire-aliases");
const ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin');

var path = require("path");

module.exports = function override(config, env) {
  config.module.rules.push({
    test: /\.ts$/,
    use: ["awesome-typescript-loader"],
    enforce: "pre"
  });

  config.resolve.plugins = config.resolve.plugins.filter(plugin => !(plugin instanceof ModuleScopePlugin));

  config = rewireAliases.aliasesOptions({
    "@common": path.resolve(
      __dirname,
      `node_modules/my-common-module/src/index.ts`
    )
  })(config, env);

  return config;
};