-
Notifications
You must be signed in to change notification settings - Fork 11.9k
Description
Versions
Angular CLI: 1.6.3
Node: 8.9.1
OS: darwin x64
Angular: 5.1.3
... animations, common, compiler, compiler-cli, core, forms
... http, language-service, platform-browser
... platform-browser-dynamic, platform-server, router
@angular/cli: 1.6.3
@angular-devkit/build-optimizer: 0.0.36
@angular-devkit/core: 0.0.22
@angular-devkit/schematics: 0.0.42
@ngtools/json-schema: 1.1.0
@ngtools/webpack: 1.9.3
@schematics/angular: 0.1.11
@schematics/schematics: 0.0.11
typescript: 2.4.2
webpack: 3.10.0
Repro steps
We have a set of apps that depend on a common core of node_modules and other assets. Our file structure is roughly organized as follows:
project
└───app1
│ │ package.json
│ │ tsconfig.json
│ │ ...
│ └───src
│ └───node_modules
└───app2
│ │ package.json
│ │ tsconfig.json
│ │ ...
│ └───src
│ └───node_modules
└───commons
│ │ package.json
│ │ tsconfig.base.json
│ │ ...
│ └───assets
│ └───node_modules
│ └───angular-commons
│ │ tsconfig.json
│ │ CommonModule.ts
│ │ lib.ts
│ │ ...
Where all shared node_modules and other assets live in commons, and only node_modules unique to a given app live in its own directory. We are in the process of adopting Webpack for the many benefits it brings, not the least of which is the AngularCompilerPlugin. I can get our build to work as expected as long as the submodules are child directories of the build directory
and the build directory houses all the common node_modules (eg Angular). While this is a possible solution, our prefered solution allows us to maintain our current directory structure. Unfortunately, this is where I am running into issues.
As soon as the child directories leave the root of the build directory, I am running into issues with the AngularCompiler. In my current setup, I receive the following message from a webpack build: ERROR in Error: No NgModule metadata found for 'AppModule'. This suggests to me that the AngularCompiler is not successfully finding the NgModule decorator, as Webpack appears to otherwise successfully walk the tree of the application. I have tried to point it at the correct location to find the NgModule using both the mainPath option and the entryModule options. This has led me to closely inspect the configuration options of AngularCompilerPlugin as well as the specific pathing behavior of TypeScript in both "moduleResolution": "node" and "moduleResolution": "classic" and to experiment with a number of different configurations and directory structures. In every case, the only working structure appeared to be making the root build folder the root folder for @angular and our apps as well. It's worth noting here that difficulties specifying where Angular should look for its pathing / dependencies were the same thing that drove us away from using the Angular compiler, which I understand wraps Webpack.
I attempted to reproduce this behavior in a standalone repo, and ran into a different set of issues that may be related. The repo shares some similarities with our project. In this case, however, the build fails at app.module.ngfactory, unable to find @angular/common. In order to remove pathing ambiguities with TypeScript module resolution, I used relative imports directly to the appropriate node_modules. I suspect that the pathing issues in this example repo are related to the ones we are seeing in our project, even though they manifest differently. Any help in resolving this issue would be much appreciated.
git clone --recursive -j8 https://github.com/mscottnelson/ngWebpackCompile.gitcd ngWebpackCompile/commonsnpm installnpm run watch:app1
Observed behavior
ERROR in Error: No NgModule metadata found for 'AppModule'.
at NgModuleResolver.resolve (/Users/me/project/commons/node_modules/@angular/compiler/bundles/compiler.umd.js:20276:23)
at CompileMetadataResolver.getNgModuleMetadata (/Users/me/project/commons/node_modules/@angular/compiler/bundles/compiler.umd.js:15229:60)
at visitLazyRoute (/Users/me/project/commons/node_modules/@angular/compiler/bundles/compiler.umd.js:31090:104)
at AotCompiler.listLazyRoutes (/Users/me/project/commons/node_modules/@angular/compiler/bundles/compiler.umd.js:31058:20)
at AngularCompilerProgram.listLazyRoutes (/Users/me/project/commons/node_modules/@angular/compiler-cli/src/transformers/program.js:156:30)
at Function.NgTools_InternalApi_NG_2.listLazyRoutes (/Users/me/project/commons/node_modules/@angular/compiler-cli/src/ngtools_api.js:44:36)
at AngularCompilerPlugin._getLazyRoutesFromNgtools (/Users/me/project/commons/node_modules/@ngtools/webpack/src/angular_compiler_plugin.js:248:66)
at Promise.resolve.then.then (/Users/me/project/commons/node_modules/@ngtools/webpack/src/angular_compiler_plugin.js:562:50)
at <anonymous>
at process._tickCallback (internal/process/next_tick.js:188:7)
at Function.Module.runMain (module.js:678:11)
at startup (bootstrap_node.js:187:16)
at bootstrap_node.js:608:3
Desired behavior
Allow the AngularCompiler to be configured to compile apps that are in a directory other than the directory where the angular compiler and its dependencies are installed.
Mention any other details that might be useful
I can successfully build and run the applications using a directory structure like the one below:
project
└───commons
│ │ package.json
│ │ tsconfig.base.json
│ │ ...
│ └───assets
│ └───node_modules
│ └───angular-commons
│ │ tsconfig.json
│ │ CommonModule.ts
│ │ lib.ts
│ │ ...
│ └───app1
│ │ │ package.json
│ │ │ tsconfig.json
│ │ │ ...
│ │ └───src
│ │ └───node_modules
│ └───app2
│ │ │ package.json
│ │ │ tsconfig.json
│ │ │ ...
│ │ └───src
│ │ └───node_modules