Solvedangular cli Cannot create components with CLI on Windows

We are not able to generate components on a project that's using a slightly different directory structure. After a bit of testing, it seems like it's a Windows path issue as generating components on Macbooks are working just fine.

Bug Report or Feature Request (mark with an x)

- [ x ] bug report -> please search issues before submitting
- [ ] feature request

Versions.

@angular/cli: 1.4.5
node: 6.11.3
os: win32 x64
@angular/animations: 4.4.4
@angular/common: 4.4.4
@angular/compiler: 4.4.4
@angular/core: 4.4.4
@angular/forms: 4.4.4
@angular/http: 4.4.4
@angular/platform-browser: 4.4.4
@angular/platform-browser-dynamic: 4.4.4
@angular/router: 4.4.4
@angular/cli: 1.4.5
@angular/compiler-cli: 4.4.4
@angular/language-s
Windows 10 Enterprise version 1703

Repro steps.

  1. Create a new project using ng new PROJECT-NAME
  2. Create an apps folder inside of the src folder.
  3. Move everything in src/app into src/apps, which will result in a file structure of src/apps/app/<component>
  4. Change the apps root in .angular-cli.json to be src/apps

The final result of executing steps 1 to 4 can be seen here: https://github.com/Feeni/angular-cli-windows

  1. Attempt to generate a new component using ng g c test-me -d - an error will appear stating Could not find an NgModule for the new component. Use the skip-import option to skip importing components in NgModule.
  2. Attempt to generate a new component using ng g c test-me --skip-import -d - it will do a dry run of the component creation, but the path will be src/apps/src/apps/<component>. Notice how the root seems to be duplicated twice.

The log given by the failure.

ng g c test-me -d
Error: Could not find an NgModule for the new component. Use the skip-import option to skip importing components in NgModule.
Could not find an NgModule for the new component. Use the skip-import option to skip importing components in NgModule.
ng g c test-me --skip-import -d
  create src/apps/src/apps/app/test-me/test-me.component.html (26 bytes)
  create src/apps/src/apps/app/test-me/test-me.component.spec.ts (629 bytes)
  create src/apps/src/apps/app/test-me/test-me.component.ts (272 bytes)
  create src/apps/src/apps/app/test-me/test-me.component.css (0 bytes)

NOTE: Run with "dry run" no changes were made.

NOTE: While there are no errors above, note how the path of src/apps is being copied twice.

Desired functionality.

We would like to use the Angular CLI to generate components even with a different directory structure on Windows.

Mention any other details that might be useful.

  • Our current work-around is to downgrade to v.1.3.2, as generating components in Windows works fine in that version.
  • When attempting to generate components using the repo linked above on a Macbook as well as using Bash on Ubuntu for Windows, it works with no issues.
28 Answers

✔️Accepted Answer

I had the same problem after upgrading a project from Angular 4.3 to Angular 6. The problem turned out to be the sourceRoot value in angular.json under the [project-name]-e2e project. It was set to "e2e". When comparing to other projects created initially with Angular 6 (not upgraded), I noticed that they had an empty string specified for sourceRoot on the e2e project. After changing mine to that configuration, this problem was resolved.

Please note that sourceRoot for the primary project should still be "src", you should only need to change it to an empty string on the e2e project.

Other Answers:

I'm having the same problem. "Upgraded" to Angular 6, and now I can no longer generate components, services, etc.

"Could not find an NgModule"

I am creating a project to support multiple apps and ran into a similar (or perhaps same) scenario. For starters, I'm using @angular/cli@1.5.0-beta.4 (on Windows) since I needed appRoot support. The basic directory structure is similar to .NET Core features where all code is grouped by folders and client code lives right next to server code, which is why appRoot is called Client. I've pushed the common Angular config files to the root so they are shared across apps, so the structure is as follows (I've obviously left out some files from this listing):

TestProject\Group1\Feature1\Client (contains main.ts, app.module.ts, and app.component.ts)
TestProject\Group1\Feature2\Client (contains main.ts, app.module.ts, and app.component.ts)
TestProject\angular-cli.json

More importantly, here are the associated CLI config values:

"apps": [
    {
      "name": "feature1",
      "root": "Group1/Feature1",
      "appRoot": "Client",
      "prefix": "feature1",
      ...
    },
    {
      "name": "feature2",      
      "root": "Group1/Feature2",
      "appRoot": "Client",      
      "prefix": "feature2",
      ...
    }
   ],

When I run the command with --skip-import and dry run, I get the following as others have been observing:

ng g c foo --skip-import -d
create Group1/Feature1/Group1/Feature1/Client/foo/foo.component.html (22 bytes)
create Group1/Feature1/Group1/Feature1/Client/foo/foo.component.ts (238 bytes)

Without skip-import, it's also unable to track down the module to add it to as a result of the wrong path.

I spent some time adding logging to the angular-cli code and came up with the following findings that I hope will help troubleshoot this:
In generate.ts, the run function had the following values:
parsedPath value

{
	root: '\\',
	dir: 'Group1\\Feature1\\Client',
	base: 'foo',
	ext: '',
	name: 'foo',
	appRoot: 'Group1\\Feature1\\Client',
	sourceDir: 'Group1/Feature1'
 }

commandOptions values

  • path: Group1/Feature1/Client
  • appRoot: Group1\Feature1\Client
  • sourceDir: Group1/Feature1

When seeing the behavior in find-module.js, it looks like the root problem there is in the way that it builds out the pathToCheck.
findModuleFromOptions

  • options.sourceDir: Group1/Feature1
  • options.path: Group1/Feature1/Client

pathToCheck logic

        const pathToCheck = (options.sourceDir || '') + '/' + (options.path || '')
            + (options.flat ? '' : '/' + strings_1.dasherize(options.name));

resulting pathToCheck value
Group1/Feature1/Group1/Feature1/Client/foo

I took a quick look in the component\index.js file that is used to create components and it has similar logic:

        const componentPath = `/${options.sourceDir}/${options.path}/`
            + (options.flat ? '' : stringUtils.dasherize(options.name) + '/')
            + stringUtils.dasherize(options.name)
            + '.component';

I'm not sure what the exact fix is since this code has to support multiple combinations of command option values, but hopefully this helps isolate the issue. Thanks.

A temporary workaround is switching to bash on windows when using ng generate.

This should really be a highly prioritized bug to fix.

Angular CLI: 6.0.7
Node: 8.9.0
Angular: 6.0.3

use --skip-import flag to ignore this message because otherwise angular-cli will look for a module to declare the component and if it can't find it it won't generate component. try this and it should work.

ng g component components/news/news --skip-import

More Issues: