Aerosol Posted January 7, 2015 Report Share Posted January 7, 2015 OverviewIn Part I we setup basic project and prepared output package for mobile device. This got us some benefits coming from statically typed system provided by Typescript, dependency loading and given us some automation in building and possible integration with Continuous Integration systems.This part will cover additional tools that can be used to provide better cooperation with other developers and template engines. We will cover following topics:Templates of view Templates of CSS stylesMaintenanceJade - view templatesJade is powerful template engine for HTML pages or snippets that can be controlled via models passed. Traditionally it's more used for web servers to provide base templates however with our setup we can easily reuse this component to prepare mobile web applications and take away some of redundancy coming to play with .To start with we install Jade task for Grunt:> npm install grunt-contrib-jade --save-devNow we can update our existing views/index.html file to views/index.jade file:html head script(data-main='js/config', src='js/require.js') body #corpus Hello, world!And finally update our Gruntfile.js to execute new task:module.exports = function(grunt) { // Project configuration. grunt.initConfig({ pkg: grunt.file.readJSON('package.json'), typescript: { base: { src: ['src/**/*.ts'], dest: './dist/www/js', options: { module: 'amd', //or commonjs target: 'es5', //or es3 base_path: 'src' } } }, copy: { libs: { files: [ { flatten: true, expand: true, src: ['lib/require.js'], dest: 'dist/www/js/'} ] }, tizen: { files: [ { flatten: true, expand: true, src: ['platform/tizen/**'], dest: 'dist/tizen'}, { flatten: true, expand: true, src: ['dist/www/index.html'], dest: 'dist/tizen'}, { flatten: true, expand: true, src: ['dist/www/js/*'], dest: 'dist/tizen/js'} ] } }, zip: { tizen: { src: 'dist/tizen/*', cwd: 'dist/tizen', dest: 'dist/helloWorld.wgt' } }, jade: { compile: { options: { data: { debug: true } }, files: { "dist/www/index.html": ["views/*.jade"] } } } }); grunt.loadNpmTasks('grunt-typescript'); grunt.loadNpmTasks('grunt-contrib-copy'); grunt.loadNpmTasks('grunt-zip'); grunt.loadNpmTasks('grunt-contrib-jade'); // Default task(s). grunt.registerTask('default', ['copy:libs', 'typescript', 'jade']); grunt.registerTask('tizen', ['default', 'copy:tizen', 'zip:tizen']);};This approach has added benefit of simpler structure (no need to use closing tags), better readability and ability to use inheritance, blocks and includes.Stylus - CSS templatesSimilar approach as for views can be used for CSS by using Stylus; in this case benefit is less obvious but with help of in-line conditioning and functions which can take away some of the maintenance problems. Approach to integrate with our solution is straightforward:> npm install grunt-contrib-stylus --save-devPut initial style definition into styles/index.styl:body font: 62.5% "Trebuchet MS", sans-serif#canvas margin: 8pxUpdate views/index.jade:html head link(rel='stylesheet', href='css/index.css') script(data-main='js/config', src='js/require.js') body #corpus Hello, world!And finally update Gruntfile.js:module.exports = function(grunt) { // Project configuration. grunt.initConfig({ pkg: grunt.file.readJSON('package.json'), typescript: { base: { src: ['src/**/*.ts'], dest: './dist/www/js', options: { module: 'amd', //or commonjs target: 'es5', //or es3 base_path: 'src' } } }, copy: { libs: { files: [ { flatten: true, expand: true, src: ['lib/require.js'], dest: 'dist/www/js/'} ] }, tizen: { files: [ { flatten: true, expand: true, src: ['platform/tizen/**'], dest: 'dist/tizen'}, { flatten: true, expand: true, src: ['dist/www/index.html'], dest: 'dist/tizen'}, { flatten: true, expand: true, src: ['dist/www/js/*'], dest: 'dist/tizen/js'}, { flatten: true, expand: true, src: ['dist/www/css/*'], dest: 'dist/tizen/css'} ] } }, zip: { tizen: { src: 'dist/tizen/*', cwd: 'dist/tizen', dest: 'dist/helloWorld.wgt' } }, jade: { compile: { options: { data: { debug: true } }, files: { "dist/www/index.html": ["views/*.jade"] } } }, stylus: { compile: { files: { 'dist/www/css/index.css': 'styles/index.styl' } } } }); grunt.loadNpmTasks('grunt-typescript'); grunt.loadNpmTasks('grunt-contrib-copy'); grunt.loadNpmTasks('grunt-zip'); grunt.loadNpmTasks('grunt-contrib-jade'); grunt.loadNpmTasks('grunt-contrib-stylus'); // Default task(s). grunt.registerTask('default', ['copy:libs', 'typescript', 'jade', 'stylus']); grunt.registerTask('tizen', ['default', 'copy:tizen', 'zip:tizen']);};MaintenanceImportant part of software development process is making sure that everyone in the team starts from same spot and follows same rules and avoid common mistakes. First part of this process can be automated by linting (CSSLint, JSLint, JSHint etc.), unit testing (QUnit), adding clean task and second part can be done by code peer reviews. Let's start by adding some more tasks:> npm install grunt-contrib-csslint grunt-contrib-jshint grunt-contrib-qunit grunt-contrib-clean --save-devNow let's make clean & lint part of our daily workflow by updating Gruntfile.js:module.exports = function(grunt) { // Project configuration. grunt.initConfig({ pkg: grunt.file.readJSON('package.json'), typescript: { base: { src: ['src/**/*.ts'], dest: './dist/www/js', options: { module: 'amd', //or commonjs target: 'es5', //or es3 base_path: 'src' } } }, copy: { libs: { files: [ { flatten: true, expand: true, src: ['lib/require.js'], dest: 'dist/www/js/'} ] }, tizen: { files: [ { flatten: true, expand: true, src: ['platform/tizen/**'], dest: 'dist/tizen'}, { flatten: true, expand: true, src: ['dist/www/index.html'], dest: 'dist/tizen'}, { flatten: true, expand: true, src: ['dist/www/js/*'], dest: 'dist/tizen/js'}, { flatten: true, expand: true, src: ['dist/www/css/*'], dest: 'dist/tizen/css'} ] } }, zip: { tizen: { src: 'dist/tizen/*', cwd: 'dist/tizen', dest: 'dist/helloWorld.wgt' } }, jade: { compile: { options: { data: { debug: true } }, files: { "dist/www/index.html": ["views/*.jade"] } } }, stylus: { compile: { files: { 'dist/www/css/index.css': 'styles/index.styl' } } }, csslint: { strict: { options: { import: 2 }, src: ['dist/www/css/*.css'] } }, jshint: { files: [ 'dist/www/js/main.js', 'dist/www/js/config.js' ], options: { force: true, // Don't fail hard .. browser: true, devel: true, globals: {define: true}, } }, clean: ['dist'] }); grunt.loadNpmTasks('grunt-typescript'); grunt.loadNpmTasks('grunt-contrib-copy'); grunt.loadNpmTasks('grunt-zip'); grunt.loadNpmTasks('grunt-contrib-jade'); grunt.loadNpmTasks('grunt-contrib-stylus'); grunt.loadNpmTasks('grunt-contrib-csslint'); grunt.loadNpmTasks('grunt-contrib-jshint'); grunt.loadNpmTasks('grunt-contrib-clean'); // Default task(s). grunt.registerTask('default', ['copy:libs', 'typescript', 'jade', 'stylus', 'csslint', 'jshint']); grunt.registerTask('tizen', ['clean', 'default', 'copy:tizen', 'zip:tizen']);};By running grunt command we will run into couple of issues in both CSS and JS files (bad, bad developer!). Most of those can be easily resolved except for W033 (missing semicolon) which is not generated by Typescript compiler in current version so we turn off hard fail for JS validation.With clean task integrated into tizen target we can ensure that everybod will always receive same build from same source files; clean task can be run also directly to force cleaning of dist directory.Complete project can be downloaded here without node_modules folder so it is necessary to run following command from project directory to load dependenciesSource Quote Link to comment Share on other sites More sharing options...