[英]Angular Schematics relative path
我想為 Angular 創建一個自定義示意圖,它將在與執行示意圖相同的目錄中創建一個文件。 我關注了這篇文章,但我不確定如何將新文件添加到所需目錄中。 ( https://developer.okta.com/blog/2019/02/13/angular-schematics#create-your-first-schematic )
例如,如果我有以下目錄結構:
src/app/ !-- Angular Root
|- modules
|_ foo
|- foo.component.ts
|_ foo.component.html
|- app.component.ts
|- app.component.html
|_ app.module.ts
如果我這樣做,請執行以下命令:
> cd /src/app/modules/foo
> ng g my-component:my-component
我希望新創建/更新的文件位於 /src/app/modules/foo 目錄而不是根目錄中。 想想 ng generate 是如何工作的。 如果我從 /src/app/modules/foo 目錄中執行ng g component bar
,那么將在該目錄中生成一個新組件。 這是我需要復制的行為。
這是我的工廠。 現在它顯然是以project.root
為目標的根目錄,但是我沒有找到任何替代方法,如果我不提供路徑,那么我會收到錯誤消息。 如何獲取當前路徑 (src/app/modules/foo) 以存儲在options.path
中?
export function setupOptions(host: Tree, options: any): Tree {
const workspace = getWorkspace(host);
if (!options.project) {
options.project = Object.keys(workspace.projects)[0];
}
const project = workspace.projects[options.project];
options.path = join(normalize(project.root), 'src');
return host;
}
// You don't have to export the function as default. You can also have more than one rule factory
// per file.
export function myComponent(_options: any): Rule {
return (tree: Tree, _context: SchematicContext) => {
setupOptions(tree, _options);
const movePath = normalize(_options.path + '/');
const templateSource = apply(url('./files/src'), [
template({ ..._options }),
move(movePath),
forEach((fileEntry: FileEntry) => {
if (tree.exists(fileEntry.path)) {
tree.overwrite(fileEntry.path, fileEntry.content);
}
return fileEntry;
})
]);
const rule = mergeWith(templateSource, MergeStrategy.Overwrite);
return rule(tree, _context);
};
}
將此添加到您的 schema.json
{
...,
"properties": {
..
"path": {
"type": "string",
"format": "path",
"description": "The path to create the simple schematic within.",
"visible": false
}
按照角度文檔中提到的步驟進行操作
你會遇到一些問題。 例如
1) const workspaceConfig = tree.read('/angular.json');
// 在使用 'schematics' 命令時將為空,但在使用 'ng g' 命令時會起作用。
2) 類似地,當使用 'schematics' 命令時,'options.path' 將是未定義的,但在使用 'ng g' 命令時將起作用。
上面的回復是正確的,你需要添加到 schema.json 文件的路徑,然后在你的函數中
'導出函數 myComponent(_options: any): 規則 {'
您應該能夠使用“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) ]); } }; }
有一段時間讓我感到困惑並需要注意的事情。
在角度項目的根目錄中執行原理圖命令時,'options.path' 將是未定義的。 只有將目錄更改為根目錄的子目錄,該路徑才可用。
可能這是丑陋的解決方案,但我找到它的唯一方法。
您必須更改樹的根目錄才能訪問當前目錄的父目錄
const currentPath = (tree as any)['_backend']['_root'] ;
(tree as any)['_backend']['_root'] = '/' ;
const currentDir = tree.getDir(currentPath);
const parent = currentDir.parent ;
知道您可以訪問父目錄並可以編寫自己的函數來更改所有內容
見樣本
const rootModelDirectory = 'model-form-request'
export function model(_options: any): Rule {
return (tree: Tree, _context: SchematicContext) => {
const currentPath = (tree as any)['_backend']['_root'] ;
(tree as any)['_backend']['_root'] = '/' ;
console.log(currentPath);
const rootdir = findParentDirectoryPath(tree.getDir(currentPath) , rootModelDirectory);
const templateSource = apply(url('./files'), [
// filter(path => path.endsWith('__name@dasherize__.module.ts.template')),
template({
...strings,
..._options
}),
move(normalize(`/${rootdir}/${dasherize(_options.name)}/`))
]);
return mergeWith(templateSource);
};
}
export function findParentDirectoryPath(location :ReturnType<Tree['getDir']>, directoryName : string): string {
for(const dirPath of location.subdirs){
if(new RegExp(directoryName).test(dirPath)){
return `${location.path}/${dirPath}` ;
}
}
if(location.parent){
return findParentDirectoryPath(location.parent , directoryName);
}
throw new Error('root model directory not found')
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.