gulp + angular + requirejs 简单学习

Posted 孙建平

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了gulp + angular + requirejs 简单学习相关的知识,希望对你有一定的参考价值。

一、安装gulp(已经安装了node环境)

  npm  install -g gulp

二、在package.json文件中配置依赖插件

{
  "name": "xxxx",
  "version": "0.0.0",
  "private": true,
  "scripts": {
    "start": "node ./bin/www"
  },
  "devDependencies": {
    "del": "^2.2.0",
    "gulp": "^3.9.1",
    "gulp-autoprefixer": "^3.1.0",
    "gulp-cache": "^0.4.5",
    "gulp-compass": "^2.1.0",
    "gulp-concat": "^2.6.0",
    "gulp-imagemin": "^3.0.1",
    "gulp-jshint": "^2.0.1",
    "gulp-livereload": "^3.8.1",
    "gulp-minify-css": "^1.2.4",
    "gulp-notify": "^2.2.0",
    "gulp-rename": "^1.2.2",
    "gulp-requirejs": "^0.1.3",
    "gulp-requirejs-optimize": "^1.0.0",
    "gulp-sass": "^2.3.2",
    "gulp-sourcemaps": "^1.6.0",
    "gulp-uglify": "^1.5.3"
  }
}

注:devDependencies里可以注册你要包含的插件以及相应的版本
三、安装这些插件
npm install (如果想单独安装某个插件 npm install --save-dev gulp-uglify@version)

四、配置gulpfile.js文件

var gulp = require(\'gulp\'),
	  sass = require(\'gulp-sass\'),
    compass = require(\'gulp-compass\'),
    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\'),
    del = require(\'del\'),
    sourcemaps = require(\'gulp-sourcemaps\'),
    requirejsOptimize=require(\'gulp-requirejs-optimize\');
 
gulp.task(\'styles\', function() {
  return gulp.src(\'public/stylesheets/src/*.scss\')
    .pipe(sass({outputStyle: \'expanded\'}).on(\'error\', sass.logError))
    .pipe(sourcemaps.init())
    .pipe(autoprefixer(\'last 2 version\'))
    .pipe(sourcemaps.write())
    .pipe(gulp.dest(\'public/stylesheets/dist\'))
    .pipe(rename({suffix: \'.min\'}))
    .pipe(minifycss())
    .pipe(gulp.dest(\'public/stylesheets/dist\'))
    .pipe(notify({ message: \'Styles task complete\' }));

   //.pipe(browserSync.reload({stream: true}));
});
 

gulp.task(\'scripts\', function() {
  return gulp.src(\'public/javascripts/src/**/*.js\')
    // .pipe(jshint(\'.jshintrc\'))
    // .pipe(jshint.reporter(\'default\'))
    .pipe(requirejsOptimize({
        mainConfigFile: \'public/javascripts/src/config.js\',
        //optimize: \'none\',
        optimize: \'none\',
        exclude: [
            \'angular\',
            \'angularRoute\',
            \'angularMocks\',
            \'text\',
            \'ngFileUpload\',
            \'routeStyles\',
            \'uediter\',
            \'ueditorConfig\',
            \'ueditorAll\',
            \'pagination\'
        ]
    }))
    .pipe(gulp.dest(\'public/javascripts/dist\'))
    .pipe(rename({suffix: \'.min\'}))
    .pipe(uglify())
    .pipe(gulp.dest(\'public/javascripts/dist\'))
    .pipe(notify({ message: \'Scripts task complete\' }));
});


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

gulp.task(\'clean\', function(cb) {
    del([\'public/stylesheets/dist\', \'public/javascripts/dist\', \'public/images/dist\'], cb)
});

gulp.task(\'blog\',function() {
    gulp.start(\'styles\', \'scripts\', \'images\');
});

gulp.task(\'watch\', function() {
  // Watch .scss files
  gulp.watch(\'public/stylesheets/src/**/*.scss\', [\'styles\']);
  // Watch .js files
  gulp.watch(\'public/javascripts/src/**/*.js\', [\'scripts\']);
  // Watch image files
  gulp.watch(\'public/images/src/**/*\', [\'images\']);

  livereload.listen();
  // Watch any files in dist/, reload on change
  gulp.watch([\'public/stylesheets/dist\', \'public/javascripts/dist\', \'public/images/dist\']).on(\'change\', livereload.changed);
});

注:以上为比较直观简单的配置,可以使用gulp-load-plugin插件进一步优化该文件,相关插件功能可以访问官网查看相关的信息

五、angular + requirejs 使用

1、首先看下js文件的目录结构

2、看下main.js文件的内容

require.config({  
    paths: {  
        angular: \'../lib/angular/angular\',  
        angularRoute: \'../lib/angular-route/angular-route\',  
        angularMocks: \'../lib//angular-mocks/angular-mocks\',  
        text: \'../lib/requirejs-text/text\',
        ngFileUpload:\'../lib/ng-file-upload/ng-file-upload\',
        routeStyles:\'../lib/angular-route-styles/route-styles\',
        ueditorConfig:\'../lib/ueditor/ueditor.config\',
        ueditorAll:\'../lib/ueditor/ueditor.all\',
        uediter:\'../lib/angular-ueditor/dist/angular-ueditor\',
        pagination:\'../lib/angularjs-pagination/src/ng-pagination\' 
    },  
    shim: {  
        \'angular\' : {\'exports\' : \'angular\'},  
        \'angularRoute\': [\'angular\'],  
        \'angularMocks\': {  
            deps:[\'angular\'],  
            \'exports\':\'angular.mock\' 
        } ,
        \'ngFileUpload\': [\'angular\'],
        \'routeStyles\':[\'angular\'],
        \'uediter\':[\'ueditorConfig\',\'ueditorAll\',\'angular\'],
        \'pagination\':[\'angular\']
    },  
    priority: [  
        "angular" 
    ]  
});
//http://code.angularjs.org/1.2.1/docs/guide/bootstrap#overview_deferred-bootstrap  
window.name = "NG_DEFER_BOOTSTRAP!";  
require( [  
    \'angular\',  
    \'app\',  
    \'routes\' 
], function(angular, app, routes) {  
    \'use strict\';  
    var $html = angular.element(document.getElementsByTagName(\'html\')[0]);  
 
    angular.element().ready(function() {  
        angular.resumeBootstrap([app[\'name\']]);  
    });  
}); 

3、看下app.js文件内容

define([  
    \'angular\',  
    \'filters\',  
    \'services\',  
    \'directives\',  
    \'controllers\',  
    \'angularRoute\',
    \'ngFileUpload\',
    \'routeStyles\',
    \'pagination\',
    \'uediter\'  
    ], function (angular, filters, services, directives, controllers) {  
        \'use strict\';  
 
        // Declare app level module which depends on filters, and services  
          
        return angular.module(\'myApp\', [  
            \'ngRoute\',
            \'ngFileUpload\',
            \'ng.ueditor\',  
            \'routeStyles\',
            \'ng-pagination\',
            \'myApp.controllers\',  
            \'myApp.filters\',  
            \'myApp.services\',  
            \'myApp.directives\' 
        ], function($httpProvider) {
          // Use x-www-form-urlencoded Content-Type
          $httpProvider.defaults.headers.post[\'Content-Type\'] = \'application/x-www-form-urlencoded;charset=utf-8\';

          /**
           * The workhorse; converts an object to x-www-form-urlencoded serialization.
           * @param {Object} obj
           * @return {String}
           */ 
          var param = function(obj) {
            var query = \'\', name, value, fullSubName, subName, subValue, innerObj, i;
              
            for(name in obj) {
              value = obj[name];
                
              if(value instanceof Array) {
                for(i=0; i<value.length; ++i) {
                  subValue = value[i];
                  fullSubName = name + \'[\' + i + \']\';
                  innerObj = {};
                  innerObj[fullSubName] = subValue;
                  query += param(innerObj) + \'&\';
                }
              }
              else if(value instanceof Object) {
                for(subName in value) {
                  subValue = value[subName];
                  fullSubName = name + \'[\' + subName + \']\';
                  innerObj = {};
                  innerObj[fullSubName] = subValue;
                  query += param(innerObj) + \'&\';
                }
              }
              else if(value !== undefined && value !== null)
                query += encodeURIComponent(name) + \'=\' + encodeURIComponent(value) + \'&\';
            }
              
            return query.length ? query.substr(0, query.length - 1) : query;
          };

          // Override $http service\'s default transformRequest
          $httpProvider.defaults.transformRequest = [function(data) {
            return angular.isObject(data) && String(data) !== \'[object File]\' ? param(data) : data;
          }];
        });  
}); 

4、路由文件routes.js文件下内容

define([\'angular\', \'app\'], function(angular, app) {  
    \'use strict\';  
 
    return app.config([\'$routeProvider\',function($routeProvider) {  
        $routeProvider.when(\'/\', {  
            templateUrl: \'templates/main.html\',//加载的模版  
            controller: \'index\' ,//加载的控制器
            css: \'stylesheets/dist/index.css\'//加载的样式
        });  
        $routeProvider.otherwise({redirectTo: \'/\'});  
    }]);  
 
}); 

5、控制器 (以下以分页服务为例子 )

(1)controllers文件内容

define([\'angular\', \'services\'], function (angular) {  
    \'use strict\';  
 
    /* Controllers */ 
      
    return angular.module(\'myApp.controllers\', [\'myApp.services\'])  
        // Sample controller where service is being used  
        .controller(\'index\', [\'$scope\', \'$injector\', function ($scope, $injector) {  
            require([\'controllers/index\'], function(index) {  
                // injector method takes an array of modules as the first argument  
                // if you want your controller to be able to use components from  
                // any of your other modules, make sure you include it together with \'ng\'  
                // Furthermore we need to pass on the $scope as it\'s unique to this controller  
                $injector.invoke(index, this, {\'$scope\': $scope});  
            });   
        }])  
}); 

(2)index文件下内容

define([], function() {  
    return [\'$scope\', \'$http\',\'$sce\', \'pagination\',function($scope, $http, $sce,pagination) {  
        // You can access the scope of the controller from here  
         $scope.posts = [];
 	    var getPosts= function () {
 
            var postData = {
                page: 1,
                pageSize: 10
            }
 	        var url = \'/main\'
            pagination.list($http,url,postData).success(function (response) {
            	console.log(response);
                // $scope.paginationConf.totalItems = response.total;
                $scope.posts = angular.forEach(angular.fromJson(response.posts), function (post) {
		            post.post = $sce.trustAsHtml(post.post);
		        });
            });
 
        }
 	    getPosts();

 	    $scope.onPageChange = function() {
	      // ajax request to load data
	      console.log($scope.currentPage);
	    };

	    // set pagecount in $scope
	    $scope.pageCount = 100;
        //配置分页基本参数
       
 
        /***************************************************************
        当页码和页面记录数发生变化时监控后台查询
        如果把currentPage和itemsPerPage分开监控的话则会触发两次后台事件。
        ***************************************************************/
        // $scope.$watch(\'paginationConf.currentPage + paginationConf.itemsPerPage\', getPosts);
        // because this has happened asynchroneusly we\'ve missed  
        // Angular\'s initial call to $apply after the controller has been loaded  
        // hence we need to explicityly call it at the end of our Controller constructor  
        $scope.$apply();  
    }];  
}); 

6、服务(没有找到方法实现按需加载 如果有好的的方法实现像控制器那样按需加载 请留言给我 感激不尽,谢谢)

(1)services文件内容

define([\'angular\',\'require\',\'services/pagination\'], function (angular,require) {  
    \'use strict\';  
      
  /* Services */ 
 
  // Demonstrate how to register services  
  // In this case it is a simple value service.  
    angular.module(\'myApp.services\', [])  
        .value(\'version\', \'0.1\')
        .factory(\'pagination\',function () { 
            return require(\'services/pagination\');
        })
}); 

(2)pagination文件下内容

define([], function() { 
        var list = function ($http,url,postData) {
	        return $http.post(url, postData);
	    }
	    return {
	        list: function ($http,url,postData) {
	            return list($http,url,postData);
	        }
	    }
}); 

7、指令和过滤器实现和服务实现事一样的

(1)directives文件下内容

define([\'angular\', \'services\'], function(angular, services) {  
    \'use strict\';  
 
  /* Directives */ 
 
    angular.module(\'myApp.directives\', [\'myApp.services\'])  
        .directive(\'appVersion\', [\'version\', function(version) {  
            return function(scope, elm, attrs) {  
                elm.text(version);  
        };  
    }]);  
}); 

(2)filters文件内容

define([\'angular\', \'services\'], function (angular, services) {  
    \'use strict\';  
 
    /* Filters */ 
    
    angular.module(\'myApp.filters\', [\'myApp.services\'])  
        .filter(\'interpolate\', [\'version\', function(version) {  
            return function(text) {  
                return String(text).replace(/\\%VERSION\\%/mg, version);  
            };  
    }]);  
}); 

(注:如果有更好的实现方式或错误 请留言给我 或 demo地址给我 谢谢)

 

未完待续(angular 深入理解和开发)  

 

 

  

 

 

  

以上是关于gulp + angular + requirejs 简单学习的主要内容,如果未能解决你的问题,请参考以下文章

通过gulp为requireJs引入的模块添加版本号

gulp解决RequireJS

Gulp + Webpack ts loader 移除 requirejs 和定义模块名称注解

基于requireJS和Gulp可快速搭建前端项目的脚手架

用less+gulp+requireJs 搭建项目(了解less)

GruntGulp区别 webpack requirejs区别