- 浏览: 1460254 次
- 性别:
- 来自: 上海
文章分类
最新评论
-
luhouxiang:
写的很不错,学习了
Extjs 模块化动态加载js实践 -
kingkongtown:
如果想改成淘宝后台那样,可以在编辑器批量上传图片呢?
kissy editor 阶段体会 -
317966578:
兄弟我最近也在整jquery和caja 开放一些接口。在git ...
caja 原理 : 前端 -
liuweihug:
Javascript引擎单线程机制及setTimeout执行原 ...
setTimeout ,xhr,event 线程问题 -
辽主临轩:
怎么能让浏览器不进入 文档模式的quirks模式,进入标准的
浏览器模式与文本模式
yiminghe at gmail.com
Because there rarely exists articles on this topic, I will write in English, this article can also be found at Google Doc . Forgive my chinglish and syntactic error if you are interested.
Preface
About how to use closure compiler, you can refer to: 使用closure compiler高级模式
About module, you can refer to : 模块加载
,模块设计
Part 1: Introduction
In this article, I will show how to customize your own module compiler using closure compiler’s APIs provided.
Goals
Combiner
Scene
There exists some modules, they may depend on each other, but cyclic dependence will be left for later discussion.
For example:
Event module in event.js:
KISSY.add(“event”,function(){ //do your stuff and return event module return xx; },{ requires:[”event/base”,”event/ie”] });
event/ie module in event/ie.js :
KISSY.add(“event/ie”,function(){ //do your stuff and return event/ie module return yy; },{ requires:[“event/base”] });
There also exists dom, dom/ie …. , infrastructure module and some UI modules, complicated UI modules may depend on dom, event and infrastructure module.
Expected
This combiner tool can generate file with modules you want exactly, no more and no less. for example : if you want a simple slide ui module ,and this module only depends on dom and infrastructure, it simply shows some effect (no interaction),so event module is not needed ,you can run :
combiner requires=slide output=slide_standalone.js
Done! That’s it. slide_standalone.js is generated, and only includes dom/ie, dom, infrastructure, slide in one file .Invoker does not need to know which depends on which . At the same time it can accelerate your application (less http connection);
Compiler
Scene
If you look closely at the above part, you will notice some information redundancies, for example: a module file is named as dom.js, and in this file, you have to say
KISSY.add(“dom”,function(){},{…});
It would be better: if in dom.js:
KISSY.add(function(){},{…})
The module’s name is same with module’s file name. If dom.js only contains dom module, it’s fine, some module loaders can solve this problem by attaching file name with module name when loading module files dynamically. But when you combine dom.js with some other module into one file, it’s impossible to associate a single module’s factory function with corresponding module name.
Expected
This tool will automatically transform original module definition code by adding module name which can be obtained from module’s file name.
For example: dom.js contains dom module:
KISSY.add(function(){},{requires:[“dom/base”,”dom/ie”]});
After transformation, the code will be:
KISSY.add(“dom”,function(){},{requires:[“dom/base”,”dom/ie”]});
“dom” comes from dom.js
Now you can be free to use combiner to combine multiple modules into one file.
Part 2: Using closure compiler
Closure compiler provides some unpublished APIS, they can be used to customize your own module compiler, it means you do not need to code everything from scratch ,such as lexical, syntactic parser (actually closure compiler does not code from scratch neither, it uses rhino but exports a set of better API) and serialize.
Parse
The first thing is parsing, if you want to do code analysis, you have to parse code to an AST(abstract syntax tree ). In closure compiler it does not provide a simple api (or I missed) ,here is what i do :
/** * get root node of ast from javascript source string * * @param {String} code javascript source * @return {Node} root node of ast corresponding to source code */ public static Node parse(String code) { //just want to use Compiler as one parameter for CompilerInput's getAstRoot method Compiler compiler = new Compiler(); CompilerOptions options = new CompilerOptions(); // Advanced mode is used here, but additional options could be set, too. CompilationLevel.WHITESPACE_ONLY.setOptionsForCompilationLevel( options); compiler.initOptions(options); //get a fake file representing input source code //CompilerInput need JSSourceFile as type of input for constructor JSSourceFile input = JSSourceFile.fromCode("parse.js", code); CompilerInput ci = new CompilerInput(input); //here we go , finally get root node of ast return ci.getAstRoot(compiler); }
For example (from closure compiler’s wiki)
x=’string’
AST correspond to the above code :
After you get AST ,you can do anything about this tree ,just as DOM tree with different operation API. In reality closure compiler applies multiple optimization passes to AST and changes it dramatically in the end.
Serialize
Finally AST is ready, you want to serialize it to code file, I still do not find a direct way, it seems closure compiler associates everything with Compiler class. I have to construct a Compiler Object:
/** * get javascript source from root node of its ast * * @param {Node} jsRoot root node of javascript source's abstract syntax tree * @return {String} corresponding javascript source */ public static String toSource(Node jsRoot) { //here,just want Compiler's toSource method Compiler c = new Compiler(); CompilerOptions options = new CompilerOptions(); //just need option,no real effect CompilationLevel.WHITESPACE_ONLY.setOptionsForCompilationLevel( options); options.prettyPrint = true; c.initOptions(options); Compiler.CodeBuilder cb = new Compiler.CodeBuilder(); //finally can get source code by ast c.toSource(cb, 0, jsRoot); return cb.toString(); }
Part 3: Customize module compiler
This part is short. Because it simply combines the above two parts together:
1. Read code file and transform it to AST, add the missing module name by module’s file name.
2. Track current module’s dependencies and recursively process them.
3. After solve current module’s dependencies, serialize current module’s final AST to file.
4. If you want, you can call closure compiler’s optimization method or just leave it to external invoke later.
Part 4: Usage
To Be Continued
Part 5: Summary
Using closure compiler you do not need to code everything from scratch, you can also process code file deeply according to your own business logic.
I hope there will be more articles about closure compiler’s implementation. It’s a fantastic library for F2E.
发表评论
-
continuation, cps
2013-09-12 16:49 2791起 随着 nodejs 的兴起,异步编程成为一种潮流 ... -
一种基于匹配回朔的 css3 选择器引擎实现
2013-05-07 20:40 3401一种基于匹配回朔的 css3 选择器引擎实现 介绍 C ... -
cubic-bezier 模拟实现
2013-01-05 16:34 14089cubic-bezier 曲线是 css3 动画的一个重要基石 ... -
构建前端 DSL
2012-10-11 22:10 5359目前在传统的软件开 ... -
Get cursor position and coordinates from textarea
2012-04-10 20:50 5037最近需要从 textarea 中获 ... -
兼容 ie 的 transform
2012-02-23 14:00 6424css 2d transform 是 css3 引入的一个新的 ... -
promise api 与应用场景
2012-02-07 17:34 7375promise 是 commonjs 社区中提出的异步规范,其 ... -
closure compiler 代码优化实例
2012-01-08 03:23 2829closure compiler 可以进行不少有意思的优化 ... -
write html parser
2011-12-01 02:48 2916首先需要声明 html 不能用正则表达式来直接匹配进行内容抽取 ... -
获取剪贴板数据
2011-11-07 23:31 6447兼容性: 获取剪贴板数据这块各个浏览器间存在很大的 ... -
url 映射问题
2011-11-07 21:52 3221背景 url mapping 我最早知道是作为 j ... -
tip:如何原生播放声音
2011-10-19 12:45 2977如果不想考虑浏览器间 ... -
转载:瀑布流布局浅析
2011-09-29 19:02 2845简介 如果你经 ... -
cross domain request
2011-09-29 18:39 2845场景 跨域请求是随着 ... -
基于多继承的树设计
2011-09-18 03:42 2268分类 树是一种常见 ... -
caja 原理 : 前端
2011-09-01 16:48 7047作为前端开放的基础安全保证,caja 是目前比较合 ... -
tokenization of html
2011-08-29 22:38 2786html 符号解析问题 场景: 在页面上输出包 ... -
ie 下 cloneNode 导致的属性克隆
2011-08-24 16:10 2475这个还是很值得记下,一直存在的很大隐患终于解决,由于在 ie& ... -
循环引用下的深度克隆
2011-08-04 20:39 2305深度复制和浅度复制 是当初初学 c 遇到的第一批问题,似乎使 ... -
模块的静态与动态循环依赖
2011-07-25 03:43 3279场景: 循环依赖 我是不支持的,但现实中似乎又确实需 ...
相关推荐
Customize Rules 使用附件中的 myrules 中的内容覆盖 Customize 的内容然后保存
### 使用SharePoint Designer定制SharePoint 2010列表表单 #### 主讲人简介: 本次分享由Asif Rehmani主讲,他是一位资深的SharePoint Server MVP、微软认证讲师(MCT),同时也是SharePoint培训及解决方案架构师。...
Getting Started with OpenCart Module Development gives you step-by-step explanations and illustrations on how to clone, customize, and develop modules and pages with OpenCart. This book shows you how...
2:#customize_compiler_for_nvcc(self.compiler) 110行 2、执行Makefile文件中的 python setup.py ,build_ext --inplace 3、注释掉nms_wrapper.py中的 17行 # from nms.gpu_nms import gpu_nms #
《前端开源库 Customize Engine Handlebars 深度解析》 在现代前端开发中,自定义引擎扮演着重要的角色,它们允许开发者根据特定需求定制化处理模板、数据和逻辑。其中,“customize-engine-handlebars”是一个专注...
TPaxCompiler, TPaxProgram and TPaxPascalLanguage are Delphi components that allows you to embed the paxCompiler into Delphi, Kylix or Borland C++ Builder application so you can customize and extend ...
在压缩包中的`customize-tabwidget`文件可能是项目的主要源代码文件,包含实现上述功能的C++代码。开发者可能使用了Qt Creator作为IDE,编写了`.cpp`和`.h`文件,定义了自定义的`TabWidget`类,并在`main.cpp`中实例...
在"[iOS开发教程-2]Customize that UIViewCell – Part 1: Using Interface Builder"这篇教程中,我们将深入探讨如何利用Interface Builder来设计并定制自定义的UITableViewCell。 首先,Interface Builder是Xcode...
Building Tools with GitHub Customize Your Workflow 英文mobi 本资源转载自网络,如有侵权,请联系上传者或csdn删除 本资源转载自网络,如有侵权,请联系上传者或csdn删除
然而,软件在使用过程中难免会出现一些问题,比如标题所提到的“不能启动Customize Perspective”就是一个常见的故障。本文将详细解析这个问题及其解决方案。 "Customize Perspective"是Eclipse和MyEclipse中的一个...
标题 "myeclipse_2014_customize_perspective修复bug" 指向的是一个针对MyEclipse 2014版本中自定义透视图(perspective)问题的修复工具包。MyEclipse是一款功能丰富的Java集成开发环境(IDE),它是Eclipse的商业...
customize sort.txt
Building Tools with GitHub Customize Your Workflow 英文无水印pdf pdf所有页面使用FoxitReader和PDF-XChangeViewer测试都可以打开 本资源转载自网络,如有侵权,请联系上传者或csdn删除 本资源转载自网络,...
【标题】"前端开源库-customize"涉及到的核心概念是前端开发中的自定义化框架,它为开发者提供了一种创建可定制引擎的能力。在现代Web应用中,为了满足不同项目的需求和提升用户体验,开发者往往需要对现有的开源库...
customize_service.py
Module 6: Customizing Cube FunctionalityThis module describes how to customize a cube.Lessons Implementing Key Performance Indicators Implementing Actions Implementing Perspectives Implementing ...
《前端开源库 Customize Engine Uglify 深度解析》 在前端开发中,优化代码是提高网页性能的关键环节之一。其中,代码压缩是优化的重要手段,它能显著减少文件大小,加快页面加载速度。而`customize-engine-uglify`...