zoukankan      html  css  js  c++  java
  • 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 的代码变得更加简洁了。

    感谢您的阅读,如果您对我的文章感兴趣,可以关注我的博客,我是叙帝利,下篇文章再见!


    基于 Angular Material 的中后台管理框架 https://github.com/ng-matero/ng-matero

    Angular Material Extensions 扩展组件库 https://github.com/ng-matero/extensions

    仿 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

  • 相关阅读:
    优化输出质数
    springboot嵌入式Servlet容器自动配置原理
    springboot中配置servlet三大组件
    springboot中springmvc的自定义配置
    springboot实现自定义国际化
    springboot错误处理机制及自定义错误处理
    SpringBoot对静态资源的映射规则
    docker中启动mysql容器
    Java函数式编程(一)
    java并发编程之美——高级篇(三)
  • 原文地址:https://www.cnblogs.com/nzbin/p/14650354.html
Copyright © 2011-2022 走看看