[Cordova/Phonegap] 打包Cordova App时,合并所有插件的js文件并压缩,提升App加载速度
来源:互联网 发布:小黑裙香水淘宝 编辑:程序博客网 时间:2024/05/22 03:10
原文链接:http://blog.csdn.net/lovelyelfpop/article/details/56014300
问题的背景和现象
Cordova App 添加的各种plugin插件,每个plugin都有自己的js文件。
App入口index.html中只引入了一个www目录下的cordova.js文件,此文件会在同一级目录下寻找cordova_plugins.js,然后根据这个文件中描述的各个plugin的路径,找到它们的js,并加载。
www目录结构如下:
注意:
- 安卓的www目录为cordova/platforms/android/assets/www
- ios的www目录为cordova/platforms/ios/www
如果我们用了很多的plugin,那么最后app需要加载的js文件就会变得非常多,加载变慢就拖慢了app的启动速度。如下图:
解决办法
browserify
那么,如何才能把这些js文件整合成为一个js文件呢?其实,cordova-cli命令行提供了参数--browserify,具体可以查看官方文档:
https://cordova.apache.org/docs/en/latest/reference/cordova-cli/#cordova-prepare-command
cordova prepare、cordova build、cordova run命令都可以使用--browserify参数,以build为例:
cordova build android --browserify
最后打包的目录下的cordova.js文件变大了:
这就是因为cordova.js、cordova_plugins.js以及cordova-js-src目录和plugins目录下的js,都打包到了一起。
最后App加载的结果是这样:
是不是少多了?
Cordova Hooks
当然,上面的--browserify参数只是把插件js打包进了cordova.js,但是并没有把cordova_plugins.js、cordova-js-src目录和plugins目录下的js删除掉。
如果你想把这些无用的js删掉的话,变成下面的结构:
此时,cordova hooks就派上用场了。
hooks,中文意思是钩子。
cordova在build过程中分为各个阶段,如下表格:
cordova platform add
To be executed before and after adding a platform.cordova prepare
cordova platform add
cordova build
cordova run
To be executed before and after preparing your application.cordova compile
cordova build
To be executed before and after compiling your application.cordova emulate
cordova run
To be executed before deploying your application.cordova build
To be executed before and after building your application.每个hook就相当于一个事件,我们可以监听它,然后执行我们的自定义操作。
我们要做的就是在after_prepare阶段,把www目录下的无用文件删除掉,并且压缩cordova.js。
我就直接提供代码了。
1、建立目录cordova/scripts/after_prepare,把下面的代码保存为minify.js,放到after_prepare目录下
#!/usr/bin/env nodemodule.exports = function(ctx) { var fs = ctx.requireCordovaModule('fs'), path = ctx.requireCordovaModule('path'), shell = ctx.requireCordovaModule("shelljs"), UglifyJS = require('uglify-js'), CleanCSS = require('clean-css'), htmlMinify = require('html-minifier').minify, cssOptions = { keepSpecialComments: 0 }, cssMinifier = new CleanCSS(cssOptions), rootDir = ctx.opts.projectRoot, platformPath = path.join(rootDir, 'platforms'), platforms = ctx.opts.cordova.platforms, platform = platforms.length ? platforms[0] : '', cliCommand = ctx.cmdLine, debug = true, //false htmlOptions = { removeAttributeQuotes: true, removeComments: true, minifyJS: true, minifyCSS: cssOptions, collapseWhitespace: true, conservativeCollapse: true, removeComments: true, removeEmptyAttributes: true }, successCounter = 0, errorCounter = 0, notProcessedCounter = 0, pendingCounter = 0, hasStartedProcessing = false, processRoot = false, isBrowserify = (cliCommand.indexOf('--browserify') > -1), //added //isRelease = true; isRelease = (cliCommand.indexOf('--release') > -1); // comment the above line and uncomment this line to turn the hook on only for release function processFiles(dir, _noRecursive) { fs.readdir(dir, function (err, list) { if (err) { // console.error('processFiles - reading directories error: ' + err); return; } list.forEach(function(file) { file = path.join(dir, file); fs.stat(file, function(err, stat) { hasStartedProcessing = true; if (stat.isDirectory()) { if (!_noRecursive) processFiles(file); } else { compress(file); } }); }); }); } function processFile(file) { fs.stat(file, function(err, stat) { hasStartedProcessing = true; compress(file); }); } function compress(file) { var ext = path.extname(file); switch(ext.toLowerCase()) { case '.js': (debug) && console.log('Compressing/Uglifying JS File: ' + file); var result = UglifyJS.minify(file, { compress: { dead_code: true, loops: true, if_return: true, keep_fargs: true, keep_fnames: true } }); if (!result || !result.code || result.code.length == 0) { errorCounter++; console.error('\x1b[31mEncountered an error minifying a file: %s\x1b[0m', file); } else { successCounter++; fs.writeFileSync(file, result.code, 'utf8'); (debug) && console.log('Optimized: ' + file); } break; case '.css': (debug) && console.log('Minifying CSS File: ' + file); var source = fs.readFileSync(file, 'utf8'); if (!source || source.length == 0) { errorCounter++; console.error('Encountered an empty file: ' + file); } else { var result = cssMinifier.minify(source).styles; if (!result || result.length == 0) { errorCounter++; console.error('\x1b[31mEncountered an error minifying a file: %s\x1b[0m', file); } else { successCounter++; fs.writeFileSync(file, result, 'utf8'); (debug) && console.log('Optimized: ' + file); } } break; case '.html': (debug) && console.log('Minifying HTML File: ' + file); var source = fs.readFileSync(file, 'utf8'); if (!source || source.length == 0) { errorCounter++; console.error('Encountered an empty file: ' + file); } else { var result = htmlMinify(source, htmlOptions); if (!result || result.length == 0) { errorCounter++; console.error('\x1b[31mEncountered an error minifying a file: %s\x1b[0m', file); } else { successCounter++; fs.writeFileSync(file, result, 'utf8'); (debug) && console.log('Optimized: ' + file); } } break; default: console.error('Encountered file with ' + ext + ' extension - not compressing.'); notProcessedCounter++; break; } } function checkIfFinished() { if (hasStartedProcessing && pendingCounter == 0) console.log('\x1b[36m%s %s %s\x1b[0m', successCounter + (successCounter == 1 ? ' file ' : ' files ') + 'minified.', errorCounter + (errorCounter == 1 ? ' file ' : ' files ') + 'had errors.', notProcessedCounter + (notProcessedCounter == 1 ? ' file was ' : ' files were ') + 'not processed.'); else setTimeout(checkIfFinished, 10); } switch (platform) { case 'android': platformPath = path.join(platformPath, platform, "assets", "www"); break; case 'ios': platformPath = path.join(platformPath, platform, "www"); break; default: console.error('Hook currently supports only Android and iOS'); return; } if(isBrowserify) { shell.rm('-rf', path.join(platformPath, 'cordova-js-src')); shell.rm('-rf', path.join(platformPath, 'plugins')); shell.rm('-f', path.join(platformPath, 'cordova_plugins.js')); } if (!isRelease) { return; } console.log('cordova-minify STARTING - minifying your js, css, html. Sit back and relax!'); //minify files inside these directories //var foldersToProcess = ['javascript', 'style', 'js', 'css', 'html']; var foldersToProcess = isBrowserify ? [] : ['cordova-js-src', 'plugins']; if (processRoot) processFiles(platformPath, true); foldersToProcess.forEach(function(folder) { processFiles(path.join(platformPath, folder)); }); //minify files one by one var filesToProcess = ['cordova.js']; if(!isBrowserify) filesToProcess.push('cordova_plugins.js'); filesToProcess.forEach(function(file) { processFile(path.join(platformPath, file)); }); checkIfFinished();};
上述代码来自:https://github.com/adamerny/cordova-minify-v2
2、打开cordova/plugins.xml文件,在其中加一句
<hook type="after_prepare" src="scripts/after_prepare/minify.js" />
如下图:
3、打开命令行界面,全局安装下面的npm包
npm install -g clean-css html-minifier uglify-jsminify.js 会用到上面的包
好了,现在执行Cordova的打包命令
Debug 打包:运行cordova build android --browserify,完成后就没有多余的插件js文件了;
Release打包:运行cordova build android --release --browserify,不仅删除了多余的插件js文件,还把cordova.js压缩了。
ps: 如果你想要在Debug打包时,也压缩cordova.js文件,那就把上面hook脚本中的isRelease设为true。
Sencha+Cordova
上面是针对cordova项目来说的,如果你是Sencha项目(Touch或ExtJS6 Modern),需要修改文件:
Sencha项目\.sencha\app\cordova-impl.xml
在每个命令后面加上--browserify
这样,以后Sencha app build xxx就可以整合压缩cordova.js了。
实际测试,app的加载速度提升不到1秒。
应该设备越低端,提升越明显吧。(忽略ios,ios本来就快)
- [Cordova/Phonegap] 打包Cordova App时,合并所有插件的js文件并压缩,提升App加载速度
- Cordova(Phonegap)在iOS端App的使用(二)---插件的创建
- cordova-plugin-app-version插件的使用
- Cordova App 打包全揭秘
- 使用cordova进行App打包
- Cordova App 打包全揭秘
- 关于phonegap(cordova)跨平台app应用的环境配置
- Cordova(Phonegap)在iOS端App的使用(一)
- phonegap之cordova构建Android app
- ionic angularJS phoneGap(cordova) 搭建app应用
- 使用cordova将Ext JS 6.2的Modern应用程序打包为安卓APP
- [Phonegap+Sencha Touch] 移动开发76 让cordova app访问远端网站也能调用cordova插件功能
- phonegap cordova ionic插件
- [Phonegap+Sencha Touch] 移动开发77 Cordova Hot Code Push插件实现自动更新App的Web内容
- [Cordova/Phonegap] 一位程序猿朋友封装的Cordova插件
- Cordova 打包 Android release app 过程详解
- Cordova 打包 Android release app 过程详解
- Cordova 打包 Android release app 过程详解
- 0220
- Intel系列CPU架构的发展史
- EM 13CR2 相关问题汇总
- 图的基本存储的基本方式三
- Java日期格式化多位数表示规则
- [Cordova/Phonegap] 打包Cordova App时,合并所有插件的js文件并压缩,提升App加载速度
- javascript 继承详解
- Java 向mysql插入中文数据乱码问题
- 由 B-/B+树看 MySQL索引结构
- docker容器安装配置redis集群
- 大整数排序
- 第一讲:ANSYS入门基础之GUI
- java 记错--继承
- ZeroMQ初探