Single Page Javascript Application
I have built a sophisticated ajax-driven single page webapp that uses a RESTful backend web service serving JSON. The javascript is split into many different files, each file representing some sort of feature or component.
While the service has been in alpha testing, I've just be serving all these files separately without minification. But now that I'd like to launch a beta version, I really need to combine files, minify them, and version them. I want to add this to my build process, using Maven.
Javascript File Types
I'm using the following "types" of javascript files, of which #3 and #4 are my concerns:
External files, such a jquery and jquery-ui served from the Google CDN. Rarely change these versions, can be handled manually.
Jquery plugins that I'm hosting myself, such as fullcalendar or ui-layout. Again, I rarely update these to new versions and can handle it manually.
Application-wide javascript code. Custom javascript that is spread across many files and can change occasionally. All of these files need to be loaded for the app to work.
Feature-specific javascript code. Custom javascript that is loaded on demand when a specific feature is requested. This code can change quite frequently and is not loaded at startup.
Build Objectives
I'd like to do the following during my build process:
Concatenate all type 3 javascript files together, minify them, and save as a single file with a version number. For instance: app-2.0.6.min.js, where 2.0.6 is the maven project version.
All type 4 files should be individually minified and saved as separate files with version numbers in the name. For instance: feature-abc-56ab32de29.min.js, where 56ab32de29 is the version number of that specific file.
Update HTML files with <script> tags to point to javascript files with the correct version numbers.
Update Javscript files that load type 4 feature javascript files to point to the right versions.
Questions
Is there a maven plugin that will assist with the concatenation?
Is there a maven plugin that will assist with the minification? Ideally, I'd like to use Google Closure Compiler, but would work with others if simpler.
Is there a maven plugin that will assist with the versioning?
Is there a way to have the type 4 javascript files have independent version numbers? Ideally, if a file doesn't change between version 2.0.5 and 2.0.6, there is no need for users to download a new version and their cached version would work fine. I'm using GIT for source control, so would there be a way to use a file's GIT hashcode for versioning?
Is there a solution that will compress the javascript that is inline in regular HTML files without killing the HTML?
Is there a solution that will compress and version my CSS files as well?
Take a look at the yuicompressor-maven-plugin. It can aggregate various js (as well as css) files as well as minify and obfuscate them.
Here's a brand-new Maven plugin that targets this task: http://mojo.codehaus.org/webminifier-maven-plugin/
I've successfully incorporated RequireJS optimization (uses Google Closure compiler + does concatenation) in a Maven environment (for single page JS app). See my question and the follow up answer for details: RequireJS Compilation in Maven project with external JS dependencies
You could probably expand on that to version and archive the minified JS artifacts.
Related
I have a legacy project, it was built using cdn urls and local scripts (some them are minified).
Everytime I need (manually) minify every file to a better perfomance on frontend.
Is possible use webpack in this case? If there are some others options, will be welcome!!
I've recently been thrown in to clean up a project which has like 45-50 individual .js javascript files. I wonder what the best approach would be to decrease the loading size of them all. Just concatenate all files into one with npm or gulp? Install some module loader? webpack?
If you're already concatenating, minifying, and uglifying and you don't want all the files to be loaded on all the pages due to a monolithic bundle, you might be looking for something like Webpack's Commons Chunk Plugin.
This plugin walks down the tree of dependencies for each endpoint defined in your Webpack.config file and determines which modules are required across all pages. It then breaks the code into two bundles, a "common" bundle containing the modules that every page requires, which you must load with a script tag on each page:
<script src="commons.js" charset="utf-8"></script>
And an endpoint bundle for each individual page that you reference normally in a script tag placed after the commons script tag:
<script src="specificpage.bundle.js" charset="utf-8"></script>
The result is that an individual page will not have to load modules that will only ever be used on other pages.
Again, this is a Webpack plugin. I don't know if this functionality is available as a Gulp plugin, because it must have knowledge of all endpoints in order to determine which dependencies are common to them all.
I redirect you to the very good https://github.com/thedaviddias/Front-End-Checklist
In particular the following advises:
JavaScript Inline: High You don't have any JavaScript code inline
(mixed with your HTML code).
Concatenation: High JavaScript files
are concatenated.
Minification: High JavaScript files are minified (you can add the .min suffix).
You can accomplish this with a package manager such as gulp, grunt or webpack (for the most famous ones). You just need to choose what you prefer to use.
If you consider webpack, You can start with my very simple (but understanding) starter: https://github.com/dfa1234/snippets-starter
There's no much thing that you can do, basically is:
Concatenation - https://www.npmjs.com/package/gulp-concat
Minification - https://www.npmjs.com/package/gulp-minify
Instead of creating all those scripts, you can get something to re-use on yeoman, f.e. the Fountain, so it will reduce a lot of time just typing procedural code for doing the concatenation/minification.
Also if you can use some lazy load (like RequireJS or some frameworks have support to lazy load the module, like Angular) that will improve the performance of your aplication
EDIT:
If you want even more performance, you can install some compression tool in your server, for example this one for NodeJS https://www.npmjs.com/package/compression
I'm my personal opinion, if you have time, the best approach would be to read and understand the purpose of the project. Then plan a proper refactor. You are not fixing anything with concatenating, this is just a deployment step.
You should analyze which technologies are being used and if you want to maintain this code, in the long run, make a proper refactor into a much more modern stack, maybe you can take a seed project with ES6, webpack, Babel... and create a proper repository well maintained with proper modularity and dependencies resolution.
Once you have that, decreasing the load its just about adding proper tools in build time (babel, webpack, etc).
You would like to add some unit tests and continue working properly :)
Is there is any way to have a common project which contains plugin, java script file etc and there is a multiple Cordova project which can access/get those plugins and java script files.
For an example, Cordova-Project-A and Cordova-Project-B has some common plugins, CSS files and java script files. So need to separate these common codes and place it on separate project.
Note: Cordova templates will do this work. But if there is any plugin/JS file update in the template, it won't reflect anything on Cordova projects.
there is. this place is called npm, and it serves as a giant, worldwide, warehouse for javascript developers. by the way, cordova is already using it to power its plugin system.
to join the party:
create the desired projects to contain the common, extracted, code as npm projects (i.e. use npm init on them).
use npm's link to always have the updated source in all consuming projects.
I need your help with website project I'm working on. My project consits of 7 html documents, 3 stylesheets, 8 .js (including jquery.min.js and some jquery plugins) and some pictures. I want to bundle and minify it as much as it is possible (it would be good to get only 1 css and 1 js file or maybe 1 js, which contains styles inside).
For clarity - now, when I have all dependencies in html - everything is working properly. But I'm not sure how to set all module.exports and requires. Could you tell me how to do it step-by-step in a proper way?
Many thanks in advance.
PS. I write in ES5, so I don't use Babel.
You can do the following to make your codebase a bit more tidy.
Manually group the content of your relevant js files into one and export it as a nodejs module by using module.exports = module_name on the top of your merged js script (Repeat as needed for any jscripts in your project).
Then include the exported module in your main node file and include its main functionality using var modulesfile = require(./module_name); Please note directory paths while importing your js modules.
You can also run a minifier like minifyjs to make your js files size even smaller if they need to be called multiple times from a url. Nodejs installation and usage for minifyjs can be found here.
You can also call other css from within existing ones by using the
#import url("./css/filename.css"); Just verify proper css directory paths first.
In case you also want to use browserify for node there is a full guide in the npm website.
Another good and simple solution is to move all of your codebase in a visual studio web project. From there you can do pretty much what you want, organize your scripts and css files (/Scripts and /Content directories) in bundled configuration files etc.
NOTE: All your code has to be migrated to an asp .NET project to use this approach (as per Microsoft doc) properly.
I have many JS snippets and files shared across multiple projects. I have to either copy-past them into a single file for each project, or serve them as individual files on cdn. Both are bad ideas.
Is there any dependency management and build tool like Maven for JavaScript? Ideally it would take a set of js dependencies and build a single js file which can be served on cdn.
I can write a script to do that. But I'm looking to find if anything comparable to Maven exists for JS.
Update 2014: Based on answers here and my research following are most popular tools:
Bower, NPM, RequireJS, Browserify, Webpack, Grunt, Gulp
There's RequireJS, but that's kind of a different thing than Maven, and what you're asking it to do is different than Maven too. There are any number of JS combiner/minifiers, like jekyll-combiner and a zillion others.
If you're using Maven, the JavaScript Maven Tools might be of interest. If you're not, I don't know of a unified way to specifiy, download, combine, etc. for arbitrary build systems. Some of the node.js stuff might be useful, but I've never used that outside of a node.js context, so I'm not sure.
http://webjars.org/ packages JS libraries as JAR files and makes them available under Maven.
RequireJS is not a replacement to WebJars; it complements it.RequireJS will use public JS files (on CDNs) at runtime, whereas Webjars will download the necessary files at build-time and have you host them yourself.
Because most JS files are not hosted on CDNs, I use Webjars to download the necessary JS files at build-time, and reference them using RequireJS. That way I get the best of both worlds.
Take a look to grunt. It's very flexible build tool for javascript projects. Used by jquery team and other big projects. It combine, minify, test, lint js files, wtitten in javascript, have dozens plugins for whatever you want