如何在 Angular 示意图中使用当前路径
How to use current path in Angular schematics
我正在开发生成一些文件的原理图。我想在当前目录中有新文件,即
我的项目根目录是 /src/app
。当我在文件夹 /src/app/features/f1
中并键入
ng g my:some-schemaitc --name=name
我正在等待新文件
/src/app/features/f1/name.ts
相反,结果是
/src/app/name.ts
我想实现与 ng g class --name=name
相同的行为。当我在目录 /src/app/features/f1
中键入 ng g class --name=class
时,结果将是
/src/app/features/f1/class.ts
我试图模仿 Angular ng g class
行为 schematics source code,但没有令人满意的结果。我的代码几乎一样。
有人用过当前路径吗?
无意间发现了一个全局变量__dirname
,它存储了当前路径。例如:
console.log('DIR', __dirname);
按照 angular docs
中提到的步骤进行操作
您会 运行 遇到一些问题。例如
1) const workspaceConfig = tree.read('/angular.json');
// 在使用 'schematics' 命令时为空,但在使用 'ng g' 命令时有效。
2) 类似地,'options.path' 在使用 'schematics' 命令时将是未定义的,但在使用 'ng g' 命令时将起作用。
您需要将路径添加到 schema.json 文件,然后在您的函数中,您应该能够使用 'options.path' 来获取当前位置。然而,正如我提到的,我无法在使用 'schematics' 命令时让它工作。我只能在使用 'ng g' 命令时让它工作。
这里是我的文件的例子
1) ..schematics/ng-generate/customComponent/schema.json
{
"$schema": "http://json-schema.org/schema",
"id": "GenerateCustomComponent",
"title": "Generate Custom Component",
"type": "object",
"properties": {
"name": {
"description": "The name for the custom component.",
"type": "string",
"x-prompt": "What is the name for the custom component?"
},
"path": {
"type": "string",
"format": "path",
"description": "The path at which to create the component file, relative to the current workspace. Default is a folder with the same name as the component in the project root.",
"visible": false
}
},
"required": [
"name"
]
}
2) ..schematics/ng-generate/customComponent/schema.ts
import { Schema as ComponentSChema } from '@schematics/angular/component/schema';
export interface Schema extends ComponentSChema {
// The name of the custom component
name: string;
}
2) ..schematics/ng-generate/customComponent/index.ts
import {
Rule, Tree, SchematicsException,
apply, url, applyTemplates, move,
chain, mergeWith
} from '@angular-devkit/schematics';
import { strings, experimental, normalize } from '@angular-devkit/core';
import { Schema as CustomSchema } from './schema';
export function generate(options: CustomSchema): Rule {
return (tree: Tree) => {
const workspaceConfig = tree.read('/angular.json'); // will return null when using schematics command but will work when using ng g
console.log('workspaceConfig::', workspaceConfig);
console.log('path:', options.path); // will be undefined when using schematics command but will work when using ng g
// from now following along with angular docs with slight modifications.
if (workspaceConfig && !options.path) {
const workspaceContent = workspaceConfig.toString();
console.log('workspaceContent::', workspaceContent);
const workspace: experimental.workspace.WorkspaceSchema = JSON.parse(workspaceContent);
console.log('workspace', workspace);
options.project = workspace.defaultProject;
const projectName = options.project as string;
const project = workspace.projects[projectName];
const projectType = project.projectType === 'application' ? 'app' : 'lib';
console.log('projectType::', projectType);
options.path = `${project.sourceRoot}/${projectType}`;
}
if (options.path) {
// this will be used by the ng g command
const templateSource = apply(url('./files'), [
applyTemplates({
classify: strings.classify,
dasherize: strings.dasherize,
name: options.name
}),
move(normalize(options.path as string))
]);
return chain([
mergeWith(templateSource)
]);
} else {
// this will be used by the schematics command
const templateSource = apply(url('./files'), [
applyTemplates({
classify: strings.classify,
dasherize: strings.dasherize,
name: options.name
})
]);
return chain([
mergeWith(templateSource)
]);
}
};
}
我正在开发生成一些文件的原理图。我想在当前目录中有新文件,即
我的项目根目录是 /src/app
。当我在文件夹 /src/app/features/f1
中并键入
ng g my:some-schemaitc --name=name
我正在等待新文件
/src/app/features/f1/name.ts
相反,结果是
/src/app/name.ts
我想实现与 ng g class --name=name
相同的行为。当我在目录 /src/app/features/f1
中键入 ng g class --name=class
时,结果将是
/src/app/features/f1/class.ts
我试图模仿 Angular ng g class
行为 schematics source code,但没有令人满意的结果。我的代码几乎一样。
有人用过当前路径吗?
无意间发现了一个全局变量__dirname
,它存储了当前路径。例如:
console.log('DIR', __dirname);
按照 angular docs
中提到的步骤进行操作您会 运行 遇到一些问题。例如
1) const workspaceConfig = tree.read('/angular.json');
// 在使用 'schematics' 命令时为空,但在使用 'ng g' 命令时有效。
2) 类似地,'options.path' 在使用 'schematics' 命令时将是未定义的,但在使用 'ng g' 命令时将起作用。
您需要将路径添加到 schema.json 文件,然后在您的函数中,您应该能够使用 'options.path' 来获取当前位置。然而,正如我提到的,我无法在使用 'schematics' 命令时让它工作。我只能在使用 'ng g' 命令时让它工作。
这里是我的文件的例子
1) ..schematics/ng-generate/customComponent/schema.json
{
"$schema": "http://json-schema.org/schema",
"id": "GenerateCustomComponent",
"title": "Generate Custom Component",
"type": "object",
"properties": {
"name": {
"description": "The name for the custom component.",
"type": "string",
"x-prompt": "What is the name for the custom component?"
},
"path": {
"type": "string",
"format": "path",
"description": "The path at which to create the component file, relative to the current workspace. Default is a folder with the same name as the component in the project root.",
"visible": false
}
},
"required": [
"name"
]
}
2) ..schematics/ng-generate/customComponent/schema.ts
import { Schema as ComponentSChema } from '@schematics/angular/component/schema';
export interface Schema extends ComponentSChema {
// The name of the custom component
name: string;
}
2) ..schematics/ng-generate/customComponent/index.ts
import {
Rule, Tree, SchematicsException,
apply, url, applyTemplates, move,
chain, mergeWith
} from '@angular-devkit/schematics';
import { strings, experimental, normalize } from '@angular-devkit/core';
import { Schema as CustomSchema } from './schema';
export function generate(options: CustomSchema): Rule {
return (tree: Tree) => {
const workspaceConfig = tree.read('/angular.json'); // will return null when using schematics command but will work when using ng g
console.log('workspaceConfig::', workspaceConfig);
console.log('path:', options.path); // will be undefined when using schematics command but will work when using ng g
// from now following along with angular docs with slight modifications.
if (workspaceConfig && !options.path) {
const workspaceContent = workspaceConfig.toString();
console.log('workspaceContent::', workspaceContent);
const workspace: experimental.workspace.WorkspaceSchema = JSON.parse(workspaceContent);
console.log('workspace', workspace);
options.project = workspace.defaultProject;
const projectName = options.project as string;
const project = workspace.projects[projectName];
const projectType = project.projectType === 'application' ? 'app' : 'lib';
console.log('projectType::', projectType);
options.path = `${project.sourceRoot}/${projectType}`;
}
if (options.path) {
// this will be used by the ng g command
const templateSource = apply(url('./files'), [
applyTemplates({
classify: strings.classify,
dasherize: strings.dasherize,
name: options.name
}),
move(normalize(options.path as string))
]);
return chain([
mergeWith(templateSource)
]);
} else {
// this will be used by the schematics command
const templateSource = apply(url('./files'), [
applyTemplates({
classify: strings.classify,
dasherize: strings.dasherize,
name: options.name
})
]);
return chain([
mergeWith(templateSource)
]);
}
};
}