#0 系列目錄#css
#1 前端開發工具介紹#html
Grunt – Js任務管理工具,經過各類插件對項目進行各類操做,好比文件轉換、運行測試、打包部署等。至關於java裏的ant/maven/gradle,ruby中的rack,scala中的sbt。前端
Bower – Js庫依賴管理工具,當你須要jquery時,不須要手動下載,只須要執行 bower install jquery。java
RequireJs – Js庫加載管理,及模塊化支持,能夠按需及並行加載js庫,能夠把咱們的代碼以模塊化的方式組織。node
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#
npm install grunt-init -g
git clone https://github.com/gruntjs/grunt-init-gruntfile.git ~/.grunt-init/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>