Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/31.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angular 如何用角度示意图覆盖文件?_Angular_Angular Cli_Angular Schematics - Fatal编程技术网

Angular 如何用角度示意图覆盖文件?

Angular 如何用角度示意图覆盖文件?,angular,angular-cli,angular-schematics,Angular,Angular Cli,Angular Schematics,我想写一个规则,每次都覆盖一个文件。在下表中,将MergeStrategy设置为Overwrite: collection.json { "$schema": "../node_modules/@angular-devkit/schematics/collection-schema.json", "schematics": { "function": { "aliases": [ "fn" ], "factory": "./function",

我想写一个
规则
,每次都覆盖一个文件。在下表中,将
MergeStrategy
设置为
Overwrite

collection.json

{
  "$schema": "../node_modules/@angular-devkit/schematics/collection-schema.json",
  "schematics": {
    "function": {
      "aliases": [ "fn" ],
      "factory": "./function",
      "description": "Create a function.",
      "schema": "./function/schema.json"
    }
  }
}
function/index.ts

export default function(options: FunctionOptions): Rule {
  options.path = options.path ? normalize(options.path) : options.path;
  const sourceDir = options.sourceDir;
  if (!sourceDir) {
    throw new SchematicsException(`sourceDir option is required.`);
  }

  const templateSource: Source = apply(
    url('./files'),
    [
      template({
        ...strings,
        ...options,
      }),
      move(sourceDir),
    ]
  )

  return mergeWith(templateSource, MergeStrategy.Overwrite);

}
export function <%= camelize(name) %>(): void {
}
文件/\uu路径__/__name@dasherize__.ts

export default function(options: FunctionOptions): Rule {
  options.path = options.path ? normalize(options.path) : options.path;
  const sourceDir = options.sourceDir;
  if (!sourceDir) {
    throw new SchematicsException(`sourceDir option is required.`);
  }

  const templateSource: Source = apply(
    url('./files'),
    [
      template({
        ...strings,
        ...options,
      }),
      move(sourceDir),
    ]
  )

  return mergeWith(templateSource, MergeStrategy.Overwrite);

}
export function <%= camelize(name) %>(): void {
}
导出函数():void{
}
我运行
schematics.:函数--name=test--dry run=false

创建/src/app/test.ts(33字节)

但是,第二次

错误/src/app/test.ts已存在

它是否应该覆盖文件test.ts而不出现错误

编辑:


所有的答案都很有效,也很好,但似乎都是权宜之计,没有明显的“正确”答案,可能是基于偏好/固执己见。所以不确定如何标记为已回答

如果要替换许多文件,这可能不太理想。在为项目添加样板文件时,我遇到了替换favicon.ico的问题。我使用的解决方案是先显式删除它

导出函数脚手架(选项:任意):规则{
return(tree:tree,_context:scheduleContext)=>{
tree.delete('src/favicon.ico');
const templateSource=apply(url('./文件')[
模板({
…选项,
}),
移动('.'),
]);
返回链([
分支合并(链([
mergeWith(templateSource,MergeStrategy.Overwrite),
]),MergeStrategy.AllowOverwriteConflict),
])(树,上下文);
};

}
我也遇到了同样的问题。无意中,我发现在
apply
中添加
forEach
可以删除文件并创建新文件。这是@angular devkit/示意图-cli@0.6.8.

export function indexPage(options: any): Rule {
    return (tree: Tree, _context: SchematicContext) => {
        const rule = mergeWith(
            apply(url('./files'), [
                template({ ...options }),
                forEach((fileEntry: FileEntry) => {
                    // Just by adding this is allows the file to be overwritten if it already exists
                    if (tree.exists(fileEntry.path)) return null;
                    return fileEntry;
                })

            ])
        );

        return rule(tree, _context);
    };
}

修改chris的答案后,我想出了以下解决方案:

export function applyWithOverwrite(source: Source, rules: Rule[]): Rule {
  return (tree: Tree, _context: SchematicContext) => {
    const rule = mergeWith(
      apply(source, [
        ...rules,
        forEach((fileEntry) => {
          if (tree.exists(fileEntry.path)) {
            tree.overwrite(fileEntry.path, fileEntry.content);
            return null;
          }
          return fileEntry;
        }),

      ]),
    );

    return rule(tree, _context);
  };
}
用对该函数的调用替换对
apply
的使用

 applyWithOverwrite(url('./files/stylelint'), [
        template({
          dot: '.',
        }),
      ]),

谢谢@cgatian的提示
不幸的是,将模板移动到某个位置不起作用,因此我不得不添加:

forEach(fileEntry => {
  const destPath = join(options.output, fileEntry.path);
  if (tree.exists(destPath)) {
    tree.overwrite(destPath, fileEntry.content);
  } else {
    tree.create(destPath, fileEntry.content);
  }
  return null;
})
MergeStrategy
按预期工作之前,
这将完成在
选项中传递目标路径的技巧。输出

再次感谢

使用
--force
参数:
ng g c component name--force

实际上是否定的,默认行为是保持文件原样。您可以使用
--force
标志强制覆盖文件,如下所示:
原理图:function--name=test--dry run=false--force
。顺便说一句:你在模板函数中为
…字符串导入了什么?我可能不理解
合并策略的含义。覆盖
,那么,如果这不是行为,那么
合并策略。覆盖
。哦,对不起,我完全错过了
合并策略。覆盖
,现在我同意它应该完全有效。在归档的angular/dev kit项目中,至少有一次它出现了一个问题:@jlang
import{strings}from'@angular devkit/core'该死,这不适用于嵌套文件夹结构。当心!我将它用于嵌套文件夹,有两层。但是我确实发现如果文件不存在就会出错,所以我必须先添加一个存在性检查。我将更新我的答案。重要的是,forEach()是最后一个,我发现ie after move()此答案不正确。它不会覆盖现有文件-只会忽略它们而不会引发“Schematics process failed”错误。@cgatian的答案确实覆盖了现有文件。此解决方案实际上覆盖了现有文件(与已接受的文件相反),谢谢:)注意:出于某种原因,WebStorm看不到它可以从何处导入forEach和FileEntry;如果
forEach
之前的
规则之一创建了文件,则应从“@angular devkit/schematics”导入该文件,然后
tree.exists(fileEntry.path)
将计算为
true
。换句话说,该文件可能还不存在于您的文件系统中,而仅存在于由原理图构建的虚拟树中。考虑到您的用例,这可能重要,也可能不重要。