x
)- [x] bug report -> please search issues before submitting
- [ ] feature request
@angular/cli: 1.2.2
node: 8.1.4
os: darwin x64
@angular/animations: 4.3.1
@angular/common: 4.3.1
@angular/compiler: 4.3.1
@angular/core: 4.3.1
@angular/forms: 4.3.1
@angular/http: 4.3.1
@angular/platform-browser: 4.3.1
@angular/platform-browser-dynamic: 4.3.1
@angular/router: 4.3.1
@angular/cli: 1.2.2
@angular/compiler-cli: 4.3.1
@angular/language-service: 4.3.1
@angular/cli
.ng serve --aot
.Notice that there are modules in a lib/
directory that is even with the generated src/
directory. This contains 2 modules and 2 components to reproduce the issue.
> ng serve --aot
** NG Live Development Server is listening on localhost:4200, open your browser on http://localhost:4200 **
Hash: 178d829ae638b28ca8b6
Time: 4870ms
chunk {0} polyfills.bundle.js, polyfills.bundle.js.map (polyfills) 177 kB {4} [initial] [rendered]
chunk {1} main.bundle.js, main.bundle.js.map (main) 15.1 kB {3} [initial] [rendered]
chunk {2} styles.bundle.js, styles.bundle.js.map (styles) 10.5 kB {4} [initial] [rendered]
chunk {3} vendor.bundle.js, vendor.bundle.js.map (vendor) 1.15 MB [initial] [rendered]
chunk {4} inline.bundle.js, inline.bundle.js.map (inline) 0 bytes [entry] [rendered]
ERROR in ~/.../new-app/src/$$_gendir/app/app.component.ngfactory.ts (11,21): Cannot find module '../../../lib/component-b.component.ngfactory'.
ERROR in ~/.../new-app/src/$$_gendir/lib/component-a.component.ngfactory.ts (10,21): Cannot find module './component-a.component'.
ERROR in ~/.../new-app/src/$$_gendir/lib/module-a.module.ngfactory.ts (10,21): Cannot find module './module-a.module'.
ERROR in ~/.../new-app/src/$$_gendir/lib/component-b.component.ngfactory.ts (11,21): Cannot find module './component-a.component'.
ERROR in ~/.../new-app/src/$$_gendir/lib/component-b.component.ngfactory.ts (12,21): Cannot find module './component-b.component'.
ERROR in ~/.../new-app/src/$$_gendir/lib/module-b.module.ngfactory.ts (10,21): Cannot find module './module-b.module'.
ERROR in ~/.../new-app/src/$$_gendir/lib/module-b.module.ngfactory.ts (11,21): Cannot find module './module-a.module'.
ERROR in ./src/$$_gendir/app/app.component.ngfactory.ts
Module not found: Error: Can't resolve '../../../lib/component-b.component.ngfactory' in '~/.../new-app/src/$$_gendir/app'
@ ./src/$$_gendir/app/app.component.ngfactory.ts 9:0-67
@ ./src/$$_gendir/app/app.module.ngfactory.ts
@ ./src/main.ts
@ multi webpack-dev-server/client?http://localhost:4200 ./src/main.ts
webpack: Failed to compile.
ng serve --aot
should not error when importing a module outside of the generated source code from angular cli's new
command.
Please let me know if you need any other info.
Also please note the file paths in the error output have been stripped a bit to preserve some other requirements.
My intent is to create an angular app that will serve as documentation and at the same time have a compile step to build a library of components, but manage it all in one repository.
If this is a duplicate I apologize, but please explain what the current status is with this issue before closing if you can. Thanks!
Possibly related to https://github.com/angular/angular-cli/issues/7113.
TL;DR: Lock the dependency of "enhanced-resolve" to 3.3.0 by running:
npm i -DE [email protected]
Though keep in mind that this is a workaround, and should be removed once "enhanced-resolve" fixes its bugs.
@elliotIndex @filipesilva I thought this was directly related to #7113 and/or #7136 but it seems like even with [email protected]
and @angular/[email protected]
this is still an issue.
As far as I can tell, this is a different problem than the enhanced-resolve
thing. This has to do with what the app root actually means, and how things are resolved relative to it.
AOT generates imports and whatnot, and because of the process paths the things it's trying to import don't really make sense because they are outside the project root:
ERROR in ~/.../new-app/src/$$_gendir/app/app.component.ngfactory.ts (11,21): Cannot find module '../../../lib/component-b.component.ngfactory'.
ERROR in ~/.../new-app/src/$$_gendir/lib/module-a.module.ngfactory.ts (10,21): Cannot find module './module-a.module'.
This is a bug and the fix might be a trivial fix, or it might not not.
But it's not something we consider very high priority to fix right now since the usecase (pretend library) is sort of a hack. Your app shouldn't be building an external library, but rather consuming it.
There's some guidance about linking libraries in https://github.com/angular/angular-cli/wiki/stories-linked-library but I understand that overall library guidance is scarce.
@filipesilva I would agree on the scarcity and I do think it is something @angular/cli
can help with at some point. I would imagine that your base app would be generated by ng new <app-name>
but inside of that generated app you could run ng g library
or outside of an app maybe ng new <library-name> --library
. Thanks for taking a quick look at it!
According to the issue https://github.com/angular/angular-cli/issues/7333, it's not just about going above src/app
but when you reference upwards of the root
property inside .angular-cli.json
.
I was waiting for the TypeScript node_modules
issue to be fixed/merged but have since found an issue with doing that for our Core components.
We want to be able to replace SCSS variables and images referenced inside the core components. An example would be a HeaderComponent that references a logo.png
and uses a $brand-primary
for the background colour. Using different apps the stylePreprocessorOptions.includePaths
and images are relative to the application that uses the Core.
An example would be a Coca Cola
and Pepsi
app which change logos and colours as shown here: https://github.com/intellix/angular-cli-library
If we were to import our Core through node_modules then we couldn't use different images/SCSS variables and the problem gets much more complex. It almost works but it's just AOT that's griefing me :)
We used to achieve this through SCSS entirely. We'd create a my-bootstrap-theme
repository and you just import variables before to change colours. But that's global and goes against Components and ViewEncapsulation that have become generally available since Angular
I have some private share modules that are installed in node_modules/@my
"ng build" works fine
but "ng build -prod" is giving errors "cannot find module"
running cli v1.4.0
Same issue as @playground ... any solution for this? Tried with enhanced-resolve but no success :/
I found this issue via #6973 - I can't discern if these are actually related issues, but the latter was closed as a dupe in favor of this issue, so I'm going to assume it is.
Specifically, the problem I've been facing is that ngfactory import statements don't appear to be generated with respect to the supplied tsconfig's baseUrl
or rootDir
arguments. Instead, they appear to be computed internally based on the most common relative path during module discovery, or by the path of the tsconfig itself.
I saw the comment from @filipesilva
This is a bug and the fix might be a trivial fix, or it might not not.
But it's not something we consider very high priority to fix right now since the usecase (pretend library) is sort of a hack. Your app shouldn't be building an external library, but rather consuming it.
I wanted to chime in to comment that in my case this was a rather insidious problem. Regardless of whether or not specific workflows are considered "hacks", I don't think it is unreasonable for a developer to expect that ngc
utilize the same path strategies as tsc
when generating import statements - after all I believe ngc
is touted as a drop in replacement wrapper for tsc
.
That said, there is a very real possibility that there are others out there sinking quite a bit of time into trying to make what would otherwise be some rather trivial use cases work. As you mentioned, there is not a ton of guidance, and there are a thousand and one different ways to scaffold a project. Might be worth taking a second look at this issue if at least to prevent others from pulling their hair out trying to comprehend why things don't appear to be working the way they've been documented.
I have the same issue.
Our use-case is that we have multiple Angular apps in a monorepo (7 of them, each in it's own subfolder).
We want to keep the components that are shared between those apps in a "Shared" folder at the root of the repository.
We were able to get half-way there by adding:
"paths": {
"@shared/*": ["../Shared/*"]
}
to the app's tsconfig.json files.
Then, in the app.module.ts of each app, we can do stuff like:
import { InputComponent } from '@shared/components/input/input.component';
@NgModule({
declarations: [
InputComponent,
],
});
This works as long as the shared components don't have any dependencies injected via DI.
As soon as we add constructor(private <something>)...
, we get runtime exceptions.
Adding a providers
array to the @Component decorator also results in runtime exceptions.
@filipesilva could you please expand on why you think doing something like this is a hack?
Also, why would this be considered a "pretend library"?
@filipesilva This issue has become more relevant than ever now, with the addition of libraries in the cli.
We should be able to reference in src/app/demos ... import { LibraryModule } from 'projects/library/src/public_api';
and build for deployment.
It works fine if I consume import { LibraryModule } from '@org/library'
however then I have to go and change the imports whenever I go to build my library's demo, importing the unpublished projects/library/src
is ideal for development.
Thoughts?
Running into similar issues, I think.
For development a @liborg/extension
library, a @liborg/core
is required as dependency. For development the following works fine
"rootDir": "../.",
"baseUrl": "../.",
"paths": {
"@liborg/core": [
"../core/src"
]
},
But when building, I get lots of errors like
error TS2307: Cannot find module '@liborg/core.
I'm trying to avoid having to first compile @liborg/core
, npm i ../core.tgz
it my @liborg/extension
project, which increases the build time a lot
I'm using 4 private packages inside one project with Angular CLI 7.1.4.
None of the projects was created using ng g library
, I created them before that exist.
They all live outside src/app
. In fact, they live at the same level.
src/app
packages/proj1
packages/proj2
packages/proj3
packages/proj4
angular.json
To build the projects and rebuild when some file was changed, I just add a section for each project inside angular.json
so the CLI compiler knows there are files to be compiled outside src/app
.
"projects": {
...
"proj1": {
"root": "packages/proj1",
"sourceRoot": "packages/proj1",
"projectType": "library",
"prefix": "proj1",
"architect": {
"build": {
"builder": "@angular-devkit/build-ng-packagr:build",
"options": {
"tsConfig": "packages/proj1/tsconfig.lib.json",
"project": "packages/proj1/ng-package.json"
}
}
}
}
...
}
After that, add the main folder to your tsconfig.json
, which in my case was packages
:
"include": [
"src/**/*",
"packages/**/*",
]
@filipesilva wrote:
Your app shouldn't be building an external library, but rather consuming it.
There is a very good reason to need to do this at the development level. Where different teams building different applications are using a shared library, and that shared library has a shared development model whereby the consuming application teams participate in the library's development, library changes and additions come directly out of and are synchronous with application development work. This is my particular situation - both the library and various applications are internal to my organization, and the library is published and made available via an internal registry like any node package might be. A common library is desired to provide consistency across applications and reduce overall development effort.
As a practical example, application 'X' - which uses library 'Y' - needs a new feature that requires a new component. The new component will belong to the library, not the application. In order to develop the component, it needs to exist alongside the application to ensure that it meets the requirements of the application's new feature. Another use case is around fixing bugs or adding features to existing library components.
Waiting for the component to be available in the library before proceeding with work on the new application feature is highly impractical and takes too long (just not very "agile" at all). There is also a lot of back and forth that would be required until it is right, so that would also consume a lot of extra cycles if they were separate development efforts.
Migrating the component out of the application into the library once the feature and component are completed, is again extra work (changing the application configuration to pull the component from the library dependency instead of from itself). This requires extra testing. And because this is at the end of the development cycle for the application's needs (story has been completed), in reality _it never gets done_ because the application team doesn't have as great a stake in the library as it does in the application (they "own" the application but not the library). So the new component lives on in the application and never gets shared via the library, defeating the purpose of the shared library entirely.
A simultaneous development model is the only good solution, so enabling developers to be able to seamlessly work on the two projects at the same time and see local changes to the library component while working on their application is essential.
This is really easy to set up via TypeScript Module Resolution using a paths
setting under compilerOptions
in the application project's tsconfig
, but Angular CLI's compiler does not work properly with it, whereas the TypeScript compiler works fine.
Please reconsider making this a priority.
This issue was created originally for Angular CLI 1.2.2.
Things are very different now:
I don't think the original reported issue (Cannot import a module above the
src/appfolder
) is still applicable. At the time I think it was mostly related to how we mapped some files and how the AOT compiler looked for them
The underlying topic of consuming/building libraries is still very relevant though.
Our stance on that is still the same as listed in the library story: you should build your lib, then consume whatever was built.
Applications and libraries are built differently. It doesn't make any sense at all, from a build system point of view, to attempt to build your library with a build system that isn't meant to build libraries. The feature set of the two build systems is just plain different. You might try, and succeed, where the feature set matches, but things won't go so well once you start going into specific feature of each.
We simply cannot recommend building your lib inside your app because it is incorrect and will lead to problems in all but the most trivial of cases.
That being said, we don't stop you from using the tsconfig
paths
property to force that behaviour. If you feel confident that your library can be built using the app builder, you should be able to go ahead and do that. You'll need to understand how TS compilation options work, and how paths interact.
@gtranter so to your point, you should be able to use paths
right now. If you find a problem with that then I think that's a bug. I'd appreciate if you opened a new issue with a reproduction so we can investigate it. But please remember to introduce a reproduction. This class of problems is very often due to setup.
@filipesilva thanks for the update. FWIW, this was not originally about _building_, as in building multiple projects from a single project. It was about _importing_, which prevents building. Even in my situation described above, I was not trying to build the library from the application, I was trying to build my application using a locally built version of the library. I would work on the two projects simultaneously but separately as in separate editor and build process etc.
Good to know things have been improved. I'll have to find time to test (no longer actively working on the project in question).
This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.
Read more about our automatic conversation locking policy.
_This action has been performed automatically by a bot._
Most helpful comment
I have the same issue.
Our use-case is that we have multiple Angular apps in a monorepo (7 of them, each in it's own subfolder).
We want to keep the components that are shared between those apps in a "Shared" folder at the root of the repository.
We were able to get half-way there by adding:
to the app's tsconfig.json files.
Then, in the app.module.ts of each app, we can do stuff like:
This works as long as the shared components don't have any dependencies injected via DI.
As soon as we add
constructor(private <something>)...
, we get runtime exceptions.Adding a
providers
array to the @Component decorator also results in runtime exceptions.@filipesilva could you please expand on why you think doing something like this is a hack?
Also, why would this be considered a "pretend library"?