{"id":272,"date":"2015-01-10T02:00:00","date_gmt":"2015-01-10T02:00:00","guid":{"rendered":"http:\/\/localhost\/?p=272"},"modified":"2017-01-09T07:04:15","modified_gmt":"2017-01-09T07:04:15","slug":"minifying-your-source-code","status":"publish","type":"post","link":"https:\/\/ionic.io\/blog\/minifying-your-source-code","title":{"rendered":"Minifying Your App&#8217;s Source Code"},"content":{"rendered":"<p><em>This is a guest post by Nic Raboy, an application developer with a strong background in Android, AngularJS, Ionic, Java, SQL, and Unity3D. Nic writes often about Ionic and how to build great hybrid apps.<\/em><\/p>\n<p>Previously, I wrote about the importance of uglifying your Apache Cordova source code. If you read my <a href=\"https:\/\/blog.nraboy.com\/2014\/11\/extract-android-apk-view-source-code\/\" rel=\"nofollow\">previous post<\/a> you&#8217;ll know that hybrid applications are incredibly easy to decompile, so uglifying your code creates additional difficulty for any malicious user.<\/p>\n<p>I also wrote a <a href=\"https:\/\/blog.nraboy.com\/2014\/12\/use-grunt-lint-uglify-javascript-project\/\" rel=\"nofollow\">generic post<\/a> about how to use<br \/>\nthe Grunt task runner to lint and uglify your code. However, using Grunt isn&#8217;t the most ideal solution when it comes to<br \/>\nlinting your Apache Cordova project for errors and uglifying your code.<\/p>\n<p>In this guide, we&#8217;re going to see how to efficiently lint and minify your Apache Cordova project before building. The same information can be applied against <a href=\"http:\/\/phonegap.com\/\" rel=\"nofollow\">Phonegap<\/a> and <a href=\"http:\/\/www.ionicframework.com\" rel=\"nofollow\">Ionic<br \/>\nFramework<\/a> projects, too.<\/p>\n<p><!--more--><\/p>\n<p>Let&#8217;s start by creating a fresh Apache Cordova Android and iOS project:<\/p>\n<pre><code class=\"bash\">cordova create TestProject com.nraboy.testproject TestProject\ncd TestProject\ncordova platform add android\ncordova platform add ios\n<\/code><\/pre>\n<p>Note that if you&#8217;re not using a Mac, you cannot add or build for the iOS platform.<\/p>\n<p>This tutorial is going to be broken into two parts:<\/p>\n<ul>\n<li>Linting the project for JavaScript errors<\/li>\n<li>Uglifying the code for obfuscation purposes<\/li>\n<\/ul>\n<p>Once you&#8217;ve run these steps, your project will be in much better shape.<\/p>\n<h3 id=\"lintingtheprojectforjavascripterrors\">Linting the project for JavaScript errors<\/h3>\n<p>One of my subscribers recommended I check out <a href=\"https:\/\/www.npmjs.com\/package\/cordova-linter\" rel=\"nofollow\">Cordova Linter<\/a> for this task. I checked it out and couldn&#8217;t figure out how to get it to work. It kept saying my project had no errors, when I know it did. The package had no documentation to prove its process.<\/p>\n<p>This is when I decided to create my own Apache Cordova hook. If you&#8217;ve read my <a href=\"https:\/\/blog.nraboy.com\/2015\/01\/hooks-apache-cordova-mobile-applications\/\" rel=\"nofollow\">previous<br \/>\npost<\/a> regarding hooks, you should have a general idea of what we&#8217;re going to do.<\/p>\n<p>Create <code>hooks\/before_prepare\/02_jshint.js<\/code>, and make sure to give it execute permissions if you&#8217;re using Linux or Mac. Based on the file title, you can probably guess we&#8217;re going to use <a href=\"http:\/\/jshint.com\/docs\/\">JSHint<\/a> for linting. Open <code>02_jshint.js<\/code>, and add the following code:<\/p>\n<pre><code class=\"javascript\">#!\/usr\/bin\/env node\n\nvar fs = require(&#039;fs&#039;);\nvar path = require(&#039;path&#039;);\nvar jshint = require(&#039;jshint&#039;).JSHINT;\nvar async = require(&#039;async&#039;);\n\nvar foldersToProcess = [\n    &#039;js&#039;\n];\n\nfoldersToProcess.forEach(function(folder) {\n    processFiles(&quot;www\/&quot; + folder);\n});\n\nfunction processFiles(dir, callback) {\n    var errorCount = 0;\n    fs.readdir(dir, function(err, list) {\n        if (err) {\n            console.log(&#039;processFiles err: &#039; + err);\n            return;\n        }\n        async.eachSeries(list, function(file, innercallback) {\n            file = dir + &#039;\/&#039; + file;\n            fs.stat(file, function(err, stat) {\n                if(!stat.isDirectory()) {\n                    if(path.extname(file) === &quot;.js&quot;) {\n                        lintFile(file, function(hasError) {\n                            if(hasError) {\n                                errorCount++;\n                            }\n                            innercallback();\n                        });\n                    } else {\n                        innercallback();\n                    }\n                } else {\n                    innercallback();\n                }\n            });\n        }, function(error) {\n            if(errorCount &gt; 0) {\n                process.exit(1);\n            }\n        });\n    });\n}\n\nfunction lintFile(file, callback) {\n    console.log(&quot;Linting &quot; + file);\n    fs.readFile(file, function(err, data) {\n        if(err) {\n            console.log(&#039;Error: &#039; + err);\n            return;\n        }\n        if(jshint(data.toString())) {\n            console.log(&#039;File &#039; + file + &#039; has no errors.&#039;);\n            console.log(&#039;-----------------------------------------&#039;);\n            callback(false);\n        } else {\n            console.log(&#039;Errors in file &#039; + file);\n            var out = jshint.data(),\n            errors = out.errors;\n            for(var j = 0; j &lt; errors.length; j++) {\n                console.log(errors[j].line + &#039;:&#039; + errors[j].character + &#039; -&gt; &#039; + errors[j].reason + &#039; -&gt; &#039; +\nerrors[j].evidence);\n            }\n            console.log(&#039;-----------------------------------------&#039;);\n            callback(true);\n        }\n    });\n}\n<\/code><\/pre>\n<p>The above script will look at only the <code>www\/js<\/code> directory, but feel free to add further directories. All files in the directory will be looped through, and if they are JavaScript, the file will be fed into JSHint. If any files contain errors, they will be presented to the screen, and then the script will stop all further processes. This means that if you execute the script with <code>cordova build [platform]<\/code>, the application will not continue to build if errors are found.<\/p>\n<p><code>02_jshint.js<\/code> requires two NodeJS libraries in order to function. They can be installed like this from the root of<br \/>\nyour project:<\/p>\n<pre><code class=\" bash\">$ npm install jshint\n$ npm install async\n<\/code><\/pre>\n<h3 id=\"uglifyingthecodeforobfuscationpurposes\">Uglifying the code for obfuscation purposes<\/h3>\n<p>One of my other subscribers recommended I check out <a href=\"https:\/\/www.npmjs.com\/package\/cordova-uglify\">Cordova Uglify<\/a> for the obfuscation process. Unlike Cordova Linter, this NPM package actually worked as advertised. From the root of your Apache Cordova project, run the following command:<\/p>\n<pre><code class=\"bash\">$ npm install cordova-uglify\n<\/code><\/pre>\n<p>When the installation completes, you should find that <code>hooks\/after_prepare\/uglify.js<\/code> was created. If you&#8217;re on Linux<br \/>\nor Mac, you&#8217;ll need to give it execute permissions; otherwise, it won&#8217;t be picked up.<\/p>\n<p>You can test that this script worked by running <code>cordova prepare<\/code> or <code>cordova build [platform]<\/code>.<\/p>\n<h3 id=\"conclusion\">Conclusion<\/h3>\n<p>By default, Apache Cordova does not check your code for errors when building. This means you won&#8217;t know if errors exist in your code until you run your application. Linting your code can save you a lot of stress when it comes to finding errors caused by typos or missing\/extra brackets.<\/p>\n<p>Your hard work is very easy to decompile by default, so it is a good idea to obfuscate your code by means of uglification before you release your application.<\/p>\n<p>Two videos for this article can be seen below:<\/p>\n<p><iframe loading=\"lazy\" width=\"100%\" height=\"510\" data-src=\"\/\/www.youtube.com\/embed\/qQiYE6x7cFk\" frameborder=\"0\" allowfullscreen=\"\" src=\"data:image\/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" class=\"lazyload\" data-load-mode=\"1\"><\/iframe><\/p>\n<p><iframe loading=\"lazy\" width=\"100%\" height=\"510\" data-src=\"\/\/www.youtube.com\/embed\/hoy3MESySWQ\" frameborder=\"0\" allowfullscreen=\"\" src=\"data:image\/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\" class=\"lazyload\" data-load-mode=\"1\"><\/iframe><\/p>\n","protected":false},"excerpt":{"rendered":"<p>This is a guest post by Nic Raboy, an application developer with a strong background in Android, AngularJS, Ionic, Java, SQL, and Unity3D. Nic writes often about Ionic and how to build great hybrid apps. Previously, I wrote about the importance of uglifying your Apache Cordova source code. If you read my previous post you&#8217;ll [&hellip;]<\/p>\n","protected":false},"author":8,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"publish_to_discourse":"","publish_post_category":"","wpdc_auto_publish_overridden":"","wpdc_topic_tags":"","wpdc_pin_topic":"","wpdc_pin_until":"","discourse_post_id":"","discourse_permalink":"","wpdc_publishing_response":"","wpdc_publishing_error":"","_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[1],"tags":[3],"class_list":["post-272","post","type-post","status-publish","format-standard","hentry","category-all","tag-ionic"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v23.0 (Yoast SEO v23.0) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Minifying Your App&#039;s Source Code - Ionic Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/ionic.io\/blog\/minifying-your-source-code\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Minifying Your App&#039;s Source Code\" \/>\n<meta property=\"og:description\" content=\"This is a guest post by Nic Raboy, an application developer with a strong background in Android, AngularJS, Ionic, Java, SQL, and Unity3D. Nic writes often about Ionic and how to build great hybrid apps. Previously, I wrote about the importance of uglifying your Apache Cordova source code. If you read my previous post you&#8217;ll [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/ionic.io\/blog\/minifying-your-source-code\" \/>\n<meta property=\"og:site_name\" content=\"Ionic Blog\" \/>\n<meta property=\"article:published_time\" content=\"2015-01-10T02:00:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2017-01-09T07:04:15+00:00\" \/>\n<meta name=\"author\" content=\"Nic Raboy\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@nraboy\" \/>\n<meta name=\"twitter:site\" content=\"@ionicframework\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Nic Raboy\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"4 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/ionic.io\/blog\/minifying-your-source-code#article\",\"isPartOf\":{\"@id\":\"https:\/\/ionic.io\/blog\/minifying-your-source-code\"},\"author\":{\"name\":\"Nic Raboy\",\"@id\":\"https:\/\/ionic.io\/blog\/#\/schema\/person\/e4c6a16b5b7a115afcdab9816c3f9e77\"},\"headline\":\"Minifying Your App&#8217;s Source Code\",\"datePublished\":\"2015-01-10T02:00:00+00:00\",\"dateModified\":\"2017-01-09T07:04:15+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/ionic.io\/blog\/minifying-your-source-code\"},\"wordCount\":631,\"publisher\":{\"@id\":\"https:\/\/ionic.io\/blog\/#organization\"},\"keywords\":[\"Ionic\"],\"articleSection\":[\"All\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/ionic.io\/blog\/minifying-your-source-code\",\"url\":\"https:\/\/ionic.io\/blog\/minifying-your-source-code\",\"name\":\"Minifying Your App's Source Code - Ionic Blog\",\"isPartOf\":{\"@id\":\"https:\/\/ionic.io\/blog\/#website\"},\"datePublished\":\"2015-01-10T02:00:00+00:00\",\"dateModified\":\"2017-01-09T07:04:15+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/ionic.io\/blog\/minifying-your-source-code#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/ionic.io\/blog\/minifying-your-source-code\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/ionic.io\/blog\/minifying-your-source-code#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/ionic.io\/blog\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Minifying Your App&#8217;s Source Code\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/ionic.io\/blog\/#website\",\"url\":\"https:\/\/ionic.io\/blog\/\",\"name\":\"ionic.io\/blog\",\"description\":\"Build amazing native and progressive web apps with the web\",\"publisher\":{\"@id\":\"https:\/\/ionic.io\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/ionic.io\/blog\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/ionic.io\/blog\/#organization\",\"name\":\"Ionic\",\"url\":\"https:\/\/ionic.io\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/ionic.io\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2020\/10\/white-on-color.png\",\"contentUrl\":\"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2020\/10\/white-on-color.png\",\"width\":1920,\"height\":854,\"caption\":\"Ionic\"},\"image\":{\"@id\":\"https:\/\/ionic.io\/blog\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/x.com\/ionicframework\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/ionic.io\/blog\/#\/schema\/person\/e4c6a16b5b7a115afcdab9816c3f9e77\",\"name\":\"Nic Raboy\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/ionic.io\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/80ca16a986c827c91604fac0c8eba63e2eae09be264ec1f701cf75633451daa2?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/80ca16a986c827c91604fac0c8eba63e2eae09be264ec1f701cf75633451daa2?s=96&d=mm&r=g\",\"caption\":\"Nic Raboy\"},\"description\":\"This is a guest post by Nic Raboy, an application developer with a strong background in Android, AngularJS, Ionic, Java, SQL, and Unity3D. Nic writes often about Ionic and how to build great hybrid apps. He can be further followed via his blog at https:\/\/www.thepolyglotdeveloper.com\",\"sameAs\":[\"https:\/\/www.thepolyglotdeveloper.com\",\"https:\/\/x.com\/nraboy\"],\"url\":\"https:\/\/ionic.io\/blog\/author\/nraboy\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Minifying Your App's Source Code - Ionic Blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/ionic.io\/blog\/minifying-your-source-code","og_locale":"en_US","og_type":"article","og_title":"Minifying Your App's Source Code","og_description":"This is a guest post by Nic Raboy, an application developer with a strong background in Android, AngularJS, Ionic, Java, SQL, and Unity3D. Nic writes often about Ionic and how to build great hybrid apps. Previously, I wrote about the importance of uglifying your Apache Cordova source code. If you read my previous post you&#8217;ll [&hellip;]","og_url":"https:\/\/ionic.io\/blog\/minifying-your-source-code","og_site_name":"Ionic Blog","article_published_time":"2015-01-10T02:00:00+00:00","article_modified_time":"2017-01-09T07:04:15+00:00","author":"Nic Raboy","twitter_card":"summary_large_image","twitter_creator":"@nraboy","twitter_site":"@ionicframework","twitter_misc":{"Written by":"Nic Raboy","Est. reading time":"4 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/ionic.io\/blog\/minifying-your-source-code#article","isPartOf":{"@id":"https:\/\/ionic.io\/blog\/minifying-your-source-code"},"author":{"name":"Nic Raboy","@id":"https:\/\/ionic.io\/blog\/#\/schema\/person\/e4c6a16b5b7a115afcdab9816c3f9e77"},"headline":"Minifying Your App&#8217;s Source Code","datePublished":"2015-01-10T02:00:00+00:00","dateModified":"2017-01-09T07:04:15+00:00","mainEntityOfPage":{"@id":"https:\/\/ionic.io\/blog\/minifying-your-source-code"},"wordCount":631,"publisher":{"@id":"https:\/\/ionic.io\/blog\/#organization"},"keywords":["Ionic"],"articleSection":["All"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/ionic.io\/blog\/minifying-your-source-code","url":"https:\/\/ionic.io\/blog\/minifying-your-source-code","name":"Minifying Your App's Source Code - Ionic Blog","isPartOf":{"@id":"https:\/\/ionic.io\/blog\/#website"},"datePublished":"2015-01-10T02:00:00+00:00","dateModified":"2017-01-09T07:04:15+00:00","breadcrumb":{"@id":"https:\/\/ionic.io\/blog\/minifying-your-source-code#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/ionic.io\/blog\/minifying-your-source-code"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/ionic.io\/blog\/minifying-your-source-code#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/ionic.io\/blog"},{"@type":"ListItem","position":2,"name":"Minifying Your App&#8217;s Source Code"}]},{"@type":"WebSite","@id":"https:\/\/ionic.io\/blog\/#website","url":"https:\/\/ionic.io\/blog\/","name":"ionic.io\/blog","description":"Build amazing native and progressive web apps with the web","publisher":{"@id":"https:\/\/ionic.io\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/ionic.io\/blog\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/ionic.io\/blog\/#organization","name":"Ionic","url":"https:\/\/ionic.io\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/ionic.io\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2020\/10\/white-on-color.png","contentUrl":"https:\/\/ionic.io\/blog\/wp-content\/uploads\/2020\/10\/white-on-color.png","width":1920,"height":854,"caption":"Ionic"},"image":{"@id":"https:\/\/ionic.io\/blog\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/x.com\/ionicframework"]},{"@type":"Person","@id":"https:\/\/ionic.io\/blog\/#\/schema\/person\/e4c6a16b5b7a115afcdab9816c3f9e77","name":"Nic Raboy","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/ionic.io\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/80ca16a986c827c91604fac0c8eba63e2eae09be264ec1f701cf75633451daa2?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/80ca16a986c827c91604fac0c8eba63e2eae09be264ec1f701cf75633451daa2?s=96&d=mm&r=g","caption":"Nic Raboy"},"description":"This is a guest post by Nic Raboy, an application developer with a strong background in Android, AngularJS, Ionic, Java, SQL, and Unity3D. Nic writes often about Ionic and how to build great hybrid apps. He can be further followed via his blog at https:\/\/www.thepolyglotdeveloper.com","sameAs":["https:\/\/www.thepolyglotdeveloper.com","https:\/\/x.com\/nraboy"],"url":"https:\/\/ionic.io\/blog\/author\/nraboy"}]}},"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/ionic.io\/blog\/wp-json\/wp\/v2\/posts\/272","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ionic.io\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ionic.io\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ionic.io\/blog\/wp-json\/wp\/v2\/users\/8"}],"replies":[{"embeddable":true,"href":"https:\/\/ionic.io\/blog\/wp-json\/wp\/v2\/comments?post=272"}],"version-history":[{"count":0,"href":"https:\/\/ionic.io\/blog\/wp-json\/wp\/v2\/posts\/272\/revisions"}],"wp:attachment":[{"href":"https:\/\/ionic.io\/blog\/wp-json\/wp\/v2\/media?parent=272"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ionic.io\/blog\/wp-json\/wp\/v2\/categories?post=272"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ionic.io\/blog\/wp-json\/wp\/v2\/tags?post=272"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}