让 Angular 1.x 跟上时代的步伐

锲而不舍
• 阅读 4355
本篇技术博客来自有着化腐朽为神奇能力的,Worktile 技术牛人Web 总监 @徐海峰 大神的分享~满满的干货,你值得拥有!

Worktile 的前端构建之路

2013年,那时候 Angular.js 才刚刚兴起,我们大胆了选择了当时看来比较新的技术,经过 3年的技术积累,Worktile 团队基本上把 Angular 1.x 可能踩得坑都踩了一遍,我们自己也写了一些关于 Angular.js 的插件,可以说团队目前采用 Angular.js 开发项目没有太大的技术难点。

Worktile 刚开始的时候是自己用 Node.js 写脚本进行合并和压缩 JS 代码,现在想想当时是多么的原始,后来切换到 Grunt 工具进行简单的合并压缩,编译 LESS,使用 Grunt 一段时间之后发现其打包的速度实在太慢,当做企业版的时候就切换到 Gulp 上了,在速度上的确有质的飞跃,使用 Gulp 的时候我们做了稍微复杂一点的任务构建,开发环境自动监控 LESS 代码变化等等,目前一直使用的是 Gulp,我们也在不停的跟随时代的变化,保持自己永不落后,所以在一些边缘项目上也会使用最近比较火的框架、类库或者工具。

Angular 1.x 使用模块化

大家都知道 Angular 1.x 有自己的一套模块机制,定义一个模块如下:

angular.module("module.abc", ["module.def"]);

上面的代码定义了一个 "module.abc" 模块,并且 "module.abc" 依赖 "module.def" 模块,然而这个模块机制很容易写出有文件顺序依赖的代码,比如 a.js 文件定义了一个 "module.abc" 模块,b.js 没有定义自己的模块,而是直接使用了 "module.abc",这样 b.js 必须在 a.js 加载之后才能工作,如果有了文件的先后依赖,合并的时候就需要手动维护一个顺序列表。所以说 Angular.js 的模块机制没有解决JS文件依赖关系和JS文件异步加载的问题。

现在大家谈起前端的模块化,之前很多选择让人眼花缭乱,比如 CommonJS,AMD(Require.js),CMD(Sea.js),UMD,从未来标准的角度首选 ES6 Modules,不要为我为什么,关于如果在Angular 1.x 使用 ES6 的 Modules,网上有很多文章介绍怎么使用,推荐一篇前端大叔徐飞的博客,这里就不详细的一一展开了。

谈到这里大家或许会问:如果使用 Require.js ,在开发阶段是每个 JS 都动态加载的,生产环境根据 r.js 这样的工具合并成一个或者多个JS来提高前端性能,如果使用 ES6 的Modules,开发环境和生产环境是怎么样的呢?

在生产环境每个js文件都动态加载显然不是最合适,中小型项目基本不需要动态加载,我觉得合并成1个或者多个js是最好的解决方案。

那怎么合并 ES6 Modules 的JS,这类的工具很多很多,包括下面要介绍的 Webpack(目前1.x版本还不能原生支持,需要借助 Babel 工具),基本上开发环境也使用合并之后的 Bundle JS,调试使用 Source Map 工具,如果你开发环境就不想使用合并之后的,systemjs也是个不错的选择。

ES2015(ES6)

如果可以,尽快使用,因为他是 Javascript 未来的标准,作为一个前端技术人员,如果不能与时俱进那就只能等着淘汰,ES 2015 有着现代语言的语法,解决了 Javascript 语言层面上的很多问题,有 Class,Modules,Arrows,Template Strings 等等一系列的新特性,用了之后腰不酸腿不痛(请一定要相信我),最终的目的只有一个:提高生产力,让代码更简单,当然现在很多浏览器还不能原生支持 ES2015,没关系,有Babel在,生产环境转换好成 ES5 不是问题。

其实 ES 2015 的新特性数也能数出来,稍微花上 1 天就全学会了,推荐2个地址:

Webpack

Webpack 是最近1-2年来非常火的构建工具,如果说前端工程师没有听过或者尝试下 Webpack ,简直会被嫌弃,当然工具之所以火当然有他的道理,在我看来他能解决很多模块化和工程化的问题,提高生产力,如果你还不知道 Webpack 是什么,赶紧花几个小时去了解下,了解之后不要不了了之,结合自己的项目,切换到 Webpack 是否可行,如果可行,接下来怎么完美过渡,即使目前不用,下一个项目开始的时候试着尝试下。

Webpack 的优点:

  • 支持CommonJS 和AMD 模块,ES 2015 Modules 在 2.0 中将会原生支持,这个问题不大,因为我们肯定要使用 Babel 的;
  • 模块加载器,能够处理一切资源,包括 CSS,LESS,Image,JSON 等等,比如使用 babel-loader 加载器让我们能够用ES6的语法来编写代码;
  • Code Spliting,可以通过配置打包成多个文件,有效的利用浏览器的缓存功能提升性能,并且能自动抽取多个入口公用的代码;

让 Angular 1.x 跟上时代的步伐

插件机制提供了更多扩展功能,弥补 Loaders 的不足,比如自带的 UglifyJsPlugin 压缩代码。

Angular 1.x + ES2015 + Webpack Seed

说了那么多,我都有点烦了,直接上代码 https://github.com/why520craz...

这是我写的一个怎么使用 Angular 1.x + ES2015 + Webpack 的一个示例项目,基本上是我目前水平觉得比较好的组织形式了,里面涵盖了:

  • 使用 ES6 Modules 进行 Angular 1.x 的模块化开发;
  • 使用全组件化开发一个简单的 Angular 1.x 单页项目;
  • 使用 Webpack 合并 JS,CSS,Image 等一切静态资源;
  • 包管理工具使用 NPM,任务的启动脚本使用 NPM Scripts;
  • 使用 Webpack 的 CommonsChunkPlugin 将引用的第三方类库单独打包成一个独立的 bundle,并把多个入口公用的JS抽取出独立的 bundle;
  • 使用 HtmlWebpackPlugin 插件生成入口的HTML文件,并把打包之后的JS和CSS引入到HTML中,不需要手动添加 scripts 标签和 style link;
  • 使用 ExtractTextPlugin 插件把 CSS 抽取成独立的文件,当然你也可以不这么做,直接放在 JS 中;
  • 使用 postcss 处理样式的兼容性问题,autoprefixer 自动追加前缀等。

Webpack 还有一些更高级的特性没有在示例中展现,比如通过dllplugin只将有变化的JS生成不同的 Hash,充分利用浏览器的缓存,频繁打包部署后,没有改动的类库将不会重新生成。

前端开发远不止于此,有人总结了前端开发的四个阶段:

  • 库/框架选型;
  • 简单构建优化;
  • 模块化开发;
  • 组件化开发与资源管理。

大部分团队还是停留在第二第三阶段,每个阶段的实现都有很多种选择。

如果只想达到第二阶段,那么选择一个压缩合并工具几分钟可能就能实现,具体任务是使用 Grunt,Gulp,还是 NPM Scripts 都可以;

第三阶段就需要代码级别的支持,选择 Webpack 原生支持 CommonJS,AMD 写法,不需要单独引入 Require.js 或者 Sea.js 这样的类库, 省去了很多麻烦,你也可以选择其他的支持模块化的构建工具:systemjs,Browserify, 或者rollup;

第四阶段的组件化开发和资源管理暂时就不讨论了,关于是全组件开发和半组件开发也有很多争议。

总结

时至今日,谈起 Angular.js ,或许有些人都觉得有些过时,人人都在谈 React,Vue。当然 Angular 2 经过一些波折之后也在逐渐走进我们的视线,其实最终哪个框架会一统天下谁都没法预料。但也有些前端大牛认为 Angular.js 在某些行业或者企业才刚刚兴起!

不得不承认 Angular 1 有很多问题,如果你的项目之前选择的是 Angular.js ,不是一拍脑袋就升级 Angular 2 的,即使不升级,我们也可以在 Angular 1.x 的基础上做一些工作来适应未来的变化,慢慢的哪一天你就会突然发现升级就是那么的简单。

希望这篇文章能够激起大家永远保持积极向前追求完美代码的心,不仅对自己的成长也会对公司带来无限的价值。对了!虽然Webpack 只是一个工具,但目前来看应该是个不错的工具,值得前端的朋友去学习,因为使用了他的确使前端的开发更简单了。

最后的内心OS篇

其实这篇文章来源于我在公司内部的一个分享前端构建工具 - Webpack

分享的时候主要是现场撸代码,通过博客的话就不好展现了,所以我基本上没有介绍 Webpack 入门的一些用法,并且网上已经有很多大牛的分享,推荐大家看一下Webpack 教程资源收集,这里面基本涵盖了各路大神,从入门到精通全看一遍即可, 如果你的英文足够好,请直接看 Webpack 官方文档~

Worktile 官网:worktile.com

点赞
收藏
评论区
推荐文章
blmius blmius
4年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
美凌格栋栋酱 美凌格栋栋酱
7个月前
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Jacquelyn38 Jacquelyn38
4年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
PHP创建多级树型结构
<!lang:php<?php$areaarray(array('id'1,'pid'0,'name''中国'),array('id'5,'pid'0,'name''美国'),array('id'2,'pid'1,'name''吉林'),array('id'4,'pid'2,'n
Wesley13 Wesley13
3年前
Java日期时间API系列36
  十二时辰,古代劳动人民把一昼夜划分成十二个时段,每一个时段叫一个时辰。二十四小时和十二时辰对照表:时辰时间24时制子时深夜11:00凌晨01:0023:0001:00丑时上午01:00上午03:0001:0003:00寅时上午03:00上午0
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Python进阶者 Python进阶者
1年前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这