利用google closure管理javascript模块依赖
为什么80%的码农都做不了架构师?>>>
在web浏览器端管理javascript模块依赖,一直以来都采用直接引入script标签的方式,这种方式直观、一目了然。
项目说明
项目中有两个页面page1.html、page2.html,其中page1要引入三个模块a、b、c,page2需a、b、d, 这四个模块分别位于a.js、b.js、c.js、d.js中,其依赖为
c-->b(-->表示依赖于,下同),
d-->b,
b-->a
传统解决方式
从依赖分析,页面引用如下:
page1.html:
<html>
<head>
<script type="text/javascript" src="a.js"></script>
<script type="text/javascript" src="b.js"></script>
<script type="text/javascript" src="c.js"></script>
</head>
<body>...</body>
</html>
page2.html:
<html>
<head>
<script type="text/javascript" src="a.js"></script>
<script type="text/javascript" src="b.js"></script>
<script type="text/javascript" src="d.js"></script>
</head>
<body>...</body>
</html>
麻烦来了
项目经过演化、重构之后,从b模块中分出b1和b2模块,分别位于b1.js和b2.js中,而新的依赖为
b1-->a,
b2-->a,
c-->b1,
d-->b2
页面需修改为
page1.html:
<html>
<head>
<script type="text/javascript" src="a.js"></script>
<script type="text/javascript" src="b1.js"></script>
<script type="text/javascript" src="c.js"></script>
</head>
<body>...</body>
</html>
page2.html:
<html>
<head>
<script type="text/javascript" src="a.js"></script>
<script type="text/javascript" src="b2.js"></script>
<script type="text/javascript" src="c.js"></script>
</head>
<body>...</body>
</html>
缺点分析
这种js模块间的依赖重构影响到页面的标签引用,丧失了部分灵活性,并且需要手动维护,不能保证修改完全正确。
缺点:
- js重构与页面重构耦合增加;
- 开发效率低下;
- 引入多个script标签,增加http请求数量,延迟时间增加,损害用户体验;
- 人工维护,可能遗漏需修改页面,容易引入错误;
- 考虑到http请求数量问题,不能更细分模块
google closure的解决办法
google closure分两个阶段,a)开发或debug阶段,b)与发布阶段。
具体实现:在closure library中,模块的发布与依赖通过base.js中的goog.provide("...")和goog.require("...")实现,
例如,a模块所在的a.js中要发布a模块,在a.js中声明
goog.provide("a");
即可实现,a代表在项目中唯一id,推荐使用package的格式,
b依赖于a,在b.js中声明
goog.provide("b");
goog.require("a");
c依赖于b,在c.js中声明
goog.provide("c");
goog.require("b");
page1.html修改为:
<html>
<head>
<script type="text/javascript" src="closurepath/base.js"></script>
<script type="text/javascript" src="c.js"></script>
</head>
<body>...</body>
</html>
注意在开发阶段,因为各模块js是通过动态插入script标签实现,所以在c.js中代码需要进行一点小改动,将c.js中依赖于其他模块的js代码部分放入window.onload之类监听函数中,避免出现变量undefined错误。
到这里,开发者可能会有疑问,开发阶段动态插入script标签,那么各js文件路径怎么得到?其实在加载运行base.js中,还会插入deps.js,该文件中配置依赖信息,包括js文件路径(相对于base.js), 发布的模块以及依赖的模块。这个文件无需人工维护,在closure library 中有python脚本(caldeps.py)会帮助你维护这些信息,当模块依赖关系有变动时,运行该脚本即可。
让我们再回到之前的重构情景中,当b模块重构成b1和b2模块时,只需要调整各js中依赖(再运行caldeps.py脚本更新deps.js),而html无需改动。
下一步来到发布编译阶段,假如我们将最终合并编译的js文件命名为c.c.min.js,html需要做一点改动
page1.html为:
<html>
<head>
<script type="text/javascript" src="c.c.min.js"></script>
</head>
<body>...</body>
</html>
这里遇到开发阶段与发布阶段引用的js不同问题,该问题比较容易解决,可以使用服务端动态网页技术来解决,例如采用ssi标签,这里不做详细说明,请参考 http://wasd.vsm.com.au/ht_root/doc/env/
google closure的优点
- 提供模块依赖,不需人工管理依赖链(各个模块负责自己的依赖);
- 减少http请求数量;
转载于:https://my.oschina.net/jinker/blog/99314
利用google closure管理javascript模块依赖相关推荐
- 利用google closure依赖工具配置
为什么80%的码农都做不了架构师?>>> 为什么需要引入google closure 这边有一篇文章简单介绍了为什么要引入google closure,有兴趣的可看看这里. 什 ...
- 使用Google Closure DepsWriter生成JS依赖文件(二)
使用ClosureBuilder 可以压缩JS文件,减小JS的大小.但是,当使用未压缩的源码时,需要使用到goog.require()来匹配需要的命名空间并且在页面中追加<script>标 ...
- java单例模式深入详解_javascript 模块依赖管理的本质深入详解
本文实例讲述了javascript 模块依赖管理的本质.分享给大家供大家参考,具体如下: 模块模式定义 模块是'javascript'的一种设计模式,它为函数定义一个包装函数,并且该包装函数的返回值与 ...
- 用Maven管理JavaScript资源
Maven用来管理Java类库之间的依赖已经非常普遍了.最近有一直在做JavaScript的开发,就突然想提问自己是不是也可以考虑用Maven的机制来管理JavaScript的依赖. Google了一 ...
- es6 依赖循环_探索 JavaScript 中的依赖管理及循环依赖
我们通常会把项目中使用的第三方依赖写在 package.json 文件里,然后使用 npm .cnpm 或者 yarn 这些流行的依赖管理工具来帮我们管理这些依赖.但是它们是如何管理这些依赖的.它们之 ...
- JavaScript代码压缩工具UglifyJS和Google Closure Compiler的基本用法
网上搜索了,目前主流的Js代码压缩工具主要有Uglify.YUI Compressor.Google Closure Compiler,简单试用了UglifyJS 和Google Closure Co ...
- Google公开其JavaScript工具:Closure Compiler
Google Code官方博客今日开源了一个Google内部使用的JavaScript工具:Closure Compiler.这个工具在Google的Gmail,Google文档和Google地图中都 ...
- google closure
自从Google释出了其Closure的JavaScript库以来,越来越多人希望了解它与Ext JS比起来究竟怎么样.由于我也属于这些想知道的人,所以我希望从我自己的角度来回答此问题,希望并不会由此 ...
- 推荐好用的JavaScript模块
2019独角兽企业重金招聘Python工程师标准>>> 译者按: 作者将自己常用的JavaScript模块分享给大家. 原文:? JavaScript Modules Worth U ...
- 导出库的版本_了解 JavaScript 模块系统基础知识,搭建自己的库
我想很多"前端工程师"都听过说过 "JavaScript 模块",那你们都知道如何处理它,以及它在日常工作中如何发挥作用吗? JS 模块系统到底是什么呢 随着 ...
最新文章
- R语言ggplot2可视化使用ggridges包可视化山脊图(Ridgeline Plots):山脊图(Ridgeline Plots)应用场景、受试者口服茶碱的之后观察茶碱的浓度变化的山脊图
- 白月黑羽教python excel_发布程序
- 用Python3、NetCore、Shell分别开发一个Ubuntu版的定时提醒(附NetCore跨平台两种发布方式)...
- 这款超火的游戏,AI只用4小时,就秀出了人类花1年才能达到的水平
- 全球及中国彩超市场销售渠道与投资竞争力研究报告2022版
- MySQL记住密码_技术分享 | mysqlsh 命令行模式 密码保存
- JavaScript实现快速傅立叶变换FFT算法(附完整源码)
- Hadoop从0开始 (安装配置:转) (一) - 沐魇
- 计算机WIN7动态硬盘分区,win7硬盘分区教程
- 《Don't make me think 》关于Web可用性的三大定律
- 51Nod 1637	幸运数字转换(思维)
- ffmpeg源码简析(十三)ffmpeg API变更 2009-03-01—— 2017-05-09变更
- T60 Fan Error 解决办法.转自ZOL产品论坛-作者zxymb
- Java进阶之路对标阿里P6(8)——分布式理论及框架设计Netty
- [转载] 细看名字服务中心
- retrofit设置单个请求的超时
- 打开EXCEL总提示 您尝试打开的文件*.xls格式与文件扩展名指定的格式不相符
- ZEMAX | 照明设计的理论背景与概念
- NSAT-2000三极管自动测试系统
- ssas脚本组织程序_SSAS系列——【01】准备知识
热门文章
- java aes加密 cbc_AES加密,CBC模式,0填充
- 山西计算机职业学校排名2015,2015山西专科学校排名及排行榜
- 多示例代码:go语言中循环练习题,不包括break,continue
- 用keil怎么擦除_环氧树脂结构胶怎么清洗 结构胶弄到衣服上怎么洗掉
- 服务器 python cant open file_如何删除分析*。gcda:无法打开python virtualenv builder出错?...
- 正则表达式在NLP的基本应用
- Go by Example练习
- 【Java集合的详细研究4】Java中如何遍历Map对象的4种方法
- sql语句有没有怎么优化的空间,这条语句在我这里执行是死机
- Flex父子窗口传值