【AngularJs学习笔记四】Grunt+Bower+Requirejs+Angular

#0 系列目录#css

#1 前端开发工具介绍#html

  1. Grunt – Js任务管理工具,经过各类插件对项目进行各类操做,好比文件转换、运行测试、打包部署等。至关于java里的ant/maven/gradle,ruby中的rack,scala中的sbt。前端

  2. Bower – Js库依赖管理工具,当你须要jquery时,不须要手动下载,只须要执行 bower install jquery。java

  3. RequireJs – Js库加载管理,及模块化支持,能够按需及并行加载js库,能够把咱们的代码以模块化的方式组织。node

  4. AngularJs – Js前端框架,支持依赖注入,双向绑定等我认为很重要的功能。jquery

这套东西都是比较基础且使用比较普遍的。通常一旦在项目中引入前端框架,或者须要写比较多的Js代码时,咱们都会采用它们,因此颇有必要学习并掌握它们。git

#2 建立项目目录# 下面咱们从零开始,首先在任意位置新建一个目录做为咱们的项目根目录,好比:angularjs

mkdir ~/myproject

而后进入该目录:github

cd ~/myproject

#3 为npm建立package.json# 首先咱们须要为npm提供一个 package.json,告诉它咱们的项目信息,特别是项目中将会使用的插件。咱们不须要手动建立,由于能够直接调用如下命令:npm

npm init

它会问咱们一些问题,咱们能够按需回答,也能够所有使用默认值,反正之后能够改起来也很容易。最后将会产生以下的 package.json 文件:

{
  "name": "myproject",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}

对于像咱们这样的非nodejs项目来讲,里面的大部份内容都没用,能够删掉大部分,只剩下:

{
  "name": "myproject",
  "version": "1.0.0",
}

#4 安装 grunt#

npm install grunt --save-dev

将使用npm下载grunt插件,它们将保存到项目根目录下的 node_modules 目录下。后面的 --save-dev 参数是说,把这个插件信息,同时添加到 package.json 的 devDependencies 中

"devDependencies": {
    "grunt": "^0.4.5"
}

因为grunt仅在开发阶段使用,因此使用 --save-dev 。若是是运行时使用的,则用 --save

#5 安装 grunt-cli# 上面安装的 grunt 并不包含命令行工具,咱们还需安装相应的 grunt-cli ,才能在命令行中调用 grunt 命令:

npm install grunt-cli -g

后面的 -g 是说,把 grunt-cli 安装成全局工具,以便在任意目录下使用。安装后,输入:

grunt --version

我这里显示为:

grunt-cli v0.1.13
grunt v0.4.5

#6 为grunt建立配置文件Gruntfile.js#

  1. 安装grunt-init
npm install grunt-init -g
  1. 下载grunt模板
git clone https://github.com/gruntjs/grunt-init-gruntfile.git ~/.grunt-init/gruntfile
  1. 生成Gruntfile
grunt-init gruntfile

根据须要回答问题,或者使用默认值,将获得如下 Gruntfile.js 文件:

/*global module:false*/
module.exports = function(grunt) {

    // Project configuration.
    grunt.initConfig({
        // Metadata.
        pkg: grunt.file.readJSON('package.json'),
        banner: '/*! <%= pkg.title || pkg.name %> - v<%= pkg.version %> - ' +
                '<%= grunt.template.today("yyyy-mm-dd") %>\n' +
                '<%= pkg.homepage ? "* " + pkg.homepage + "\\n" : "" %>' +
                '* Copyright (c) <%= grunt.template.today("yyyy") %> <%= pkg.author.name %>;' +
                ' Licensed <%= _.pluck(pkg.licenses, "type").join(", ") %> */\n',
        // Task configuration.
        concat: {
            options: {
                banner: '<%= banner %>',
                stripBanners: true
            },
            dist: {
                src: ['lib/<%= pkg.name %>.js'],
                dest: 'dist/<%= pkg.name %>.js'
            }
        },
        uglify: {
            options: {
                banner: '<%= banner %>'
            },
            dist: {
                src: '<%= concat.dist.dest %>',
                dest: 'dist/<%= pkg.name %>.min.js'
            }
        },
        jshint: {
            options: {
                curly: true,
                eqeqeq: true,
                immed: true,
                latedef: true,
                newcap: true,
                noarg: true,
                sub: true,
                undef: true,
                unused: true,
                boss: true,
                eqnull: true,
                browser: true,
                globals: {
                    jQuery: true
                }
            },
            gruntfile: {
                src: 'Gruntfile.js'
            },
            lib_test: {
                src: ['lib/**/*.js', 'test/**/*.js']
            }
        },
        qunit: {
            files: ['test/**/*.html']
        },
        watch: {
            gruntfile: {
                files: '<%= jshint.gruntfile.src %>',
                tasks: ['jshint:gruntfile']
            },
            lib_test: {
                files: '<%= jshint.lib_test.src %>',
                tasks: ['jshint:lib_test', 'qunit']
            }
        }
    });

     // These plugins provide necessary tasks.
     grunt.loadNpmTasks('grunt-contrib-concat');
     grunt.loadNpmTasks('grunt-contrib-uglify');
     grunt.loadNpmTasks('grunt-contrib-qunit');
     grunt.loadNpmTasks('grunt-contrib-jshint');
     grunt.loadNpmTasks('grunt-contrib-watch');

     // Default task.
     grunt.registerTask('default', ['jshint', 'qunit', 'concat', 'uglify']);
};

它里面已经包含了一些经常使用的插件,好比 grunt-contrib-jshint 等,咱们可根据须要删减一些用不上的。它同时还会在 package.json 里添加上这些插件的依赖:

"grunt-contrib-concat": "~0.4.0",
"grunt-contrib-jshint": "~0.10.0",
"grunt-contrib-qunit": "~0.5.2",
"grunt-contrib-uglify": "~0.5.0",
"grunt-contrib-watch": "~0.6.1"

这些插件还未下载,若是须要,能够运行:

npm install

#7 安装bower# bower跟npm在某种意义上类似,它是用来管理经常使用的js库的依赖的,好比jquery, underscore, angularjs等。咱们能够经过npm安装它:

npm install bower -g // 把它装为全局工具

bower也有它本身的配置文件 bower.json ,咱们不须要手动建立。

bower init

将会生成以下的 bower.json :

{
  "name": "myproject",
  "description": "",
  "main": "",
  "authors": [
    "TaoBangren <mingkai.tao@gmail.com>"
  ],
  "license": "MIT",
  "homepage": "",
  "private": true,
  "ignore": [
    "**/.*",
    "node_modules",
    "bower_components",
    "test",
    "tests"
  ]
}

对于咱们的项目来讲,里面的东西基本上都没用。有用的是后面将会出现的dependencies

#8 下载requirejs、jquery、angularjs#

bower install requirejs --save
bower install jquery --save
bower install angularjs --save

将会自动下载jquery到angularjs相应的文件,到项目根目录下的 bower_components 目录。并在 bower.json 中添加:

"dependencies": {
    "requirejs": "~2.1.22",
    "jquery": "~2.2.0",
    "angular": "angularjs#~1.4.9"
  }

#9 安装grunt-bower-task# bower只负责把依赖下载到本地的 bower_components 目录,并不负责把它们拷贝到咱们项目中实际使用的地方,好比 public/js/lib 目录下。为了实现这样的功能,咱们还须要另外一个插件的帮助:

npm install grunt-bower-task --save-dev

而后打开其文档:https://www.npmjs.org/package/grunt-bower-task ,按照上面的提示进行配置。

首先在 Gruntfile 中合适位置添加:

grunt.loadNpmTasks('grunt-bower-task');

而后在 grunt.initConfig({...}) 参数中,添加相应的配置项:

bower: {
    install: {
        options: {
            targetDir: './public/js/lib',
            layout: 'byComponent',
            install: true,
            verbose: false,
            cleanTargetDir: false,
            cleanBowerDir: false,
            bowerOptions: {}
        }
    }
}

这里指定拷贝的目标目录为 public/js/lib ,且文件按照模块分红单个目录(byComponent)。若是想把全部的js放在同一个目录,全部的css文件放在同一个目录,则使用 byType

#10 关于RequireJs使用# 在前面咱们已经使用bower安装了requirejs:

bower install requirejs

RequireJs可用来管理页面中使用的js库之间的依赖关系,能够按需、并行、延迟加载js库。同时它可让咱们以模块化的形式组织js代码。

前面咱们第三方的依赖,经过grunt-bower-task拷贝到了 public/js/lib 目录下。咱们本身写的js,将会放置在 public/js 目录下。咱们须要手动建立一个 config.js 文件,用来配置和初始化requirejs。

若是咱们使用了requirejs,则在HTML中,咱们一般只须要一个 <script src="..."></script> 标签引入requirejs并指定入口文件便可,而不须要写多个 script 标签手动加载其它js文件。

在HTML中合适位置加入:

<script src="/public/js/lib/requirejs/require.js" data-main="/public/js/config.js"></script>

这里首先加载了require.js,并经过 data-main 属性告诉requirejs:当你加载完之后,请加载config.js文件进行初始化。config.js 内容以下:

requirejs.config({
  baseUrl: '/public/js',
  paths: {
    app: 'app',
    jquery: 'lib/jquery/jquery',
    angular: 'lib/angularjs/angular'
  },
  shim: {
  }
});

requirejs(['app'], function(app) {
  app.hello();
});

咱们在 paths 中声明了几个模块,其中的 app 是咱们本身建立的js文件,用于放咱们本身的业务代码,它对应于 /public/js/app.js . jquery 与 angular 对应的文件是咱们使用grunt-bower-task拷贝过来的第三方js库。

shim 中用来处理一些没有遵照requirejs规范的js库,好比 underscore 之类。可在里面对它们进行一些依赖声明、初始化操做等。这里暂时用不上。

最后用 requirejs 来导入咱们本身的模块,可在后面的callback中拿到对应模块的实例,并对它进行一些操做,好比咱们调用了 app.hello() 方法。

为了让这个例子完整,咱们能够定义相应的 app.js :

define([], function() {
  return {
    hello: function() {
      alert("hello, requirejs");
    }
  }
});

为了能让例子跑起来,咱们还须要建立一个 public/index.html ,内容以下:

<html>
<head>
  <script src="/public/js/lib/requirejs/require.js" data-main="/public/js/config.js"></script>
</head>
<body>
  <div>Hello, world!</div>
</body>
</html>

#11 Angularjs例子# 因为angularjs并非按requirejs的模块方式组织代码的,咱们须要在 config.js 中添加:

shim: {
    angular : { exports : 'angular'}
}

Angularjs会在全局域中添加一个名为 angular 的变量。咱们必须在 shim 中显式把它暴露出来,才能经过模块注入的方式使用它,好比:

define(['angular'], function(ng) {
  // we can use argument `ng` instead of gloabl `angular` now
});

在index.html中添加angular代码:

<div ng-controller="MyController">
    <input type="text" ng-model="name" />
    <span>{{name}}</span>
</div>

准备相应的controller,把 app.js 的内容改成:

define(['angular'], function(angular) {
    angular.module('myApp', []).controller('MyController', ['$scope', function ($scope) {
        $scope.name = 'Change the name';
    }]);

    angular.element(document).ready(function() {
        angular.bootstrap(document, ['myApp']);
    });
});

在这段代码里,我定义了一个angularjs本身的模块 myApp ,以及相应的 MyController 。在后面,经过 angular.bootstrap 方法,把该模块与 document 结合在了一块儿

在html中显示angularjs里的一个字段时,咱们使用 {{}} 来占位,好比:

<span>{{name}}</span>

若是咱们同时使用了mustcahe模板,就会有冲突。咱们能够更改angularjs的配置:

angular.module('myApp', []).config(function($interpolateProvider){
        $interpolateProvider.startSymbol('[[').endSymbol(']]');
    }
);

而后咱们就能够写成:

<span>[[name]]</span>
相关文章
相关标签/搜索