I am developing Phonegap Build application. For the android file,when I try to compile the zip file, the APK file always contain 3 javascript file:phonegap.js cordova.js ... Yet the three files are of exactly the same content. How can I remove the two redundant js file in order to optimize my application?
FYI the reason the redundant files are present is to avoid user confusion according to the devs:
Many users were including the wrong file. Allowing inclusion of any of
the above avoided a lot of confusion -- enough to outweigh the
footprint of two extra files, in our opinion.
Now that PhoneGap 2.8 introduced cordova.js without the version number in the filename, there is a low-priority issue being tracked to remove the redundant files (so if you just wait, it might be fixed soon on its own):
Enhancement: PhoneGap 2.8 introduce cordova.js without version number.
Build could now exclude redundant .js files.
But, if you aren't willing to wait for them to upgrade the build process, you can remove the files yourself following these instructions:
1. Unpack the APK files into a local directory structure using apktool (you'll need the Android and Java SDKs installed on your machine) - instructions here on how to unpack and remove files:
$ \path\to\AndroidSDK\platform-tools\apktool d myApp.apk
2. Remove the phonegap.js and cordova-x.x.x.js files (these are the unused ones in > 2.8.0).
3. Repackage the APK, again using apktool:
$ \path\to\AndroidSDK\platform-tools\apktool b myApp myAppUnsigned.apk
note at this point that the APK isn't signed, and therefore can't be deployed to the Play Store or any devices which doesn't allow apps from unsigned sources.
4. Re-sign the APK file using your android cert so it's valid:
Sign the apk using the jarsigner tool that’s part of the Java JDK.
You’ll also need your keystore and key alias that you used to sign the
app, as well as the password.
jarsigner -verbose -keystore ~/MySigningKey.keystore ~/Desktop/myAppUnsigned.apk myKeyAlias
Enter Passphrase for keystore:
After you enter your passphrase, you’ll see a whole bunch of ‘signing:’ messages zoom by; once it’s all done, you have a signed apk file.
5. The last step is to zipalign the apk file:
zipalign -v 4 myAppUnsigned.apk myApp.apk
And you should be done. You could automate all these steps into a batch/shell script for ease of use when building files.
Related
I'm troubleshooting a React Native app and one article suggested deleting the ios/build folder, but didn't explain why. Does anyone know, in as much detail as you can, what the role of this folder is, how it's created, and what the implications are of deleting it?
Thanks!
what the role of this build folder
Actually it's the code compiled into native. when you compile your code, for example react-native run-ios , this command compile and build code for ios and then run it on IOS simulator. its generated after compiling project.
how it's created
When you run the app, the compiler will build this folder.
and what the implications are of deleting it?
Then the compiler will build the whole project from start as the build folder for IOS or ANDROID is missing which is needed to run the native app.
I hope this helps in your understanding.
ios/build folder is updated when the app is built. It contains several subfolders, each having its own use:
Build/Products
Stores final build artifacts that are installed on Simulator or device.
Build/Intermediates.noindex
Stores additional files used while building the app. These are cached to speed up subsequent builds. Removing it will slow down the next build.
Index
Xcode performs indexing of project source code and stores the index in this folder. Index is used to speed up Xcode operation like search, quick navigation, refactoring. Removing this will trigger indexing next time Xcode is opened. However, Xcode index doesn't really affect React Native developer experience since you normally don't use Xcode much while developing RN apps.
Logs
Stores logs collected while performing various tasks like building, testing, debugging etc.
ModuleCache
Stores precompiled module files. Modules allow to reduce compile time of Xcode apps. Removing this will slow down the next build.
To summarize, ios/build folder contains final installation app files, auxiliary files and precompiled modules, various logs and source code index. The main implication of removing the build folder is that the next build will be slower than usual.
I have one code base for both Web and NodeWebkit (NW) application.
I use the following stack:
- React
- Hapi
- Sequelize
- Windows environment
Web version of the application uses MySQL, while NW uses Sqlite. It all works fine. I have config file that compiles application for what I need (web or NW).
The problem that I face now is how to deploy the NW application. Idea is to provide NW applicaiton to a client, where he will open it clicking the icon.
Since I use the Node for the NW version, and the application uses many modules which are stored in node_modules, I face a challenge how to pack it all up.
My idea is to make an Windows installer. User will click it and the installer will extract all files to the destination. And also make an icon on the user desktop to run it.
Problem is with the Windows file name limitation. Inside the node_modules, there are many subdirectories that simply violate the Windows limitation. I cant even copy the node_modules folder. I cant even delete it. Well sure I can copy it If I zip it... or remove manually long folders.
I have not yet started working on the installer, but I am thinking I will hit the wall with this approach.
Does anyone have an idea how to make this deployment?
How can I integrate NPM3 in NW?
My plan now is to make Windows installer. That windows installer will install normally application files. The node_modules will be zipped previously and placed inside the installer. Installer will then simply unzip it to the destionation folder.
I will post my progress here.
Some update here.
Main issue here was the depth of the node_modules. I have many modules in node_modules, and after some thinking I figured out there is a simple rule there. Some modules are server side modules, while other ones are used by react.
And since Webpack already creates a huge files in which all of the modules are already included, I simply do not need them at all.
So I have removed all front end side modules(babel modules, react-*), and left only server side (Hapi, sequelize...). Miracle happened, application run and was much faster at the startup.
I am going to use Inno setup to make a manifest file, and it should be good to go.
I am still not out of the danger zone, as developer might need a server side module, which has huge depth. But I will think about that if it happens.
More to follow...
actually in nodejs you can do the following:
1-Create another folder inside your project folder for example "server_modules"
2-In the created folder create another package.json file and install any modules needed for server out there
3-All these modules will be accessible as normal node_modules using require('module_name') and you can delete "server_modules" folder when you package your desktop version if you don't need it
Note: this approach used by some developers to achive micro services in nodejs but it is useful in your case
So I've been using knockout.js to do the data-binding for a particular chrome extension I am working on. I've thought that it may make sense to move to a framework (like Angular). After using npm to install all of the dependencies for my angular, the node_module folder is over 100 MB. This is obviously too large to contain in the chrome extension, and have installed on each users machine. Any recommendations on how I should go about using Angular for my extension in such a way that it doesn't require hundreds of MB of files on the client's machines?
There is no need to include bower_components or node_modules folder in your Chrome Extension. Try using Grunt/Gulp for minification.
Your Repository should ideally contain a dist folder, which contains the production ready state of your extension. When you're uploading your extension to the Chrome Webstore, you should create a ZIP of this folder.
Use the below Grunt plugins for optimizing your application,
grunt-usemin - will extract all your stylesheets or scripts from index.html, and combine them into a single CSS or JS file, so you do not have to worry about the node_modules or bower_components folder.
grunt-contrib-uglify - will uglify/minify the JS file.
In short, treat your Chrome Extension as any real world production Angular application, which will normally contain a distribution folder containing the optimized version of your code. You will be deploying the contents in this folder to production, and not the entire repository.
You can refer a Chrome Extension, which I have worked on, named Browser Automation Tookit on Github. You can check Gruntfile.js and the dist folder for further guidance.
https://github.com/kensplanet/browser-automation-toolkit
When you use npm for client-side dependencies you should only include the dist files. (Angular for instance - /node_modules/angular/angular.js)
Usually those files only weight few kb.
It's better to use the package minified version in production if they expose such (/node_modules/angular/angular**.min**.js) or minify it by your self you can use any task runner for it (grunt/gulp)
Furthermore, I will highly recommend you not to reinvent the wheel and start with a yeoman genrator or a project seed like: https://github.com/yeoman/generator-chrome-extension
I'm investigating the complexity involved in maintaining a cross-platform (web, ios, android) phonegap codebase that allows for platform specific code (and assets/tests) as simply as possible.
The current best approach I'm taking is to use grunt to build the code of a typical web app, and then use the grunt-phonegap module to generate the respective phonegap projects.
I'm confident this will work, however for my phonegap projects, I know I'm going to need to make use of some specially written plugins to make use of some device capabilities (these aren't typical cordova plugins)
I'm wondering if anyone has figured out an approach for maintaining a codebase that can adapt to different platforms and requirements. Javascript has no #IF_DEF functionality, but would it be possible to implement something like that using grunt?
I recently had the same question myself. I couldn't really find much online regarding this so I decided to deep dive into Grunt, Node, and Git.
Grunt and Node
In the root folder of my Cordova projects (alongside the www, platforms, merges, and plugins folders) I have a grunt project. I store modular JavaScript files and CSS files that may or may not be platform dependent inside a src folder inside the root of the Cordova project. This grunt project builds the JavaScript and CSS stored in the src folder and places the resulting files into the www or merges folder as appropriate.
I even wrote a grunt task that will make a production build of the app by optimizing and minifying css, javascript, and html templates, then rebuilds the Cordova platform projects to include these production files.
Because there is no #IF_DEF in JavaScript, I have to use Grunt (mentioned above) to build out the JavaScript for each platform. I modularize almost all of the JavaScript functions by platform. If there are no platform differences for that function (no native hooks), I only need one file. If there are differences, I need to create a separate file for each platform for that function. For example, my Cordova onDeviceReady and onResume function usually differ from platform to platform. I create files called
CordovaEvents-ios.js and CordovaEvents-android.js
Inside the package.json file, I describe the "features" I want in my app. CordovaEvents is an example of a feature.
I also support "arguments". I use the same approach above in the file names of the modular files. An argument could look like this
CordovaEvents-ios--production.js and CordovaEvents-android--production.js
In this case the code needed in a production app will differ from non production code. I can simply pass this argument (or list of arguments) during the build process, and the correct files will be picked up and built. I think this most closely addresses your question if there is an approach to maintaining a codebase that can adapt to different platforms and requirements. The requirements are the feature names and arguments. The argument can be anything you want, maybe using one plugin or another plugin.
I also describe the platforms I want to support ("iOS", "Android", and "Desktop"). Grunt processes each platform in a MultiTask, and then looks at the features I want to support. It will try to find a file called feature-platform.js. If it cannot find this file, it will just try to look for feature.js. After I concatenate all the functions together needed for the platform, it will copy the file over to the merges folder for iOS or Android. Typically all the files kept in the WWW folder in the root project will work on a desktop because there are no native Cordova hooks... this allows me to debug in Chrome. All the files that contain native hooks are stored in the merges folder. Once the Cordova project is built for the respective platform, the code can be tested in a device simulator.
If you are new to Grunt I would strongly suggest taking a look a their getting started guide.
http://gruntjs.com/getting-started
Git
I also employed Git to version my code. I used SourceTree to create the Git repository in the root folder of my Cordova project, and have a remote repository on my Mac Mini server that I can push my commits too. This allows us to have a backup copy of the code, and makes it so my team can also work on the code out-of-band.
I Git ignore the following folders:
node_modules
plugins
platforms
plugins
All the other files and folders contained in the root directory of my Cordova project are versioned. I used the following link as a reference to help define my Git strategy for Cordova:
https://leanpub.com/developingwithcordovacli/read#version-control
It didn't take me overnight to figure all this stuff out, in fact it took a little bit more than two months. I hope my answer can server as a guide to you and others to address your concerns you mentioned in your opening post.
I am using gruntjs, javascript, jade, bower, and phonegap to build hybrid web applications and phonegap mobile applications. After some investigation, I settled on to use jade template language for creating my html and javascript files. This is my setup.
//begin grunt module
module.exports = function(grunt) {
var $jadeConfigObject = {
compileDevelopment: {
options: {
pretty: true,
data: {
debug: true,
**phonegap : '<%= isPhonegapBuild %>'**
}
},
files: [{
expand: true,
cwd : "src",
src: "**/*.jade",
ext: ".html",
dest:"dist/development/www/"
}]
}
};
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
clean: [$dist_folder,"www"],
jade: $jadeConfigObject
// other gruntjs tasks
})
grunt.registerTask('setPhonegap', 'Set Phonegap related values.', function(n) {
**grunt.config.set('isPhonegapBuild', true);**
});
grunt.registerTask('buildPhonegap', ['setPhonegap','buildDevelopment'
,'copy:phonegap_www']);
}
Now explanation
Use gruntjs setPhonegap task to distinguish between phonegap build and normal web application build.
Task setPhonegap set isPhonegapBuild config property, this property, in turn, is used by jade config object. Then I can use "if phonegap" statements in jade files.
I have following line in my jade layout file
include ../includes/mainJavascript.jade
mainJavascript.jade
if phonegap
script(type='text/javascript',src='#{mainFolder}/cordova.js')
script(type='text/javascript',src='#{mainFolder}/cordova_plugins.js')
script(type='text/javascript',src='#{mainFolder}/plugins/org.apache.cordova.device/www/device.js')
script(type='text/javascript',src='#{javascriptServicesFolder}/pushTokenService.js')
script(type='text/javascript',src='#{javascriptFolder}/plugins/com.phonegap.plugins.PushPlugin/www/PushNotification.js')
script(type='text/javascript',src='#{javascriptFolder}/phonegap/pushNotificationHelper.js')
This way I have following features
My web application does not contain any phonegap related scripts or html
I can use jade layouts (Master Page) to simplify my files very easily.
Adding new javascript to every page or changing every html for every page in application very easy.
Note that phonegap wants www folder for its build scripts, therefore I create following directory structure.
src -- every code file here, jade, javascript
www -- only created for phonegap build
dist/development/www -- normal development www build
dist/production/www -- production www build
I ignore www/* and dist/* in my source control. I only work with src jade and javascript files. Add this setup to bower, I believe it is a good option.
I've been pulling my hair lately. I have a Yeoman generated JekyllRB grunt/bower setup. The build works correct on my Windows machine but not on an automated Linux build machine.
With correct, I mean that I get a minified/uglified/revv-ed version of JQuery in
dist/js/50b6.app.js
On the continuous integration build setup, which runs Linux, I get an empty js file:
dist/js/d41d.app.js
I updated Grunt and all plugins to the latest version, without success. Analyzed my full Gruntfile.js, verified the src and dest of all the plugins and all seems the same, taking into account the difference in platform specific path separators.
Here is the link to the sources of my Jekyll site: site-ringo
Eventually, I was able to resolve this myself. I hadn't updated my local Bower components for a while. On my build server, I ended up with another version of JQuery than on my local machine. The newer JQuery was packaged differently leading to the jquery.js file being in another location. As such, the concat+uglify+rev build chain didn't pick up the correct file leading to the output file being empty.