簡體   English   中英

如何用角度原理圖覆蓋文件?

[英]How to overwrite file with 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"
    }
  }
}

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

}

files/__path__/__name@dasherize__.ts

export function <%= camelize(name) %>(): void {
}

我運行schematics .:function --name=test --dry-run=false我得到

創建 /src/app/test.ts(33 字節)

但是,第二次。

錯誤! /src/app/test.ts 已經存在。

它不應該在沒有錯誤的情況下覆蓋文件 test.ts 嗎?

編輯:

所有的答案都有效並且很好,但似乎它們是解決方法,沒有明顯的“正確”答案,可能基於偏好/自以為是。 所以不確定如何標記為已回答。

修改克里斯的回答我能夠想出以下解決方案:

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: '.',
        }),
      ]),

我遇到了同樣的問題。 我偶然發現在apply中添加forEach允許刪除文件並創建新文件。 這是@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);
    };
}

如果您要替換許多文件,這可能並不理想。 我在向項目添加樣板時遇到了替換 favicon.ico 的問題。 我使用的解決方案是先明確刪除它。

 export function scaffold(options: any): Rule { return (tree: Tree, _context: SchematicContext) => { tree.delete('src/favicon.ico'); const templateSource = apply(url('./files'), [ template({ ...options, }), move('.'), ]); return chain([ branchAndMerge(chain([ mergeWith(templateSource, MergeStrategy.Overwrite), ]), MergeStrategy.AllowOverwriteConflict), ])(tree, _context); }; }

注意:此方法不再適用於當前版本的 Schematics。

以下似乎適用於 0.6.8 原理圖。

 export function scaffold(options: any): Rule { return (tree: Tree, _context: SchematicContext) => { const templateSource = apply(url('./files'), [ template({ ...options, }), move('.'), ]); return chain([ branchAndMerge(chain([ mergeWith(templateSource, MergeStrategy.Overwrite), ]), MergeStrategy.Overwrite), ])(tree, _context); }; }

作為獎勵,我不再需要明確刪除該文件。

感謝@cgatian 的提示!
不幸的是, move模板move到某個位置並沒有奏效,所以我不得不添加:

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按預期工作,
這將完成在options.output傳遞目標路徑的技巧!

再次感謝!

使用--force參數: ng gc component-name --force

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM