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分按需压缩与全压缩两种方式;

每种方式下又可以分:

  1. APP_APPJS_ADKCOMS : 压缩两份: apps/下的文件, 以及 sdk+components的文件
  2. APP_APPJS_ADK_COMS : 压缩三份 : apps/下的文件, 以及 sdk文件 和 components文件三部分.
  3. 每种模式都可以全压缩

所有配置出来的可压缩项为:

全压缩: '<%=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 项目压缩方案;的更多相关文章

  1. 第一步 使用sencha touch cmd 4.0 创建项目、打包(加入全局变量、公用类、自定义扩展、资源文件)

    参考资料: http://www.cnblogs.com/qqloving/archive/2013/04/25/3043606.html http://www.admin10000.com/docu ...

  2. 跟我一起玩转Sencha Touch 移动 WebApp 开发(一)

    1.目录 移动框架简介,为什么选择Sencha Touch? 环境搭建 创建项目框架,框架文件简介 创建简单Tabpanel案例 自定义图标的方式 WebApp产品测试和发布 HTML5离线缓存 发布 ...

  3. jQuery Mobile和Sencha Touch哪个更适合你?

    纯粹的总结一下移动web开发框架,移动web开发框架有jQuery Mobile .Sencha Touch等等,他们都来源于web开发,是成熟的框架,jQuery Mobile出自于jQuery家族 ...

  4. 跟我一起玩转Sencha Touch 移动 WebApp 开发1

    跟我一起玩转Sencha Touch 移动 WebApp 开发(一) 1.目录 移动框架简介,为什么选择Sencha Touch? 环境搭建 创建项目框架,框架文件简介 创建简单Tabpanel案例 ...

  5. Sencha Touch开发完整流程快速讲解

    1.目录 移动框架简介,为什么选择Sencha Touch? 环境搭建 创建项目框架,框架文件简介 创建简单Tabpanel案例 自定义图标的方式 WebApp产品测试和发布 HTML5离线缓存 发布 ...

  6. 用 Sencha Touch 构建移动 web 应用程序

    Sencha Touch 是一个使用 HTML5.CSS3 和 JavaScript 语言构建的移动 web 应用程序框架,在本文中,学习如何应用您当前的 web 开发技能进行移动 web 开发.下载 ...

  7. sencha touch 入门系列 扩展篇之sencha touch 项目打包压缩

    经常有新手同学抱怨说sencha touch的项目加载速度为什么这么慢,经常要10秒左右的时间甚至更多, 大家都知道,sencha touch开发的项目中引用了大量的js文件,当我们打开项目时,st的 ...

  8. 选择移动web开发框架研究——有mui、frozenui以及Sencha Touch等

    纯粹的总结一下移动web开发框架,移动 web开发框架有jQuery Mobile .Sencha Touch等等,他们都来源于web开发,是成熟的框架,jQuery Mobile出自于jQuery家 ...

  9. 动端逐渐出了许多的移动端的框架,比如Sencha Touch、JQTouch、Jquery-moblie、jqMobi等等。这些框架都有优缺点,不同的框架应用在不同的项目中。现简单阐述一下各框架的优缺点:

    移动前端工作的那些事---前端制作之微信小技巧篇   (2013-11-15 15:20) 转载▼ 标签: it css3/javascript html5 webapp 手机网站搭建 分类: 前端制 ...

随机推荐

  1. POJ 2406 Power Strings (KMP)

    Power Strings Time Limit: 3000MSMemory Limit: 65536K Total Submissions: 29663Accepted: 12387 Descrip ...

  2. [嵌入式开发板]iTOP-4412以模块的方式编译驱动

    本文转自迅为:http://www.topeetboard.com 大家好,本章节我们将向大家讲解如何在 linux 下实现以模块的方式加载内核驱动.我们以内核里面蜂鸣器的 驱动为例来讲解. 1)首先 ...

  3. 学习嵌入式Linux-选择iTOP-4412开发板

    部分视频观看地址: [视频教程]iTOP-4412开发板之学习方法--致初学者 http://v.youku.com/v_show/id_XNzQ5MDA4NzM2.html [视频教程]三星Exyn ...

  4. Memcached内存分配优化及使用问题

    前几天做了个Memcached的思考,并测试了一些数据,是关于如何提高Memcached内存使用率的问题.在启动memcached的时候可以加-f参数和-n参数.-f指定各slab里面chunk大小的 ...

  5. 循环 wxl

    #include <cstdio> #include <cstring> #include <string> #include <algorithm> ...

  6. 2014 Super Training #1 F Passage 概率DP

    原题: HDU 3366   http://acm.hdu.edu.cn/showproblem.php?pid=3366 本来用贪心去做,怎么都WA,后来看网上原来是一个DP题. 首先按P/Q来做排 ...

  7. [原创] NetBean开发c++程序指南1- 加入c++项目文件夹

    利用 NetBean开发c/c++程序,导入原有程序代码. 1. 在菜单栏的 "工具" -> 选项 -> c/c++开发 如果彩色就是激活的状态,否则选择激活. 2. ...

  8. Android 动态加载 (二) 态加载机制 案例二

    探秘腾讯Android手机游戏平台之不安装游戏APK直接启动法 重要说明 在实践的过程中大家都会发现资源引用的问题,这里重点声明两点: 1. 资源文件是不能直接inflate的,如果简单的话直接在程序 ...

  9. 获取元素在浏览器中的绝对位置(从jquery1.8中抠出来)

    <style> html,body{margin:0;padding:0;} .d1{margin-left:40px;background:red;width:2000px;height ...

  10. “display:block-inline形式的Span或Div中添加文字后,导致Span或Div排版掉落、错位”的原因及解决方法

    最近在使用3个span(或div)制作带圆角边框的按钮时,按照常识,把span的display设置成inline-block,这样就可以设置span的width和height了,很爽的~ 可是当我在中 ...