前端重构之路01

在 CodeInsight 开发告一段落之后,CTO 大人找到我说要想一个把 Coding.net 的前端拆分重构的方案,于是我从一个欢脱的开发状态开始切换到要面对一句魔咒的考验。

动态语言一时爽,代码重构火葬场。

不管怎么样,先从梳理现状开始。

Coding 前端使用 Angular 构建,前端工程化还是使用合并文件打包的方式,并没有引入 CommonJS 之类的模块化开发方式,作为一个 SPA 网站,随着网站规模的增大,前端代码开始越来越臃肿,开发体验也直线下降,这是我们考虑重构的原因。

所以首先我们要想清楚重构要解决的问题

  • 代码打包拆分,避免所有功能模块打包到单一的文件
  • 引入 CommonJS 做到更清晰的模块化
  • 边开车边换轮子

要做到最后一点尤其困难,但这也是我们能否顺利重构的关键,重构不是重写,所以如何在现有代码基础上重构,并且还要和当前的开发进度无缝衔接起来就是我们所要面临的一个挑战。

好消息是我们使用了 Angular 保证了我们的代码分 Module 有了一层封装,不至于太过散乱。作为一个 SPA 网站,前端路由已经很好的分离出了各个功能模块。我们用到了 Grunt,虽然有点过时,task 写得有点复杂,但是提供了一个工程化的切入口。

经过小伙伴们几轮讨论之后,最终确定了一套比较靠谱的方案:

  • 按照功能模块重新整理/拆分代码
  • 保持作为一个 SPA 网站,按照路由懒加载功能模块

后一点是我们这套重构思路的核心,在这之前我们有考虑把每个功能模块拆分出独立的单元来跑,但是为了保证“边开车边换轮子”,重构必须是一个快速迭代的过程,不能说等到某一个完整的功能模块单元重构完了再去整合到现有的代码,这种重构方式将是一个漫长耗时的过程,并且风险也很大。

保持 SPA,引入懒加载,我们可以快速将这种架构调整整合到现有代码中去,验证是否可行,之后的重构过程就可以细化到每一个 controller,做到“边开车边换轮子”。

功能模块拆分

这一步很简单,Coding 网站的功能模块已经比较清晰了,比如冒泡,任务,搜索等等,我们只需要确立一套统一的目录结构和命名空间规范来重新整理代码,得益于 Angular 的依赖注入机制,之前的代码逻辑完全可以保持不变,对于那些独立的模块,这个重构过程基本上没有什么引入 Regression Bugs 的风险,重构一个模块只是修改命名空间而已。

我们约定:

  • 重构的每个 controller, service 等等都有自己的命名空间(规范)
  • 每个功能模块定义自己的路由
  • 每个功能模块有一个唯一的 module 注入所有依赖

比如重构后的冒泡可能是类似这样的结构:

tweet/
├── tweet-list.controller.js
├── tweet-list.html
├── tweet-topic.controller.js
├── tweet-topic.html
├── tweet.module.js
└── tweet.routes.js

tweet.routes.js 将会指定懒加载 tweet.module.js。

Webpack 懒加载

为了做到代码打包拆分,我们使用懒加载的方式,当导航到对应的功能模块时才去加载相应的功能模块代码,引入 webpack 一并实现了对 CommonJS 的支持以及 Lazy Load。

现有的 Angular 路由已经很好的分离出了功能模块入口,所以我们只要把这个路由文件当做一个切入点,作为 webpack 的打包入口文件,由这个入口文件引入的所有依赖就都可以使用 CommonJS 的模块化方式了,也就是说我们所有重构的代码自然而然就可以迁移到使用 CommonJS,在这里 webpack 将作为一个完美的粘合剂,衔接现有的代码和重构后的代码,这里通过一个简单的路由来看一下是如何做到的。

./tweet/tweet.routes.js

    $routeProvider.when(‘/pp/:region?‘, {
        templateUrl: require(‘./tweet-list.html‘),
        controller: ‘TweetListController‘,
        title: ‘冒泡‘,
        resolve: {
            lazyLoader: function($q, $ocLazyLoad) {
                var defer = $q.defer();
                require.ensure([], function() {
                    var module = require(‘./tweet.module‘);
                    $ocLazyLoad.load({ name: module.name });
                    defer.resolve(module);
                });
                return defer.promise;
            }
        }
    });

Angular 的路由支持异步加载,require.ensure 是 webpack 用来异步加载回调函数内部指定的 tweet.module.js,这个 module 注入了 tweet 这个功能模块的所有依赖,比如TweetListController

‘use strict‘;

var angular = require(‘angular‘);

module.exports = angular
    .module(‘tweet‘, [
        require(‘./tweet-list.controller‘).name,
        require(‘./tweet-topic.controller‘).name,
    ]);

最后我们用到了 ocLazyLoad 来注入这个异步加载的 module。

grunt-webpack

新引入的 webpack 可以很容易的整合到我们现有的开发流程里面去,使用 grunt-webpack 就可以把 webpack 作为一个新的任务给 grunt 调用,所以我们可以独立 webpack 的打包编译流程,并且作为一个子任务插入原来的编译流程,而不影响原来的开发/发布方式。

gruntfile.js

...

    webpack: {
      dev: {
        entry: {
          ‘routes‘: [‘./src/routes.js‘],
        },
        ...
      },
      prod: { ... }
    }

grunt.registerTask(‘server‘, [..., ‘webpack:dev‘, ...]);
grunt.registerTask(‘build‘, [..., ‘webpack:prod‘, ...]);

...

公用模块

对于独立的,不被其他地方依赖的 module,重构可以很方便,但是对于公用的模块,虽然可以重构这个模块,但是要更改所有针对这个模块的引用,牵涉到的代码就有点不受控制了。

所以我们才要约定所有重构的模块都会有自己的命名空间,对于那些公用的模块,迁移到新的命名空间,同时会保留之前的代码,直到我们重构其他功能模块到某个时间点,可以确定没有模块依赖这些被保留的公用模块,再去清理,这样在前期会有一部分代码冗余,但是保证了我们重构的质量和进度。

至此,Coding 前端开启了重构之路,相信 http://Coding.net 将会逐步带来更好的体验。

原文地址:https://www.cnblogs.com/HHHAI/p/11539959.html

时间: 2024-10-13 02:55:06

前端重构之路01的相关文章

Hybird框架UI重构之路:五、前端那点事儿(HTML、CSS)

上文回顾 :Hybird框架UI重构之路:四.分而治之 这里讲述在开发的过程中,一些HTML.CSS的关键点. 单页模式的页面结构 在单页模式中,弱化HTML的概念,把HTML当成一个容器,BODY中显示的主体内容才是页面,一个HTML容器中可以存放1个或者多个页面,每个页面放置于section中.而一个页面(section)中必有主体内容(content),也有可能包含头部内容.底部内容,甚至一些侧滑菜单等. 所以,以我们通常看到的一个移动应用的界面中包含了顶部Title和主体内容的页面代码如

Hybird框架UI重构之路:六、前端那点事儿(Javascript)

上文回顾 :Hybird框架UI重构之路:五.前端那点事儿(HTML.CSS) 这里讲述在开发的过程中,一些JS的关键点. 换肤 对于终端的换肤,我之前一篇文章有说了我的想法. 请查看:http://www.cnblogs.com/lovesong/p/4122262.html iscroll的问题 1.使用iscroll的页面里面有表单元素,当键盘弹出再缩回后,页面拖不到最顶地方. 这个在android上总出现,使用的iscroll版本是4.2.5. 这原来是个很棘手的问题,导致了有input

Hybird框架UI重构之路:四、分而治之

上文回顾:Hybird框架UI重构之路:三.工欲善其事,必先利其器 上一篇文章有说到less.grunt这两个工具,是为了css.js分模块使用的.UI框架提供给使用者的时候,是一个大的xxx.js.xxx.css,但在开发时候,必须划分模块. CSS模块划分 1.variables.less 这里面是一些样式的变量.函数 例: 字体: @baseFontSize: 20px; 圆角: .rounded-corners (@radius: 5px) { border-radius: @radiu

我的web前端自学之路-心得篇:我为什么要学习web前端?

时光如流水,转眼间,自己已经是大三的学长了,看着一个个学弟学妹,心中有种莫名的感觉,很怀念大学的前两年时光,但也很憧憬着自己的未来,自己将要去经历很多从未经历的事.我是我们学校信科院的一名学生,在编程方面,一开始只是接触到了C语言,但是c语言对于我来说并不友好,也并不是那么的好学,所以自己对程序不是很有兴趣,但一个偶然的机会,我接触到了web前端,看着我的一个大牛同学用前端 所涉及的语言写出了一些很棒的程序,于是就产生了一种很想学习前端的想法和很想把前端做的完美的渴望,于是,就开始了我的前端之路

百度前端技术学院任务-01

这两天发现了一个很不错的学习前端的地方:百度前端技术学院. 里面有不同类型的任务,任务之间的难度是递增的,很适合作为练习. 下面是任务-01的代码(并没有涉及到CSS): <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>百度前端技术学院任务-01</title> </head> <bod

前端这条路,我们该何去何从

原文地址:https://www.usblog.cc/blog/post/justzhl/前端这条路,我们该何去何从 这样,因为你会发现,如果你觉得某个教程写的不好,那可能很难找到一个教程适合你的,不是因为别人教程写的差(除非特别那种的),而是你该问问自己,是否有静下心来认真去看.找教程我给一个建议,建议你刚入门不要去看大牛的作品,最好看那些菜鸟或者和你技术差不多的,因为他们更容易让你懂,大牛的作品一般里面会涉及到很多东西,你去看的话,难免受打击,等到你了解部分之后再去品味大牛的作品. 当然菜鸟

重构之路 组合查询之传参+存储过程

上篇博文给大家一起讨论了实现组合查询的一种方法,即在U层将select语句的where子句部分组装好,赋给一个字符串变量,传到D层然后与select子句组成完整的sql语句,之后执行,返回查询结果,就是这么简单,但是博文的结尾也留下了一个疑问,这种方法的安全性有点欠佳,有没有相对好一点的办法呢? 答案是肯定的,这次我们一起来看看我实现的另一种方法.首先给大家简单介绍一下这种方法的思路,其实也比较简单,最初我是想在程序代码里写sql查询语句的,然后将组合查询的各个条件的值当做实体参数(现在实体层定

重构之路 组合查询之传递SQL字符串

既然是使用VB.NET语言对机房收费系统进行重构,那么无可避免的要去解决组合查询的问题,在VB版的实现中这是一个难点,不过大家还是依靠自己或者共同的智慧解决了这个看似复杂的问题. 如今编程的语言不同是一方面,更重要的是系统的结构不一样了,采用了三层架构去实现系统,这样一来就要考虑组合查询的在三层结构中的实现方法.当然,组合查询的核心办法是不变的,都是通过将查询的各个条件组装成SQL查询语句的where子句来实现的,问题就是这个where子句的组装在哪里完成? 如果放在U层完成,那么我们向下传递的

重构之路 峰回路转

其实敲代码的时间并不是太长,往往调试的时间很长,登录早就敲完了,可是迟迟运行不出想要的结果,甚至不能完整的从U层运行到D层,实在是让人揪心,先后请了三位高手帮我调试,愣是没有发现错误在哪里. 在今天的上午,问题有了转机,终于是将登录完整的运行下来了,也得到了预期的反馈,因此在下午的时候就再次尝试加入配置文件,没想到一个意想不到的警告信息让我相信之前的判断是正确的,于是顺藤摸瓜终于找到了问题的根源,万万没想到,一系列问题的答案竟是如此简单,让人哭笑不得. 先来分析分析报错信息,以便找到解决问题的线