I am creating a web app which uses express for backend(webapp/server) and React for frontend(webapp/client) (see below for project structure). I created my react app using create-react-app. I needed a common module that is used by both server and client. So I created a local module named "common" and used "npm link" to make it available to my client and server
The common folder has a class in /src and upon building it I am getting the compiled js,types and source map in /dist folder.
My Project structure
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();
...
I had no problems importing the service, building and running the react app.
Problem
The problem is that when I try to debug the service from the react app, I am getting the compiled Service.js instead of the original Service.ts.
Debugging is working as expected on the server side code.
I think the source of the issue is that create-react-app uses webpack to build the app, and when is resolves module dependencies, it is ignoring the original source maps and added the .js files in its final bundle (main.chunk.js and main.chunk.js.map)
Actual
main.chunk.js.map --> has path to common/dist/Service.js
Expected
main.chunk.js.map --> has path to common/src/Service.ts
I figured out how to debug through my react app.
The key is not to use the built js files in the react app, but to reference the ts files themselves in the react project. I finally used react-app-rewired to reconfigure my webpack config for the react project. two things had to be done.
{
"compilerOptions": {
...
"paths": {
"@common": ["my-common-module/src/index.ts"]
}
}
}
Updated webpack config with following changes (using config-overrides.js for react-app-rewired)
The final config-overrides file should look something like this:
/* 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;
};