Sencha Touch 手机移动开发框架 HTML5 项目压缩方案;
Sencha Touch框架生成基本项目目录结构
Index.html/
App.js
App.json
/touch[sdk]/
/Sencha-touch.js
/src
Resources/
App/
app.js以及app.json 是程序的入口点及基本加载配置;
/touch[sdk]
sencha-touch[debug|min...].js 是 SDK 文件
/src 这里是存放组件的位置
Resources/用于存放 样式及图片等资源文件;
app/用于存放我们编写的程序源码;
压缩优化目标
把app/ , app.js , sdk[touch/sencha-touch.js], components[touch/src]分开压缩
再对app/ 各自模块进行压缩!
Sencha Touch compile编译研究
>sencha compile \
>[-cl=touch/src,app] //这个不必写,不然生成出来的文件,会很大,估计是重复拼接的原因.
>-ig=app.js,app/view //这里可以写文件,或是文件夹都可以
>concat –yui jsoutfile.js
以上需要具有 Sencha touch 编译命令行环境下运行;
按需加载压缩方式:
获取依赖组件命令:
sencha compile –cl=touch/src,app meta –filenames –out filenames.txt
将获取的列表中把 app.js, app/下所有脚本去除;
采用 YUI Compressor加密压缩这些dependencies文件合并后的文件; 采用批处理命令先合并为一个大文件;
Union.bat
@echo off
set /p outFile=请填写输出文件名:
set /p fList=请填写合并列表文件:
for /f %%i in (%fList%) do (
for /f "delims=" %%j in (%%i) do echo %%j >> %outFile%
)
java -jar D:\software\YUI-Compass\yuicompressor-2.4.2\build\yuicompressor-2.4.2.jar --type js --charset utf-8 %outFile% -o %outFile%
这种方法,会出现汉字乱码,会出现双引号异常.
//修改
要不出现乱码,及双引号问题,只能copy命令:
Copy命令可以拷贝其他文件夹的文件, 但只支持 \ 的路径, [/这种不支持];
for /f "delims=" %%j in (%%i) do echo %%j >> %outFile%
###改为:
copy "%outFile%"+"%%i" %outFile%
但这样也会出现一些特殊的符号出来,需要手动改掉;
这种情况下,按需合并的结果为 788KB , 原来有 2956KB [1/4]; 这是除 app.js 以及 app/ 下脚本的压缩结果;
把压缩后的文件, 放在sdk [sencha-touch.js] 之下
发现有错误, sencha-touch.js加载后,会默认的引用touch/src下的一些必须依赖文件;
在文件中如果使用到类型Ext.xxx.Component的地方,默认的加载方式还是为/touch/src/xx/xx 这样的地址;
想要把组件+SDK与我们写的app文件夹脚本以及app.js分开,这种方式有点困难!
Touch/src下全压缩方式
其实按需压缩,对于一个差不多点大的项目,所使用到依赖组件都几本上都用到,整个touch/app组件库是3M左右,按需获取的依赖文件也是3M左右。
所以可以压缩所有组件来使用。
使用grunt=> /touch/src全压缩方式,不采用依赖方式
Concat: {
Dist: {
Src:’build/**/*.js’,
Dest:’build/components.js’
}
},
Uglify: {
Build: {
Src:’build/components.js’,
Dest:’build/components.min.js’
},
Dist: {
Files: {
‘build/sencha.min.js’:’touch/sencha-touch.js’
}
}
}
Concat 看字就可以知道是什么意思,他表示联合起来的意思,这里是把脚本文件都联接起来,/build/**/*.js 表示 build 下的所有文件;
Dist 可以不用管,这是一个自定义的词,表示一个要执行的任务名称;
src代表脚本文件,或集合;
Dest: 'build/components.js' ; 表示把 src 集合 联接成 未压缩的 components.js 文件;
Uglify 表示压缩配置;
下面有两个任务:build, Dist;
build 的任务是把 上面联合起来的文件 components.js 压缩成 components.min.js;
Dist 下的 Files 可以配置多个执行项,是个 json 格式数据;Files:{outfile: file}, 把Value 代码的文件,压缩成 key 所指定的 outfile;
这样压缩出来的组件文件 components.min.js 大小为: 760kb,sdk文件sencha.min.js为122kb;
创建 grunt-Sencha_ZOrderCompress 插件过程;
按顺序压缩指定Sencha加载的脚本文件, 可以选择多种模式压缩;
grunt-sencha-zordercompress分按需压缩与全压缩两种方式;
每种方式下又可以分:
- APP_APPJS_ADKCOMS : 压缩两份: apps/下的文件, 以及 sdk+components的文件
- APP_APPJS_ADK_COMS : 压缩三份 : apps/下的文件, 以及 sdk文件 和 components文件三部分.
- 每种模式都可以全压缩
所有配置出来的可压缩项为:
全压缩: '<%=Sencha_ZOrderCompress_dist%>'
组件或组件加sdk: '<%=Sencha_ZOrderCompress_dist_ext_core%>'
apps/下文件压缩: '<%=Sencha_ZOrderCompress_dist_apps%>';
详见:https://github.com/gloot/grunt-sencha-zordercompress
1. grunt 命令行 转到项目根目录 /node_modules 下;
2. 使用
npm install –g grunt-init
安装grunt-init;
3. 第二安装github工具.
Git,Windows下的Git,地址:http://msysgit.googlecode.com/files/Git-1.7.9-preview20120201.exe
git、CopSSH安装可以参照(注意:看图片就好了其它的无视): http://www.codeproject.com/Articles/296398/Step-by-Step-Setup-Git-Server-on-Windows-with-CopS ;
这样就可以了,CopSSH可以不用安装;
再用 执行:
git clone git://github.com/gruntjs/grunt-init-gruntplugin.git ~/.grunt-init/gruntplugin
4. 安装gruntplugin模板
转到目标项目根目录,如果已经存在node_modules,就转到node_modules下;
>md 项目文件夹名[grunt-sencha-zorderCompress] >cd grunt-sencha-zorderCompress >grunt-init gruntplugin #[在这个文件下创建grunt插件模板]#
接下来是做些配置,最后生成一个标准的 grunt 插件模板;
5. 接下来给 grunt-sencha-zorderCompress 插件内再添加辅助插件 [自动生成node_modules]
>Npm install grunt-lib-phantomjs
>Npm install phantomjs #[会生成phantomjs与.bin文件夹]#
>Npm install connect
在package.json添加dependencies节点 包含上面三个插件;
"dependencies": {
"grunt-lib-phantomjs": "~0.4.0",
"phantomjs": "1.9.2-1",
"connect": "~2.9.0"
},
生成结构:
刚才配置的项目名为: Sencha_ZOrderCompress
模板生成后会在 grunt-sencha-zorderCompress/task 下生成一个 Sencha_ZOrderCompress.js 文件;
内容大概为:
‘use strict’; Module.exports = function(grunt) {
Grunt.registerMultiTask(‘Sencha_ZOrderCompress’, ‘plug description’, function() {
//do…
//在这里有 方法内的 this对象.
//可以运行[gruntfile.js] grunt.registerTask (‘xxx’, [‘Sencha_ZOrderCompress’]);
//所指定节点的数据
});
};
这里的gruntfile.js里 Sencha_ZOrderCompress 的配置为:
GetSenchaOrderAllComponents: {
dist: {
options: {
appJs : ‘app.js’,
processHtml:’index.html’
}
}
}
那么. Sencha_ZOrderCompress.js 的 Grunt.registerMultiTask 内,就可以获取 options的配置项:
Var options = this.options({});
Sencha_ZOrderCompress.js 代码:
/*
* Sencha_ZOrderCompress
* http://www.cmszu.com
*
* Copyright (c) 2013 Gloot/ZWD
* Licensed under the MIT license.
*/ 'use strict'; var path = require("path"),
depenconfig = require(__dirname + path.sep + 'sencha_grunt_set.js'),
depenHolder = require(__dirname + path.sep + 'sencha_phantomjs_holder.js'),
allcomponents = []; module.exports = function(grunt) { // Please see the Grunt documentation for more information regarding task
// creation: http://gruntjs.com/creating-tasks
function getOptions(instance) {
return instance.options({});
} function setOtherComponentsInOrder(files) {
for (var i=0; i<allcomponents.length; i++)
{
var hasIn = false;
var jspath = allcomponents[i];
for (var j=0; j<files.length; j++)
{
if (jspath.toLowerCase() == files[j].toLowerCase())
{
hasIn = true;
break;
}
} if (hasIn == false)
{
//grunt.log.writeln('Else files: ' + jspath);
files.push(jspath);
}
} return files;
} grunt.registerMultiTask('Sencha_ZOrderCompress', 'Compress compile sencha by order Loaded javascript files!', function() {
// Merge task-specific and/or target-specific options with these defaults.
var me = this,
options = getOptions(me),
done = me.async(); grunt.log.writeln( 'Start Task: === Sencha_ZOrderCompress' ); var holder = new depenHolder(options.processHtml, options.appName, options.mode, options.compassAll);
holder.setGrunt(grunt); me.files.forEach(function(f) { //important
var coms = f.src.filter(function(filepath) {
//grunt.log.writeln('component files: ' + filepath);
allcomponents.push(filepath);
});
});
var usecoms = options.compassAll ? allcomponents : []; holder.getDependencies(function(files, sencha) { grunt.log.writeln( 'Task Target:===================================' + me.target); //out dist depenconfig(files, grunt, 'Sencha_ZOrderCompress_'+me.target, options.mode, sencha, options.moduFunc);
done();
}, usecoms);
}); };
要想像下面的调用脚本方法:
depenconfig = require(__dirname + path.sep + 'sencha_grunt_set.js'),
depenHolder = require(__dirname + path.sep + 'sencha_phantomjs_holder.js'),
脚本文件,就需要 如果下的写法:
//脚本必须为:
//1 形式:
Module.exports = function(aaa,bbb,..) { } //2 形式:
Function afuncName(aaa,bbb,…) {
}
Module.exports = afuncName; //3 形式:
Function classfunc(aaa, bbb,…) {
This.aaa = aaa;
….
} classfunc.prototype.method = function() {
} Module.exports = classfunc;
require 才能这样加载一个脚本文件;(grunt模块|插件|中间件)可使用:var xxxx = require(__dirname + path.sep + 脚本文件来获取);
Grunt 需要了解一些知识跟常用组件;
1>. 了解 Nodejs Path模块: var path = require(‘path’);
http://lnmp.in/nodejs-path 路径拼接组合,返回标准化的路径;
2>. 了解 Nodejs connect模块: var connect = require(‘connect’);
轻量级架设服务器的Nodejs中间件组件.
http://deadhorse.me/nodejs/2011/11/26/nodejs_connect_analysis_1.html
3>. 在 gruntfile.js 部分:
Grunt.initConfig({
TaskName : {
Dist: {
//xxxx
}
}
});
其下有src/dest等属性
Src 为配置的文件路径, 该路径可正则匹配所有的文件
/*.js 代表某文件夹下的所有.js文件
/**/*.js 代表某文件夹及其所有子文件夹下的所有.js文件
返回所有文件数组为:
this.files.forEach(function(f) { var files = f.src.filter(function(filepath) { //filepath即为src设定下的文件列表的其中一个文件. }); });
Dist下的配置项可以通过如果方式获取:
这里是options:
//这是在 TaskName 所在文件 TaskName.js的 grunt.registerMultiTask 里
Var options = instance.options({}); //可以instance.options的json部分再添加字段属性.
TaskName.js 即为上面 Sencha_ZOrderCompress.js 文件;
设置值:
在 gruntfile.js 里有:
Concat : {
Dist: {
Src : ‘<%= taskName_xxx %>’
}
}
这个taskName_xxx 的值 可由 :
Grunt.config.set(‘taskName_xxx’, valueobj);
来配置,一般为数组;
Concat为组合由src设定的文件列表组合文件;
Uglify 为压缩插件, src为源数据文件, dest为压缩结果文件:
Uglify: {
Build: {
Src:’’,
Dest:’’
}
}
Dist : {
Files: {
‘压缩文件地址’, ‘源文件地址’
}
}
Grunt.registerTask(‘default’, []); //default为默认必须任务配置项;
Nodejs在这里有很多模块,中间组需要学习.
Fs, connect, path等.
1>. Connect中间件, 在指定文件下创建服务与端口:
Var app = connect().use(connect.static(process.cwd())).listen(3000);
Process为内置对象, 可直接使用.
Process.cwd() 获取当前 Nodejs命令行操作所在的当前目录.
Connect.static(这里应该可以自定义一个地址)
另写法: connect[‘static’](地址);
//关闭服务
App.close();
2>. file copy write 等;
Grunt.log.writeln|error|warn|debug…
Grunt.file.copy|delete|write
copy:
Grunt.file.copy(copyfrompath, copyTopath, {
Process: function(contstring) {
//contstring即为copyfrompath所在文件内容
//return contstring才可保存到copyTopath文件.
}
});
write:
Grunt.file.write(‘文件地址’, ‘文件内容’);
3>. Phantomjs部分
Phantomjs.on(‘onResourceRequested’, function(response) {
//response.url
//执行摸拟文件初始时加载的文件.
//骤步输出
}); Phantomjs.on(‘error.onError’, function(msg, tracer) {
//执行加载发生异常时输入
}); Phantomjs.on(‘mytask.done’, function(findfiles) {
Files = findfiles.history;
Phantomjs.halt();
});
//mytask.done为自定义响应事件. 在grunt-lib-phantomjs插件/phantomjs/main.js内 setInterval(function() {
//在执行到timeout后,获取响应结果的文件是sendMessage输出.
}); Phantomjs.on(‘fail.load’, function(url) {
//加载失败
Phantomjs.halt();
}); Phantomjs.on(‘fail.timeout’, function() {
//超时
Phantomjs.halt();
}); Phantomjs.spawn(‘由connect创建的服务下地摸拟执行文件地址(url)’, {
Options: { //引用事件响应文件
phantomScript: ‘grunt-lib-phantomjs插件下/phantomjs/main.js所在位置’,
loadImages : false
},
Done: function(err) {
//返回文件数组结果
//删除相应的文件
//关闭服务
}
});
Sencha相关研究结果:
Sencha页面初始化,需要加载相应的sencha components组件文件,而且要按一定的顺序排序,不然会出现,组件内引用另组件不存在的情况,这里他会默认到/touch/src下加载相应的文件所在位置.
所以如果要压缩所有的组件,就要把所有的组件加载到 Sencha Ext.application内的requires下,模拟运行初始化操作,这样,sencha核心加载会按顺序加载所需的文件。才能压缩到所有sencha components!
研究发现, Ext.device加载处理得不好, 实际上在debug模式下是没有Ext.device部分代码的,所以在全压缩模式下去除了Ext.device部分代码;
Sencha Touch 手机移动开发框架 HTML5 项目压缩方案;的更多相关文章
- 第一步 使用sencha touch cmd 4.0 创建项目、打包(加入全局变量、公用类、自定义扩展、资源文件)
参考资料: http://www.cnblogs.com/qqloving/archive/2013/04/25/3043606.html http://www.admin10000.com/docu ...
- 跟我一起玩转Sencha Touch 移动 WebApp 开发(一)
1.目录 移动框架简介,为什么选择Sencha Touch? 环境搭建 创建项目框架,框架文件简介 创建简单Tabpanel案例 自定义图标的方式 WebApp产品测试和发布 HTML5离线缓存 发布 ...
- jQuery Mobile和Sencha Touch哪个更适合你?
纯粹的总结一下移动web开发框架,移动web开发框架有jQuery Mobile .Sencha Touch等等,他们都来源于web开发,是成熟的框架,jQuery Mobile出自于jQuery家族 ...
- 跟我一起玩转Sencha Touch 移动 WebApp 开发1
跟我一起玩转Sencha Touch 移动 WebApp 开发(一) 1.目录 移动框架简介,为什么选择Sencha Touch? 环境搭建 创建项目框架,框架文件简介 创建简单Tabpanel案例 ...
- Sencha Touch开发完整流程快速讲解
1.目录 移动框架简介,为什么选择Sencha Touch? 环境搭建 创建项目框架,框架文件简介 创建简单Tabpanel案例 自定义图标的方式 WebApp产品测试和发布 HTML5离线缓存 发布 ...
- 用 Sencha Touch 构建移动 web 应用程序
Sencha Touch 是一个使用 HTML5.CSS3 和 JavaScript 语言构建的移动 web 应用程序框架,在本文中,学习如何应用您当前的 web 开发技能进行移动 web 开发.下载 ...
- sencha touch 入门系列 扩展篇之sencha touch 项目打包压缩
经常有新手同学抱怨说sencha touch的项目加载速度为什么这么慢,经常要10秒左右的时间甚至更多, 大家都知道,sencha touch开发的项目中引用了大量的js文件,当我们打开项目时,st的 ...
- 选择移动web开发框架研究——有mui、frozenui以及Sencha Touch等
纯粹的总结一下移动web开发框架,移动 web开发框架有jQuery Mobile .Sencha Touch等等,他们都来源于web开发,是成熟的框架,jQuery Mobile出自于jQuery家 ...
- 动端逐渐出了许多的移动端的框架,比如Sencha Touch、JQTouch、Jquery-moblie、jqMobi等等。这些框架都有优缺点,不同的框架应用在不同的项目中。现简单阐述一下各框架的优缺点:
移动前端工作的那些事---前端制作之微信小技巧篇 (2013-11-15 15:20) 转载▼ 标签: it css3/javascript html5 webapp 手机网站搭建 分类: 前端制 ...
随机推荐
- POJ 2406 Power Strings (KMP)
Power Strings Time Limit: 3000MSMemory Limit: 65536K Total Submissions: 29663Accepted: 12387 Descrip ...
- [嵌入式开发板]iTOP-4412以模块的方式编译驱动
本文转自迅为:http://www.topeetboard.com 大家好,本章节我们将向大家讲解如何在 linux 下实现以模块的方式加载内核驱动.我们以内核里面蜂鸣器的 驱动为例来讲解. 1)首先 ...
- 学习嵌入式Linux-选择iTOP-4412开发板
部分视频观看地址: [视频教程]iTOP-4412开发板之学习方法--致初学者 http://v.youku.com/v_show/id_XNzQ5MDA4NzM2.html [视频教程]三星Exyn ...
- Memcached内存分配优化及使用问题
前几天做了个Memcached的思考,并测试了一些数据,是关于如何提高Memcached内存使用率的问题.在启动memcached的时候可以加-f参数和-n参数.-f指定各slab里面chunk大小的 ...
- 循环 wxl
#include <cstdio> #include <cstring> #include <string> #include <algorithm> ...
- 2014 Super Training #1 F Passage 概率DP
原题: HDU 3366 http://acm.hdu.edu.cn/showproblem.php?pid=3366 本来用贪心去做,怎么都WA,后来看网上原来是一个DP题. 首先按P/Q来做排 ...
- [原创] NetBean开发c++程序指南1- 加入c++项目文件夹
利用 NetBean开发c/c++程序,导入原有程序代码. 1. 在菜单栏的 "工具" -> 选项 -> c/c++开发 如果彩色就是激活的状态,否则选择激活. 2. ...
- Android 动态加载 (二) 态加载机制 案例二
探秘腾讯Android手机游戏平台之不安装游戏APK直接启动法 重要说明 在实践的过程中大家都会发现资源引用的问题,这里重点声明两点: 1. 资源文件是不能直接inflate的,如果简单的话直接在程序 ...
- 获取元素在浏览器中的绝对位置(从jquery1.8中抠出来)
<style> html,body{margin:0;padding:0;} .d1{margin-left:40px;background:red;width:2000px;height ...
- “display:block-inline形式的Span或Div中添加文字后,导致Span或Div排版掉落、错位”的原因及解决方法
最近在使用3个span(或div)制作带圆角边框的按钮时,按照常识,把span的display设置成inline-block,这样就可以设置span的width和height了,很爽的~ 可是当我在中 ...