I'm trying to integrate an Angular project into a PNPM workspace monorepo that mainly contains react app. Here is the directory structure
|-apps
| |-react-app
| | |-package.json
| |
| |-angular-app (new)
| |-package.json
|
|
|-packages
| |-shared
| |-index.ts
| |-package.json
|
|-package.json
|-pnpm-workspace.yaml
Lets say the shared package has the name @my-app/shared
and it has "main": "index.ts"
.
In the react-app
, I can install this local package and directly use it in my code like the following
import { someValue } from '@my-app/shared';
With some adjustment to the webpack config, the react-app
is able to include the shared module in the bundle correctly.
However, I couldn't figure out how to do it in an angular app. The package can install correctly and everything, but when I run the development server, seems that it doesn't include the @my-app/shared
into the bundle
import { value } from '@my-app/shared';
console.log('xxx', value);
When I inspected the bundle, seems that the angular compiler does not bundle the module. Instead it just shows the placeholder
How do you import local package in Angular then? I believe there needs to be some config added to the angular.json
but I couldn't find any resource. All of the sources out there points to Angular Library through ng generate library
, which isn't what I'm looking for since @my-app/shared
just a simple typescript utils functions.
I had the same issue, I investigated why, here's what I found ⤵️
It's basically due to typescript not emitting any ts files stored in node_modules
(you can check it here).
When angular is compiling your application, it compiles files using the typescript compiler: since typescript detects the file as an external library, it is excluded, so nothing is emitted for this file.
Why it works with your react app:
I suppose, you had to set allowTsInNodeModules
to true
right? The ts-loader
is solving this issue in the webpack plugin, but @angular/cli
does not implement any workaround.
Why it works with paths
:
When typescript analyzes the list of files to compile, it does not check by looking at a specific node_modules
pattern in the file path:
currentNodeModulesDepth
variable (see here).paths
, the currentNodeModulesDepth
is seen equal to zero, as typescript found a mapping and, so, did not start to look at node_modules
.Note that you can simplify your workaround with:
"paths": {
"@my-app/*": ["../../packages/*"]
}
So, you don't have to list all dependencies, you can use *
as a placeholder.