Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Angular2 AOT compilation - "Cannot determine the module for class (... many components which are unused)" #3636

Closed
swimmadude66 opened this issue Dec 19, 2016 · 9 comments

Comments

@swimmadude66
Copy link

OS?

Cross platform, Testing on Windows 10 now.

Versions.

node v6.3.0

Repro steps.

  1. Create some components
  2. reference one of them in an appModule
  3. bootstrap the module with one component
  4. build with @ngtool/webpack loader
  5. see errors for other unused components

The log given by the failure.

Cannot determine the module for class (....) for each component we don't use.

at analyzeNgModules (C:\Repos\Project\PROJECT\client\node_modules\@angular\compiler\bundles\compiler.umd.js:13079:17)
    at OfflineCompiler.compileModules (C:\Repos\Project\PROJECT\client\node_modules\@angular\compiler\bundles\compiler.umd.js:13115:20)
    at CodeGenerator.codegen (C:\Repos\Project\PROJECT\client\node_modules\@angular\compiler-cli\src\codegen.js:58:30)
    at AotPlugin._make (C:\Repos\Project\PROJECT\client\node_modules\@ngtools\webpack\src\plugin.js:187:43)
    at Compiler.<anonymous> (C:\Repos\Project\PROJECT\client\node_modules\@ngtools\webpack\src\plugin.js:151:75)
    at Compiler.applyPluginsParallel (C:\Repos\Project\PROJECT\client\node_modules\tapable\lib\Tapable.js:193:14)
    at C:\Repos\Project\PROJECT\client\node_modules\webpack\lib\Compiler.js:468:8
    at Compiler.applyPluginsAsyncSeries (C:\Repos\Project\PROJECT\client\node_modules\tapable\lib\Tapable.js:95:46)
    at Compiler.compile (C:\Repos\Project\PROJECT\client\node_modules\webpack\lib\Compiler.js:461:7)
    at C:\Repos\Project\PROJECT\client\node_modules\webpack\lib\Compiler.js:47:17
    at next (C:\Repos\Project\PROJECT\client\node_modules\tapable\lib\Tapable.js:102:11)
    at Compiler.<anonymous> (C:\Repos\Project\PROJECT\client\node_modules\webpack\lib\CachePlugin.js:31:4)

    at next (C:\Repos\Project\PROJECT\client\node_modules\tapable\lib\Tapable.js:104:14)
    at Compiler.<anonymous> (C:\Repos\Project\PROJECT\client\node_modules\browser-sync-webpack-plugin\index.js:26:5)
    at Compiler.applyPluginsAsyncSeries (C:\Repos\Project\PROJECT\client\node_modules\tapable\lib\Tapable.js:106:13)
    at Watching._go (C:\Repos\Project\PROJECT\client\node_modules\webpack\lib\Compiler.js:45:16)
    at Watching.<anonymous> (C:\Repos\Project\PROJECT\client\node_modules\webpack\lib\Compiler.js:36:8)
    at Compiler.readRecords (C:\Repos\Project\PROJECT\client\node_modules\webpack\lib\Compiler.js:371:10)
    at new Watching (C:\Repos\Project\PROJECT\client\node_modules\webpack\lib\Compiler.js:33:16)
    at Compiler.watch (C:\Repos\Project\PROJECT\client\node_modules\webpack\lib\Compiler.js:205:17)
    at processOptions (C:\Repos\Project\PROJECT\client\node_modules\webpack\bin\webpack.js:332:12)
    at Object.<anonymous> (C:\Repos\Project\PROJECT\client\node_modules\webpack\bin\webpack.js:339:1)
    at Module._compile (module.js:541:32)
    at Object.Module._extensions..js (module.js:550:10)
    at Module.load (module.js:458:32)
    at tryModuleLoad (module.js:417:12)
    at Function.Module._load (module.js:409:3)
    at Module.runMain (module.js:575:10)
    at run (bootstrap_node.js:352:7)
    at startup (bootstrap_node.js:144:9)

Mention any other details that might be useful.

We have a src directory with modules and our app components. However, we use a shared npm module to provide common components, pipes, directives, etc between partner apps. This works fine for JIT, but seems to want a module for every component in the shared npm module too, even if we don't need it for this partner.

@swimmadude66
Copy link
Author

The error points to a line in @angular/compiler/bundles/compiler-umd.js which looks like this:

      var symbolsMissingModule = programPipesOrDirectives.filter(function (s) { return !ngModuleByPipeOrDirective.has(s); });
      if (symbolsMissingModule.length) {
          var messages = symbolsMissingModule.map(function (s) { return ("Cannot determine the module for class " + s.name + " in " + s.filePath + "!"); });
          throw new Error(messages.join('\n'));
      }

I tried to edit these lines to see if it would be possible to add an IgnoreUnusedComponents flag or something by hardcoding the lines to this:

  programPipesOrDirectives = programPipesOrDirectives.filter(function (s) { return ModuleByPipeOrDirective.has(s); });

which should just continue, using only components which do have a declared module. However, This simply blows up later down the line, somehow recognizing local code as "external module which cannot be named"

@rolandoldengarm
Copy link

This is not really an Angular CLI issue, but an Angular one.
Angular AOT compilation requires that every component/directive is declared in an ngModule. There's no workaround. I don't understand why you can't put these shared components in an ngModule, that is how the ng2 architecture works.

@swimmadude66
Copy link
Author

@rolandoldengarm because they don't all belong in the same module. We have an npm module we have created that is essentially a library of generic (with respect to our partner implementations) components, pipes, and directives, to be included as needed. Our base app uses all of them, and thus has no issue with AoT. However, many of our partners require a custom component/pipe/directive in place of the base. Or more common, they DON'T require a large number of our components at all.

My understanding of webpack was that if a file is not in the require chain, it is removed from consideration. But if that were the case, it would not blow up at these components (which are entirely unused) lacking a module.

If this is really an ngc issue, I will open up an issue with them, but I figured the webpack side of this should be weeding out unused files, so I opened this one here.

@rolandoldengarm
Copy link

@swimmadude66 ah I see.. Hmm, does it make a difference if you try a production build?

@swimmadude66
Copy link
Author

swimmadude66 commented Dec 19, 2016

We only do AoT with the production flag enabled, so that's all I've tried.

@alexciesielski
Copy link

I'm getting the same problem on the lastest cli (beta.22-1).

I have a router-stubs.ts file in my folder /testing, which holds a RouterLinkDirectiveStub @Directive, which is basically a file to hold common testing stub classes. It is only imported in spec files, so I don't expect it to have an impact on building.

> ng build --aot

10% building modules 3/3 modules 0 activeCannot determine the module for class RouterLinkDirectiveStub in /home/ciesielskico/Documents/webapp/src/testing/router-stubs.ts!

Cannot determine the module for class RouterOutletStubComponent in /home/ciesielskico/Documents/webapp/src/testing/router-stubs.ts!
Error: Cannot determine the module for class RouterLinkDirectiveStub in /home/ciesielskico/Documents/webapp/src/testing/router-stubs.t
s!
Cannot determine the module for class RouterOutletStubComponent in /home/ciesielskico/Documents/webapp/src/testing/router-stubs.ts!
    at analyzeAndValidateNgModules (/home/ciesielskico/Documents/webapp/node_modules/@ngtools/webpack/node_modules/@angular/compiler/b
undles/compiler.umd.js:12707:17)
    at OfflineCompiler.compileModules (/home/ciesielskico/Documents/webapp/node_modules/@ngtools/webpack/node_modules/@angular/compile
r/bundles/compiler.umd.js:12775:20)
    at CodeGenerator.codegen (/home/ciesielskico/Documents/webapp/node_modules/@ngtools/webpack/node_modules/@angular/compiler-cli/src
/codegen.js:58:30)
    at /home/ciesielskico/Documents/webapp/node_modules/@ngtools/webpack/src/plugin.js:210:73
    at process._tickCallback (internal/process/next_tick.js:103:7)

Adding and removing -prod doesn't change the end result.

@swimmadude66
Copy link
Author

swimmadude66 commented Dec 20, 2016

well damn. That means even without the webpack plugin, the ngc is aware of your entire working directory.
Guess I'll go open a similar issue with the angular team. Will reference here once I do.

Would still be nice if the @ngtools/webpack plugin could maybe mask files not in the require chain, since it's already aware of them. I think the best bet in the meantime will be a loader which moves all files in the require chain to a new workspace and runs the compiler there, but that's a REALLY ugly solution....

EDIT: angular/angular ticket: angular/angular#13590

@filipesilva
Copy link
Contributor

angular/angular#13590 seems better to track this, it's not a CLI issue per se.

@angular-automatic-lock-bot
Copy link

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.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Sep 6, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants