Why Refactoring Support in a JavaScript IDE Is so Important

As I’m building out a new version of the Silicon Valley Code Camp web site in AngularJS, I’m running into the very common case where I have not created my program files hierarchy optimally.  What I have now (as seen from JetBrains WebStorm) is the following:

image

I realize now that I’m adding the login screen that I really should have an app folder account and registration should be a subfolder of that.  To make that change without a good tool (like WebStorm), I would need to go into my file manager and copy the files I want, then go into my index.html file and manually change all those directory references.  Likely (because I’m not that good at that kind of work) I’d make at least one mistake and have to come back and revisit the issue again.

With WebStorm, I simply drag and drop the JavaScript files (after creating a new directory) and the index.html references are automatically cleaned up for me.

Just Sayin…

Angular and ngAnnotate, a Better Way

I recently posted to StackOverflow a question and example of how adding a dependency injection to my AngularJS app did not seem to matter regarding my program running correctly.  The answer I got back was clear, but somewhat disconcerting.  Basically, the answer is that Angular takes care of the problem for me in development but when I move to production with minification, it will fail.  Well, that sucks on so many levels. Here is an example of code that shows the problem.

angular.module('svccApp', []);

  angular.module('svccApp').
  factory('bareService', [

    function() {
      var myValue = {};
      myValue.str1 = 'xyz';
      return myValue;
    }
  ]);

  angular.module('svccApp')
    .controller('MyController', MyController);

  // WHY IS THIS NOT NECESSARY?
  //MyController.$inject = ['$scope', 'bareService'];

  function MyController($scope, bareService) {
    $scope.testVal = bareService.str1;
  }

As it turns out, there are actually 4 things I can see doing to help mitigate the issue of deploying buggy code you don’t know about. (answers included from my stackoverflow post mentioned above)

  • Test Everything in minimized JavaScript
  • Add ng-strict-di to the div containing the ng-app tag
  • Add ngAnnotate to your build process to try and fix the error automagically
  • Force your gulp or grunt build process to fail if ngAnnotate find any issues

I like number 4 best.  below is my poorly written gulp task that does that as well as a screen shot of it finding an error.  It basically gives me the code to put back into my application so it will not fail again.

gulp.task('scripts', function (cb) {
    gulp.src(['public/app/**/*.js'])
        .pipe(concat('main.js'))
        .pipe(gulp.dest('scratchfiles'));


    return gulp.src(['scratchfiles/main.js'])
        .pipe(jshint('.jshintrc'))
        .pipe(jshint.reporter('default'))
        .pipe(ngAnnotate())
        .pipe(diff())
        .pipe(diff.reporter({fail: true}))
        .pipe(gulp.dest('public/dist'))
        .pipe(rename({suffix: '.min'}))
        .pipe(uglify())
        .pipe(gulp.dest('public/dist'))
        .pipe(notify({message: 'Scripts task complete'}));
});

image

When I run the task above, the gulp diff command stops and shows me what ngAnnotate added to my JavaScript.  Then, I can go and add that myself and then my gulp build will work and it will not generate any errors.

At the moment, I can’t figure out how to get this task to stop my gulp build process so I have to run this task by itself.  I’d love to hear how to fix that also.  This is all pretty new to me.

Using Gulp to Build My JavaScript AngularJS App

Having spent the past few hours learning how Gulp works, and finally customizing it for my scenario, I feel the need to share.  As I was figuring it out, it seems that many have had my thought also.  So, for those not acquainted with Gulp, basically, it’s  is a build system of sorts that works with Node.JS. It’s got a huge community of tasks that you can use and pipeline together.

Basically, here is what my gulpfile.js does:

  • Compiles my SASS (scss) into both expanded and minified CSS
  • Runs jshint on all my JavaScript
  • Concatinates all my JavaScript together and makes both minified and non-minified versions of it
  • Optimizes my images
  • Copies my AngularJS web templates to a production directory
  • Copies my JSON files to a production directory
  • Creates a production index.html and a non-production index-nomin.html
  • Cleans up after itself

I’ll paste the code below so anyone is welcome to learn from it (or not).


/*!
 * gulp
 * $ npm install gulp-ruby-sass gulp-autoprefixer gulp-minify-css gulp-jshint gulp-concat gulp-uglify gulp-imagemin gulp-notify gulp-rename gulp-livereload gulp-cache del --save-dev
 */

// Load plugins
var gulp = require('gulp'),
    sass = require('gulp-ruby-sass'),
    autoprefixer = require('gulp-autoprefixer'),
    minifycss = require('gulp-minify-css'),
    jshint = require('gulp-jshint'),
    uglify = require('gulp-uglify'),
    imagemin = require('gulp-imagemin'),
    rename = require('gulp-rename'),
    concat = require('gulp-concat'),
    notify = require('gulp-notify'),
    cache = require('gulp-cache'),
    livereload = require('gulp-livereload'),
    htmlreplace = require('gulp-html-replace'),
    del = require('del');

// Styles
gulp.task('styles', function () {
    return gulp.src('Content/Sass/site-svcc-relative.scss')
        .pipe(sass({style: 'expanded'}))
        .pipe(autoprefixer('last 2 version', 'safari 5', 'ie 8', 'ie 9', 'opera 12.1', 'ios 6', 'android 4'))
        .pipe(gulp.dest('dist/styles'))
        .pipe(rename({suffix: '.min'}))
        .pipe(minifycss())
        .pipe(gulp.dest('dist/styles'))
        .pipe(notify({message: 'Styles task complete'}));
});

// Scripts
gulp.task('scripts', function () {
    return gulp.src(['js/modules/**/*.js', 'app/**/*.js'])
        .pipe(jshint('.jshintrc'))
        .pipe(jshint.reporter('default'))
        .pipe(concat('main.js'))
        .pipe(gulp.dest('dist'))
        .pipe(rename({suffix: '.min'}))
        .pipe(uglify())
        .pipe(gulp.dest('dist'))
        .pipe(notify({message: 'Scripts task complete'}));
});

// Images
gulp.task('images', function () {
    return gulp.src('Content/images/**/*')
        .pipe(cache(imagemin({optimizationLevel: 3, progressive: true, interlaced: true})))
        .pipe(gulp.dest('dist/images'))
        .pipe(notify({message: 'Images task complete'}));
});

// Copy fonts from a module outside of our project (like Bower)
gulp.task('copyfiles', function () {
    gulp.src('app/partials/**/*')
        .pipe(gulp.dest('dist/app/partials'));

    gulp.src('Data/**/*')
        .pipe(gulp.dest('dist/Data'));


});

gulp.task('indexhtml', function () {
    gulp.src('index.html')
        .pipe(htmlreplace({
            'css': 'styles/site-svcc-relative.min.css',
            'js': ['https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0/angular.min.js',
                'main.min.js']
        }))
        .pipe(gulp.dest('dist/'));

    gulp.src('index.html')Doe
        .pipe(htmlreplace({
            'css': 'styles/site-svcc-relative.css',
            'js': ['https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0/angular.js',
                'main.js']
        }))
        .pipe(rename('index-nomin.html'))
        .pipe(gulp.dest('dist/'));
});


// Clean
gulp.task('clean', function (cb) {
    del(['dist/assets/css', 'dist/assets/js', 'dist/assets/img','Content/Sass/.sass-cache'], cb);
});

// Default task
gulp.task('default', ['clean'], function () {
    gulp.start('styles', 'scripts', 'images','copyfiles','indexhtml');
});

// Watch
gulp.task('watch', function () {

    // Watch .scss files
    gulp.watch('src/styles/**/*.scss', ['styles']);

    // Watch .js files
    gulp.watch('src/scripts/**/*.js', ['scripts']);

    // Watch image files
    gulp.watch('src/images/**/*', ['images']);

    // Create LiveReload server
    livereload.listen();

    // Watch any files in dist/, reload on change
    gulp.watch(['dist/**']).on('change', livereload.changed);

});

My What’s New in ExtJS 5 Training Video Live!

My 3rd Pluralsight  Sencha training video is now live.  Basically I take you through the steps of building a straight forward conference session viewer application using most of the new features in ExtJS 5.

The major new features in this upgrade from Sencha that are explained include Model-View-View-Model (MVVM) architecture, 2-way data binding, formulas, tablet support, Routing Translations, and significant new capabilities with models and stores.

This is my third training video on Sencha’s technology.  The first was Sencha Touch, the second ExtJS Fundamentals (which this course builds on) and of course this one on ExtJS 5.  If you have not programmed Sencha’s ExtJS before, it is strongly advised that you watch the fundamentals video first.  That will give you a strong foundation for learning ExtJS 5.

http://pluralsight.com/courses/extjs-5-whats-new

whatsnew

Plugin by Social Author Bio

Follow

Get every new post delivered to your Inbox

Join other followers: