webpack工具链热替换 -- angularjs的粗放式实现

前端之家收集整理的这篇文章主要介绍了webpack工具链热替换 -- angularjs的粗放式实现前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

ng-hot-loader

前言

webpack-dev-server自带支持模块热替换特性(HMR),不刷新页面实现代码局部更新,使用HMR可以大幅提升开发效率。

实现目标

@H_502_12@
  • [x] 样式热替换 -- style-loader本身即支持HMR,建议依赖库css直接解析出文件link,降低热替换成本

  • [x] 模板热替换

  • [x] 服务热替换

  • [x] 过滤器热替换 -- expression 变动才会重新实例化过滤器

  • [x] 指令热替换 -- 目前low level支持

  • [x] 控制器热替换

  • 实现策略

    合理划分angular模块,将angular模块划分为主模块,业务模块。路由,业务服务全局服务合理分散到主模块与业务模块中。参照angular组件单一职责,单个模块(文件)仅承担有限职责,。

    HMR关键核心为组件声明 => 组件定位 => 组件更新

    @H_502_12@
  • 文件命名建议按照官方styleguide

  • 关联filter,service,directive在单一模块中声明。

  • 关键核心依旧在模块,路由声明。路由声明中,模板与控制器统一采用ES6引入方案,template: templateVariable,控制器声明统一采用pure function的方式,而不是字符串的方式。

  • 路由声明与组件声明在*.module.js统一文件内部声明。

  • 控制器暂时不考虑通过$controllerProvider注册的类型。

  • 路由不考虑热更新。

  • 所有模板文件,都通过ES6 default import导入,JS文件建议全部通过destruct的方式引用。

  • /**
     * @description - application level router config.
     * @author bornkiller <hjj491229492@hotmail.com>
     */
    
    'use strict';
    
    // layout module dependency
    import layoutAuthorizeTemplate from './authority/authorize.html';
    import { AuthorizeController } from './authority/authorize.controller';
    
    import layoutNavbarTemplate from './flow/navbar.html';
    import layoutSidebarTemplate from './flow/sidebar.html';
    import layoutCoreTemplate from './flow/core.html';
    import { SidebarController } from './flow/sidebar.controller';
    
    
    // layout module name
    const LAYOUT_MODULE = 'app.layout';
    
    // layout module router
    const LayoutRoute = [
      {
        name: 'authorize',url: '/authorize',views: {
          'core': {
            template: layoutAuthorizeTemplate,controller: AuthorizeController,controllerAs: 'vm'
          }
        }
      },{
        name: 'application',url: '/application',views: {
          'navbar': {
            template: layoutNavbarTemplate
          },'sidebar': {
            template: layoutSidebarTemplate,controller: SidebarController,controllerAs: 'vm'
          },'core': {
            template: layoutCoreTemplate
          }
        }
      }
    ];
    
    angular.module(LAYOUT_MODULE,[])
      // eslint-disable-next-line angular/di
      .config(['$stateProvider',function ($stateProvider) {
        LayoutRoute.forEach((route) => {
          $stateProvider.state(route);
        });
      }]);
    
    export { LAYOUT_MODULE };

    模块划分

    通过划分模块实现最终目标:

    @H_502_12@
  • ng-hot-analyzer - 分析组件的声明与定位,主要包括importregister token的分析。最终汇总,实现模块定位 <--> 模块导出实例 <--> NG组件注册的图谱。

  • ng-hot-loader - 汇聚子模块操作,基于分析结果与对应模板,生成对应HMR代码

  • ng-hmr - 热更新具体实现。

  • 组件替换约定

    服务在angularjs内部属于单例,实例声明通过factory的方式,声明literal object服务。

    过滤器仅支持ng-bind使用。

    模板热替换目前采用较为粗放的容器定位策略,基于最近的ui-router view进行局部替换。

    指令热替换同样采用较为粗放的容器定位策略,通过路由模板替换实现。

    控制器统一使用ES6 Class声明,字段更新策略如下:

    @H_502_12@
  • [x] 删除字段

  • [x] 依赖注入服务,直接override

  • [x] 函数字段,直接override

  • [x] 通过控制器内声明shouldFieldUpdate方法来精确控制对应字段是否更新。

  • [x] 如果控制器未声明shouldFieldUpdate方法,默认判定策略是类型变化,类型出现变化即直接override

  • HMR示例

    if (module.hot) {
      module.hot.accept(['${descriptor.location}'],function () {
        ${translateImportType(descriptor)}
        $hmr.hmrOnChange('${capitalize(descriptor.category)}','${descriptor.token}',${descriptor.name});
        $hmr.hmrDoActive('${capitalize(descriptor.category)}',${descriptor.name});
      });
    };

    项目实现

    @H_502_12@
  • https://github.com/bornkiller...

  • https://github.com/bornkiller...

  • https://github.com/bornkiller...

  • https://github.com/bornkiller... 热替换DEMO

  • TODO

    @H_502_12@
  • 支持字符串声明控制器

  • 调整模板scope定位方式

  • 猜你在找的Angularjs相关文章