Angular CLI: 6.0.0-rc.0
Node: 8.9.3
OS: win32 x64
Angular: 6.0.0-rc.1
... animations, common, compiler, compiler-cli, core, forms
... http, language-service, platform-browser
... platform-browser-dynamic, router
@angular/cli: 6.0.0-rc.0
@angular-devkit/architect: 0.0.10
@angular-devkit/build-angular: 0.0.10
@angular-devkit/build-ng-packagr: 0.0.4
@angular-devkit/build-optimizer: 0.4.9
@angular-devkit/core: 0.4.9
@angular-devkit/schematics: 0.5.0
@ngtools/json-schema: 1.1.0
@ngtools/webpack: 6.0.0-beta.9
@schematics/angular: 0.5.0
@schematics/update: 0.5.0
typescript: 2.7.2
webpack: 4.1.0
ng new xxxcd into the new projectng g library @xxx/coreIt throws the following error in the shell:
Could not find an NgModule. Use the skip-import option to skip importing in NgModule.
It should generate a library named @xxx/core in the folder projects/xxx-core or maybe projects/xxx/core or even projects/core with the correct package name @xxx/core in the package.json file.
If it's not possible, then it should throw an error message that explains that it doesn't support scoped package names.
I suggest to generate a folder structure where the package name is a correct directory path structure - similar to how scoped packages are installed into the node_modules folder.
So when generating a scoped package with ng g library @xxx/core where the package name in package.json will be @xxx/core CLI should generate a folder structure
|-@xxx
|-core
|-package.json
Not only would it be compatible with npm layout. It is likely to work better with VSCode's auto-import suggestions. For example consider a monorepo folder structure similar to the Angular repos. You would probably generate a library in the packages folder then.
${PROJECT_ROOT}
|-node_modules
|-packages
| |-@xxx
| | |-core
| | |-package.json
| | |-index.ts
| |-@foo
| | |-bar
| | |-src
| | |-Foo.ts
| | |-package.json
| | |-index.ts
| |-...
|-tsconfig.json
Now if you attempt to use a class Foo exported by index.ts of package @foo/bar you ideally want
VSCode to suggest an absolute import
import {Foo} from "@foo/bar";
I've been successful to make this work in VSCode 1.19 but it temporarily stopped working in 1.20 or 1.21 after some refactorings in VSCode. Absolute path imports should be working again with latest VSCode versions and with TS 2.8. once https://github.com/Microsoft/TypeScript/issues/22249 is resolved (see also https://github.com/Microsoft/vscode/issues/43575)
VSCode auto-import with absolute paths required some prerequisites in 1.19:
@foo/bar must be a valid path in the directory referenced via baseUrl in tsconfig.json @foo/bar must be declared as a dependency in the importing package's package.json (that of @xxx/core)baseUrl and a generic path mapping must be set in tsconfig.jsonExample tsconfig.json
"baseUrl": "./packages",
"paths": {
"*": ["./*", "../node_modules/*"]
}
Generating the full package name as a directory structure would also make it easier to compile an application from a monorepo structure. For example you could make webpack resolve "@foo/bar" from the packages folder by configuring
module: {
resolve: ["./packages", "./node_modules"]
}
in your webpack config. Then you can compile and bundle libs in the monorepo into an application without having to link them with npm link at all because TS and webpack can directly resolve them from packages rather than node_modules.
Ideally, the directory should be configurable regardless of the package name
Anyway, @foo/bar is a valid package name and a valid directory subtree. Why is this hocus-pocus with the directory name needed at all?
see
https://github.com/Brocco/devkit/commit/6996de1d6d05ebdf0907365adbec1045beb70d39
+ validateProjectName(options.name);
+
+ // If scoped project (i.e. "@foo/bar"), convert projectDir to "foo/bar".
+ const packageName = options.name;
+ let scopeName = '';
+ if (/^@.*\/.*/.test(options.name)) {
+ const [scope, name] = options.name.split('/');
+ scopeName = scope.replace(/^@/, '');
+ options.name = name;
+ }
+
@gms1 Brocco has answered the reasoning in one of the commit discussions. They drop the @ because it causes problems with path auto-completion on mac and windows console terminals, which they want to provide to users working a lot on the terminal (or from within VSCode e.g.).
As far as I understood instead of a generic path mapping (which would be possible when sticking to package name convention) the CLI will generate a path mapping for each lib in tsconfig.json which maps a package import path including the @ onto a filesystem path without the @. So eventually, there will be no difference in how you would import a package in source code. Writing import from "@foo/bar" will work.
@gms1 See here https://github.com/angular/devkit/pull/646#issuecomment-380136599
I see the logic made it up but I'm unable to generate a new project with a scope:
➜ ng new "@foo/bar"
Schematic input does not validate against the Schema: {"name":"@foo/bar","version":"6.1.2","newProjectRoot":"projects","skipInstall":false,"linkCli":false,"skipGit":false,"commit":null}
Errors:
Data path ".name" should match format "html-selector".
Is this as expected for now or should I open a separate issue?
This does however function with ng g library @foo/bar, generating ./projects/foo/bar with a properly scoped package name.
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 suggest to generate a folder structure where the package name is a correct directory path structure - similar to how scoped packages are installed into the
node_modulesfolder.So when generating a scoped package with
ng g library @xxx/corewhere the package name inpackage.jsonwill be@xxx/coreCLI should generate a folder structureNot only would it be compatible with npm layout. It is likely to work better with VSCode's auto-import suggestions. For example consider a monorepo folder structure similar to the Angular repos. You would probably generate a library in the
packagesfolder then.Now if you attempt to use a class
Fooexported byindex.tsof package@foo/baryou ideally wantVSCode to suggest an absolute import
import {Foo} from "@foo/bar";I've been successful to make this work in VSCode 1.19 but it temporarily stopped working in 1.20 or 1.21 after some refactorings in VSCode. Absolute path imports should be working again
with latest VSCode versions and with TS 2.8.once https://github.com/Microsoft/TypeScript/issues/22249 is resolved (see also https://github.com/Microsoft/vscode/issues/43575)VSCode auto-import with absolute paths required some prerequisites in 1.19:
@foo/barmust be a valid path in the directory referenced viabaseUrlintsconfig.json@foo/barmust be declared as a dependency in the importing package'spackage.json(that of@xxx/core)baseUrland a generic path mapping must be set intsconfig.jsonExample
tsconfig.jsonGenerating the full package name as a directory structure would also make it easier to compile an application from a monorepo structure. For example you could make webpack resolve
"@foo/bar"from thepackagesfolder by configuringin your webpack config. Then you can compile and bundle libs in the monorepo into an application without having to link them with
npm linkat all because TS and webpack can directly resolve them frompackagesrather thannode_modules.