Angular 11 中 Schematics 的代码优化
前言
升级 Angular 11 已经是几个月之前的事情了,在升级 Angular 11 之后,schematics 有些函数的用法变了,直接运行会报错,花了两天时间纠正了部分 API。本文主要记录其中的一些变化。
代码优化
1、使用 async/await
获取工作空间
更新前
function addLoaderToIndex(options: Schema): (host: Tree) => Tree {
return (host: Tree) => {
const workspace = getWorkspace(host);
const project = getProjectFromWorkspace(workspace, options.project);
const projectIndexHtmlPath = getIndexHtmlPath(project);
...
}
}
更新后
function addLoaderToIndex(options: Schema): Rule {
return async (host: Tree) => {
const workspace = await getWorkspace(host);
const project = getProjectFromWorkspace(workspace, options.project);
const projectIndexFiles = getProjectIndexFiles(project);
...
}
}
升级 Angular 11 之后的 getWorkspace
方法使用了 await
关键字,源码中 getWorkspace
已经是一个异步方法,暂时不清楚这样写的原因。
2、 新增 updateWorkspace
方法
更新前
function addHmrToAngularJson() {
return (host: Tree) => {
const workspace = getWorkspace(host);
const ngJson = Object.assign(workspace);
const project = ngJson.projects[ngJson.defaultProject];
// build
project.architect.build.configurations.hmr = {
fileReplacements: [
{
replace: `${project.sourceRoot}/environments/environment.ts`,
with: `${project.sourceRoot}/environments/environment.hmr.ts`,
},
],
};
// serve
project.architect.serve.configurations.hmr = {
hmr: true,
browserTarget: `${workspace.defaultProject}:build:hmr`,
};
host.overwrite('angular.json', JSON.stringify(ngJson, null, 2));
};
}
更新后
function addHmrToAngularJson(oprions: Schema) {
return updateWorkspace(workspace => {
const project = getProjectFromWorkspace(workspace);
const targetBuildConfig = project.targets?.get('build')?.configurations as any;
const targetServeConfig = project.targets?.get('serve')?.configurations as any;
targetBuildConfig.hmr = {
fileReplacements: [
{
replace: `${project.sourceRoot}/environments/environment.ts`,
with: `${project.sourceRoot}/environments/environment.hmr.ts`,
},
],
};
targetServeConfig.hmr = {
hmr: true,
browserTarget: `${oprions.project}:build:hmr`,
};
});
}
我个人觉得 updateWorkspace
方法很有意思,在上一个版本中如果想更新 json 文件,需要使用 host.overwrite
覆盖原文件。当前方法则使用了封装好的 updateWorkspace
方法,这个方法本身就是更新 angular.json
3、封装 chalk
的方法,不再需要直接引用
更新前
function addAnimationsModule(options: Schema) {
return (host: Tree) => {
...
if (hasNgModuleImport(host, appModulePath, noopAnimationsModuleName)) {
return console.warn(
chalk.red(
`Could not set up "${chalk.bold(browserAnimationsModuleName)}" ` +
`because "${chalk.bold(noopAnimationsModuleName)}" is already imported. Please ` +
`manually set up browser animations.`
)
);
}
...
};
}
更新后
function addAnimationsModule(options: Schema) {
return async (host: Tree, context: SchematicContext) => {
if (hasNgModuleImport(host, appModulePath, noopAnimationsModuleName)) {
context.logger.error(
`Could not set up "${browserAnimationsModuleName}" ` +
`because "${noopAnimationsModuleName}" is already imported.`
);
context.logger.info(`Please manually set up browser animations.`);
return;
}
};
}
更新后版本已经不需要显式的引用 chalk
插件了,只需要使用封装好的 context.logger
即可。
4、projectType
的取值有变化
更新前
function buildDefaultPath(project: WorkspaceProject): string {
const root = project.sourceRoot ? `/${project.sourceRoot}/` : `/${project.root}/src/`;
const projectDirName = project.projectType === ProjectType.Application ? 'app' : 'lib';
return `${root}${projectDirName}`;
}
更新后
function buildDefaultPath(project: ProjectDefinition): string {
const root = project.sourceRoot ? `/${project.sourceRoot}/` : `/${project.root}/src/`;
const projectDirName = project.extensions.projectType === ProjectType.Application ? 'app' : 'lib';
return `${root}${projectDirName}`;
}
更新之后在使用 buildDefaultPath
这个方法的时候遇到一个错误,projectType
必须通过 project.extensions.projectType
才能获取。
总结
在升级 Angular 11 之后,除了上面提到的方法优化之外,还有一些方法的删减,总的来说, schematics 的代码变得更加简洁了。
感谢您的阅读,如果您对我的文章感兴趣,可以关注我的博客,我是叙帝利,下篇文章再见!
开发低代码平台的必备拖拽库 https://github.com/ng-dnd/ng-dnd
低代码平台必备轻量级 GUI 库 https://github.com/acrodata/gui
适用于 Angular 的 CodeMirror 6 组件 https://github.com/acrodata/code-editor
基于 Angular Material 的中后台管理框架 https://github.com/ng-matero/ng-matero
Angular Material Extensions 扩展组件库 https://github.com/ng-matero/extensions
Unslider 轮播图插件纯 JS 实现 https://github.com/nzbin/unsliderjs
仿 Windows 照片查看器插件 https://github.com/nzbin/photoviewer
仿 Windows 照片查看器插件 jQuery 版 https://github.com/nzbin/magnify
完美替代 jQuery 的模块化 DOM 库 https://github.com/nzbin/domq
简化类名的轻量级 CSS 框架 https://github.com/nzbin/snack
与任意 UI 框架搭配使用的通用辅助类 https://github.com/nzbin/snack-helper
单元素纯 CSS 加载动画 https://github.com/nzbin/three-dots
有趣的 jQuery 卡片抽奖插件 https://github.com/nzbin/CardShow
悬疑科幻电影推荐 https://github.com/nzbin/movie-gallery
锻炼记忆力的小程序 https://github.com/nzbin/memory-stake