[英]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.