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

Wil*_*han 14 angular-cli angular angular-schematics

我想写一个Rule每次都覆盖一个文件.在下面并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"
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

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);

}
Run Code Online (Sandbox Code Playgroud)

files/__path__/__name@dasherize__.ts

export function <%= camelize(name) %>(): void {
}
Run Code Online (Sandbox Code Playgroud)

我跑,schematics .:function --name=test --dry-run=false我得到

CREATE /src/app/test.ts(33个字节)

但是,第二次.

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

它不应该覆盖文件test.ts没有错误吗?

编辑:

所有答案都有效,但很好但似乎它们是变通方法,没有明显的"正确"答案,可能基于偏好/见解.所以不确定如何标记为已回答.

cga*_*ian 7

修改克里斯的答案,我能够提出以下解决方案:

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);
  };
}
Run Code Online (Sandbox Code Playgroud)

apply对此函数的调用来代替您的用法。

 applyWithOverwrite(url('./files/stylelint'), [
        template({
          dot: '.',
        }),
      ]),
Run Code Online (Sandbox Code Playgroud)


chr*_*ris 5

我遇到了同样的问题。偶然地,我发现将a添加forEachapply允许删除的文件中并创建了新文件。这是@ angular-devkit / schematics-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);
    };
}
Run Code Online (Sandbox Code Playgroud)

  • 对于 forEach() 的最后一个很重要,我发现 ie 在 move() 之后 (2认同)
  • 这个答案是不正确的。它不会覆盖现有文件 - 仅忽略它们而不会抛出“原理图处理失败”错误。@cgatian 的答案确实会覆盖现有文件。 (2认同)