如何用 angular 原理图覆盖文件?
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
我得到
CREATE /src/app/test.ts (33 bytes)
但是,第二次。
ERROR! /src/app/test.ts already exists.
它不应该覆盖文件 test.ts 而没有错误吗?
编辑:
所有答案都有效并且很棒,但它们似乎是变通方法,没有明显的 "right" 答案,并且可能基于偏好/自以为是。所以不确定如何标记为已回答。
如果您要替换许多文件,这可能不太理想。我在向项目添加样板文件时遇到了替换 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);
};
}
作为奖励,我不再需要明确删除该文件。
我遇到了同样的问题。我偶然发现在 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);
};
}
修改克里斯的回答我想出了以下解决方案:
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 的提示!
不幸的是,它无法将模板 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 g c component-name --force
我想写一个每次覆盖一个文件的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
我得到
CREATE /src/app/test.ts (33 bytes)
但是,第二次。
ERROR! /src/app/test.ts already exists.
它不应该覆盖文件 test.ts 而没有错误吗?
编辑:
所有答案都有效并且很棒,但它们似乎是变通方法,没有明显的 "right" 答案,并且可能基于偏好/自以为是。所以不确定如何标记为已回答。
如果您要替换许多文件,这可能不太理想。我在向项目添加样板文件时遇到了替换 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);
};
}
作为奖励,我不再需要明确删除该文件。
我遇到了同样的问题。我偶然发现在 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);
};
}
修改克里斯的回答我想出了以下解决方案:
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 的提示!
不幸的是,它无法将模板 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 g c component-name --force