Quick note about the project
The Listing Generator is a webapp that generates HTML listings to be pasted into eBay. The project made up of two sections.- main - the webapp tool for generating HTML eBay listings; this tool is not customer facing
- ebay - scripts & stylesheet that the generated eBay listings reference; these are loaded by customers when they view a eBay listing and is separately hosted from main.
My build process
1. Validate scripts
Task: grunt-contrib-jshintJshint provides many configuration options which can be specified in Gruntfile or a .jshintrc file. I found that .jshintrc was not a good option if you want different configurations for different scripts - as overriding/merging the settings from the .jshintrc file is not possible - it's all or nothing! Also .jshintrc is JSON format so comments are a bit tricky. I prefer to specify a set global options and override it in the subtasks all within the Gruntfile. The downside is the Gruntfile will be a bit more bulky.
Jshint also generates a lot of formatting errors about missing semicolon, trailing spaces, inconsistent indentation etc which i suppress as i'm not too concerned about formatting. The ones i founded helpful: "undef" which catches leaking global variables, "unused" which catches variables declared but not used. Here's the configuration options I've used:
jshint: { options:{ // enforcing options "bitwise": true, "camelcase": false, "curly": false, "eqeqeq": false, "immed": true, "latedef": true, "newcap": true, "noarg": true, "regexp": true, "undef": true, "unused": true, "strict": true, "trailing": false, // trailing whitespace // relaxing options "asi":true, // missing semicolon "eqnull":true, "esnext": true, // ECMAScript 6 warning "laxbreak": true,// unsafe line breakings "smarttabs":true, // mixed tabs & spaces "sub":true, // square brackets instead of dot notation // environments "browser": true, // supress other warnings - I suppress these as I use truthy/falsy comparison a lot '-W041': true, // strict compare '-W099':true // Use '===' to compare with '0' }, grunt:{ options:{ "node": true // node environment }, files:{ src:['Gruntfile.js'] } }, main: { // non-customer-facing scripts - can be less strict
//- turning on devel & nonstandard to allow console.log() and escape() options:{ 'devel':true,
'nonstandard':true, ignores:['src/scripts/lib/**'], // don't lint library files globals:{ require:false, // used by requirejs define:false, gapi:false // used by google analytics } }, files:{ src:['src/scripts/**/*.js', 'test/spec/**/*.js'] } }, ebay: { //customer-facing scripts options:{ globals:{ "GH_config":false, // ebay specified globals "domain":false, "ebayItemID":false, "eBayTRItemId":false, "ActiveXObject":false, "_rg":false } }, files:{ src:['ebay/**/*.js'] } }
2. Clean distribution folder
Task: grunt-contrib-cleanI setup subtasks for cleaning all, or just 'main' or 'ebay' part of the project
clean: { all:['dist'], main:['dist/main'], ebay:['dist/ebay'] }
3. Copy files that don't require optimisation
Task: grunt-copy-toI first tried to use grunt-contrib-copy which is maintained by the Grunt team, but couldn't get it to work consistently. It would sometimes fail silently by creating folders but not copy any files over. I spent ages debugging to no avail. Once I switched over to grunt-copy-to it worked as expected. grunt-copy-to also has the advantage of only copying newer files - making the build process faster.
As most of the source files are optimised and copied by other tasks, I just needed this task to copy everything in the deploy folder to dist/main.
copyto: { main: { files: [{cwd:'deploy/',src: ['.*','**'], dest: 'dist/main/'}] } }Note:
'**'
does not match an extension only file (eg. .htacess) so use ['.*','**']
to match everything in a directory4. Optimize JS
Tasks: grunt-contrib-requirejs, grunt-contrib-uglify'Main' is a requireJS project with text plugin and I uses grunt-contrib-requirejs with the inlineText option enabled for optimisation to generate two Javascript modules: bootstrap.js and drive.js (conditionally loaded from bootstrap.js)
requirejs: { main:{ options:{ baseUrl: "src/scripts/", mainConfigFile: "src/scripts/bootstrap.js", dir: "dist/main/scripts/", paths:{ jquery:'empty:', // jquery load via CDN - don't optimise handlebars:'empty:', }, modules:[{ name:'bootstrap', exclude:['jquery','handlebars'] },{ name:'drive', exclude:['jquery','handlebars','bootstrap'] // exclude bootstrap as this script is conditional-loaded from bootstrap }], inlineText:true, // use text plugin useStrict: true, removeCombined:true // don't copy combined js to dist } } }
I used grunt-contrib-uglify for "ebay" project as it does not use requirej.
uglify: { ebay: { options: { banner: '<%= banner %>' }, files:{ 'dist/ebay/info.js':'src/ebay/info.js', 'dist/ebay/rg.js':'src/ebay/rg.js' } } }
5. Optimise CSS
Task: grunt-contrib-cssminAs I only have one CSS file each for each sub-project, it's a fairly straightforward css minification.
cssmin: { main:{ files: { 'dist/main/styles/styles.css': 'src/styles/styles.css' } }, ebay:{ files: { 'dist/ebay/styles.css': 'src/ebay/styles.css' } } }For other projects where I use SASS I use grunt-contrib-compass.
6. Optimise images
Task: grunt-contrib-imageminYou can set optimisation levels for the images - I just leave it at the default setting
imagemin: { ebay: { files: [{ expand: true, cwd: 'src/ebay', src: '{,*/}*.{gif,jpeg,jpg,png}', dest: 'dist/ebay' }] } }
7.Cache-busting
This was slightly tricky and subject to another blog post!8. Deploy on to server with FTP
Task: grunt-ftp-deployDeployment via FTP. The login info is stored in a .ftppass file which should be excluded from git. I have 'ebay' build deploying to a versioned directory, which makes rollback easier when required! Also don't add this task to the 'default' grunt task just in case you deploy something accidentally! I also increment the version with
npm version
before i deploy. 'ftp-deploy': { main: { ... }, ebay: { auth: { host: 'ftp.example.com', port: 21, authKey: 'key1' // username/password stored in .ftppass }, src: 'dist/ebay', dest: '/path/to/server/<%= pkg.version %>', // deploy as the current package.json version } }
Other things to add to my Gruntfile
- Add watch tasks for starting the server and autorefresh on file change
- Add unit-tests with grunt-mocha-phantom I've been putting this off, which is bad :-/
Tips & resources
- Grunt website's sample gruntfile is a good place to start
- Yo webapp generator generates a great Gruntfile, although it does a lot of things and probably needs better documentation to explain what each task does!
- David Tucker's blog post on Grunt is very detailed helped me a lot in setting up my Gruntfile.
- Use load-grunt-tasks to replace all those
grunt.loadNpmTasks(...)
statements in the Gruntfile.
Just addrequire('load-grunt-tasks')(grunt)
This system is one that is designed so that when the player has received over a 3rd of their bets (less than the anticipated 18/38), they'll win. This occurs as a result of|as a end result of} because the player loses, the 메리트카지노 average wager size in the line increases. Negative progression systems contain growing the size of 1's wager once they lose. The goal of this system is to recoup losses sooner so that one can return to a winning place more rapidly after a shedding streak.
ReplyDeleteAlthough it’s not as catchy as it was once, many 온라인카지노 sources nonetheless consider that it has a bright future similar to other tables games. But since we now have a lot of other on line casino games, it begs the question of whether blackjack remains to be the most well-liked on line casino recreation. Blackjack does not aim to switch an business powerhouse similar to Houdini. All proper, you are located at the desk, you've made your bet in the betting field, and your coronary heart is pumping like a jackhammer.
ReplyDelete