AngularJS體驗式編程系列文章,將介紹如何用angularjs構建一個強大的web前端系統。angularjs是由Google團隊開發的一款非常優秀web前端框架。在當前如此多的web框架下,angularjs能脫穎而出,從架構設計上就高人一等,雙向數據綁定,依賴注入,指令,MVC,模板。Angular.js創新地把后台技術融入前端開發,掃去jQuery一度的光芒。用angularjs就像寫后台代碼,更規范,更結構化,更可控。
關於作者
- 張丹(Conan), 程序員Java,R,PHP,Javascript
- weibo:@Conan_Z
- blog: http://blog.fens.me
- email: bsspirit@gmail.com
轉載請注明出處:
http://blog.fens.me/angularjs-yeoman-project/
前言
隨着AngularJS被越來越多的開發人員所了解,AngularJS的應用受到市場的好評。AngularJS是一種新型的以Javascript為基礎的框架,以后台的編程思路影響着web前端的開發。在扎根細節之前,讓我們先了解AngularJS項目構架。自頂向下的開始,就是不一樣的開發。Angular體驗式編程從此開始。
目錄
- AngularJS介紹
- 構建AngularJS項目(Yeoman,angular-seed)
- AngularJS項目結構(Yeoman)
- AngularJS必備基礎
- 啟動項目
1. AngularJS介紹
AngularJS是一個為動態WEB應用設計的結構框架。它能讓你使用HTML作為模板語言,通過擴展HTML的語法,讓你能更清楚、簡潔地構建你的應用組件。它的創新點在於,利用 數據綁定 和 依賴注入,它使你不用再寫大量的代碼了。這些全都是通過瀏覽器端的Javascript實現,這也使得它能夠完美地和任何服務器端技術結合。
AngularJS介紹,摘自:http://angularjs.cn/A00n
2. 構建AngularJS項目(Yeoman,angular-seed)
說到構建項目,目前我了解的有三種:
- 手工項目: 自己建目錄,下載類庫,寫html,js,css,自己實現引用關系
- angular-seed項目: 下載github的angular-seed,在別人的基礎之上開發
- Yeoman項目:通過Yeoman下載一個標准Yeoman項目,已經內置了grunt及各種工具包
1). 手工項目
構建手工項目是我們平時用的最多的一種方式了,適用於小型或demo項目。我不在解釋,參照angularjs一步一步操作就行了。
2). angular-seed項目
一般把這個項目稱為angular的“種子項目”,構建方法是去github下載項目源代碼,基於已有項目結構再做開發。這種項目都融入了前人的經驗,會以一種比較合理的結構,幫我們構建出項目的原型。適合於有一定規模項目開發,同時更適合geek的擴展。
下載演示一下構建過程
~ D:\workspace\javascript>git clone https://github.com/bsspirit/angular-seed.git
Cloning into 'angular-seed'...
remote: Counting objects: 1007, done.
remote: Compressing objects: 100% (497/497), done.
emote: Total 1007 (delta 521), reused 847 (delta 412)
Receiving objects: 100% (1007/1007), 6.30 MiB | 164 KiB/s, done.
Resolving deltas: 100% (521/521), done.
~ D:\workspace\javascript>cd angular-seed
~ D:\workspace\javascript\angular-seed>node scripts\web-server.js
Http Server running at http://localhost:8000/
打開瀏覽器:http://localhost:8000/app/index.html
通過閱讀READMD.md,我們可以了解這個”種子項目”如何使用。
項目目錄及介紹
## Directory Layout
app/ --> all of the files to be used in production
css/ --> css files
app.css --> default stylesheet
img/ --> image files
index.html --> app layout file (the main html template file of the app)
index-async.html --> just like index.html, but loads js files asynchronously
js/ --> javascript files
app.js --> application
controllers.js --> application controllers
directives.js --> application directives
filters.js --> custom angular filters
services.js --> custom angular services
lib/ --> angular and 3rd party javascript libraries
angular/
angular.js --> the latest angular js
angular.min.js --> the latest minified angular js
angular-*.js --> angular add-on modules
version.txt --> version number
partials/ --> angular view partials (partial html templates)
partial1.html
partial2.html
config/karma.conf.js --> config file for running unit tests with Karma
config/karma-e2e.conf.js --> config file for running e2e tests with Karma
scripts/ --> handy shell/js/ruby scripts
e2e-test.sh --> runs end-to-end tests with Karma (*nix)
e2e-test.bat --> runs end-to-end tests with Karma (windows)
test.bat --> autotests unit tests with Karma (windows)
test.sh --> autotests unit tests with Karma (*nix)
web-server.js --> simple development webserver based on node.js
test/ --> test source files and libraries
e2e/ -->
runner.html --> end-to-end test runner (open in your browser to run)
scenarios.js --> end-to-end specs
lib/
angular/ --> angular testing libraries
angular-mocks.js --> mocks that replace certain angular services in tests
angular-scenario.js --> angular's scenario (end-to-end) test runner library
version.txt --> version file
unit/ --> unit level specs/tests
controllersSpec.js --> specs for controllers
directivessSpec.js --> specs for directives
filtersSpec.js --> specs for filters
servicesSpec.js --> specs for services
啟動server
node scripts/web-server.js
單元測試(Unit test):karma + jasmine
端到端測試(End to End test):karma + jasmine + webserver
我們大概了解了“種子工程”的全貌,這樣子心理有數了,就可以開始我們的項目開發了。
對於更高要求的開發者來說,“種子工程”的基礎是不夠。
- 1. karam,jasmine都需要手動安裝
- 2. 沒有代碼自動化(自動增加controller…)
- 3. 沒有實現構建自動化(自動打包,自動壓縮js…)
- ……
一個大型項目構成是方方面面的,接下來我們通過標准化的Yeoman來構建一個企業級應用的項目基礎。
3). Yeoman項目
yeoman是一個標准化的項目開發工作流工具,詳細使用介紹請參考:Yeoman自動構建js項目
通過yeoman也構建項目
~ D:\workspace\javascript>mkdir nodejs-angular
~ D:\workspace\javascript>cd nodejs-angular
~ D:\workspace\javascript>npm install -g generator-angular
# 創建項目
~ D:\workspace\javascript\nodejs-angular>yo angular
[?] Would you like to include Twitter Bootstrap? Yes
[?] Would you like to use the SCSS version of Twitter Bootstrap with the Compass CSS Authoring Framework? No
[?] Which modules would you like to include? angular-resource.js, angular-cookies.js, angular-sanitize.js
create app/styles/bootstrap.css
create app/styles/main.css
create app\index.html
create bower.json
create package.json
create Gruntfile.js
invoke angular:common:D:\toolkit\nodejs\node_modules\generator-angular\app\index.js
create .bowerrc
create .editorconfig
create .gitattributes
create .jshintrc
create app\.buildignore
create app\.htaccess
create app\404.html
create app\favicon.ico
create app\robots.txt
create app\views\main.html
create test\.jshintrc
create test\runner.html
create .gitignore
invoke angular:main:D:\toolkit\nodejs\node_modules\generator-angular\app\index.js
create app\scripts\app.js
invoke angular:controller:D:\toolkit\nodejs\node_modules\generator-angular\app\index.js
create app\scripts\controllers\main.js
create test\spec\controllers\main.js
invoke karma:app
create karma.conf.js
create karma-e2e.conf.js
create .travis.yml
I'm all done. Running bower install & npm install for you to install the required dependencies. If this fails, try runni
ng the command yourself.
輸入yo angular后,會提示我們要不要使用bootstrap;要不要用SCSS生成CSS;要不要include試angular的資源文件。我們選擇完以后,會列出生成的項目文件,這個命令執行要2分鍾左右,會自動下載很多的依賴包。
3. AngularJS項目結構(Yeoman)
更直觀地看到目錄結構
- .tmp:臨時目錄
- app:開發的源代碼的目錄
- dist:生成用於發布的項目
- node_modules:nodejs依賴包
- test:測試文件的目錄
- .bowerrc:bower屬性
- .editooconfig:對開發工具的屬性配置
- .gitattributes:git屬性的配置
- .gitignore:git管理文件的配置
- .jshintr:JSHint配置
- .travis.yml:travis-ci持續集成的配置
- bower.json:bower依賴管理
- Gruntfile.js:grunt開發過程管理
- karma.conf.js:karma自動化測試
- karma-e2e.conf.js:karma端到端自動化測試
- package.json:項目依賴文件
4. AngularJS必備基礎
從上面的目錄結構,我們可以看出AngularJS對哪些東西是需要的。
git, yeoman, bower, grunt, karma …
所以,不要着急上手,先把基礎工具都掌握,請參考系列文章:從零開始nodejs系列文章:成為高手 – 進階篇
基礎知識掌握多少,注定我們能開發多大規模的項目。
5. 啟動項目
我們下載這個工程后,發現沒有任何的文檔。啟動項目應該如何操作呢?
從剛才分析目錄及文件結構,我們知道了這個項目是基於grunt構建的,那么一切的操作都會源於Gruntfile.js。grunt的詳細介紹,請參考:grunt讓Nodejs規范起來
打開Gruntfile.js,直接定位到grunt.registerTask()
grunt.registerTask('server', function (target) {
if (target === 'dist') {
return grunt.task.run(['build', 'open', 'connect:dist:keepalive']);
}
grunt.task.run([
'clean:server',
'concurrent:server',
'autoprefixer',
'connect:livereload',
'open',
'watch'
]);
});
grunt.registerTask('test', [
'clean:server',
'concurrent:test',
'autoprefixer',
'connect:test',
'karma'
]);
grunt.registerTask('build', [
'clean:dist',
'useminPrepare',
'concurrent:dist',
'autoprefixer',
'concat',
'copy:dist',
'cdnify',
'ngmin',
'cssmin',
'uglify',
'rev',
'usemin'
]);
grunt.registerTask('default', [
'jshint',
'test',
'build'
]);
這里定義了4個任務:server,test,build, default。
從名字看就能猜出對應該的功能。
啟動server
~ D:\workspace\javascript\nodejs-angular>grunt server
Running "server" task
Running "clean:server" (clean) task
Cleaning .tmp...OK
Running "concurrent:server" (concurrent) task
Running "coffee:dist" (coffee) task
Running "copy:styles" (copy) task
Running "autoprefixer:dist" (autoprefixer) task
File ".tmp/styles/bootstrap.css" created.
File ".tmp/styles/main.css" created.
Running "connect:livereload" (connect) task
Started connect web server on localhost:9000.
Running "open:server" (open) task
Running "watch" task
Waiting...
瀏覽器被自動打開:http://localhost:9000/#/
執行default任務,生成用於部署的目錄dist
~ D:\workspace\javascript\nodejs-angular>grunt --force
Running "jshint:all" (jshint) task
>> 3 files lint free.
Warning: Task "karma" not found. Used --force, continuing.
Running "clean:dist" (clean) task
Cleaning .tmp...OK
Cleaning dist/.htaccess...OK
Cleaning dist/404.html...OK
Cleaning dist/bower_components...OK
Cleaning dist/favicon.ico...OK
Cleaning dist/index.html...OK
Cleaning dist/robots.txt...OK
Cleaning dist/scripts...OK
Cleaning dist/styles...OK
Cleaning dist/views...OK
Running "useminPrepare:html" (useminPrepare) task
Going through app/index.html to update the config
Looking for build script HTML comment blocks
Found a block:
<!-- build:css(.tmp) styles/main.css -->
<link rel="stylesheet" href="styles/bootstrap.css">
<link rel="stylesheet" href="styles/main.css">
<!-- endbuild -->
Updating config with the following assets:
- .tmp\styles\bootstrap.css
- .tmp\styles\main.css
Found a block:
<!-- build:js scripts/plugins.js -->
<script src="bower_components/bootstrap-sass/js/bootstrap-affix.js"></script>
<script src="bower_components/bootstrap-sass/js/bootstrap-alert.js"></script>
<script src="bower_components/bootstrap-sass/js/bootstrap-dropdown.js"></script>
<script src="bower_components/bootstrap-sass/js/bootstrap-tooltip.js"></script>
<script src="bower_components/bootstrap-sass/js/bootstrap-modal.js"></script>
<script src="bower_components/bootstrap-sass/js/bootstrap-transition.js"></script>
<script src="bower_components/bootstrap-sass/js/bootstrap-button.js"></script>
<script src="bower_components/bootstrap-sass/js/bootstrap-popover.js"></script>
<script src="bower_components/bootstrap-sass/js/bootstrap-typeahead.js"></script>
<script src="bower_components/bootstrap-sass/js/bootstrap-carousel.js"></script>
<script src="bower_components/bootstrap-sass/js/bootstrap-scrollspy.js"></script>
<script src="bower_components/bootstrap-sass/js/bootstrap-collapse.js"></script>
<script src="bower_components/bootstrap-sass/js/bootstrap-tab.js"></script>
<!-- endbuild -->
Updating config with the following assets:
- app\bower_components\bootstrap-sass\js\bootstrap-affix.js
- app\bower_components\bootstrap-sass\js\bootstrap-alert.js
- app\bower_components\bootstrap-sass\js\bootstrap-dropdown.js
- app\bower_components\bootstrap-sass\js\bootstrap-tooltip.js
- app\bower_components\bootstrap-sass\js\bootstrap-modal.js
- app\bower_components\bootstrap-sass\js\bootstrap-transition.js
- app\bower_components\bootstrap-sass\js\bootstrap-button.js
- app\bower_components\bootstrap-sass\js\bootstrap-popover.js
- app\bower_components\bootstrap-sass\js\bootstrap-typeahead.js
- app\bower_components\bootstrap-sass\js\bootstrap-carousel.js
- app\bower_components\bootstrap-sass\js\bootstrap-scrollspy.js
- app\bower_components\bootstrap-sass\js\bootstrap-collapse.js
- app\bower_components\bootstrap-sass\js\bootstrap-tab.js
Found a block:
<!-- build:js scripts/modules.js -->
<script src="bower_components/angular-resource/angular-resource.js"></script>
<script src="bower_components/angular-cookies/angular-cookies.js"></script>
<script src="bower_components/angular-sanitize/angular-sanitize.js"></script>
<!-- endbuild -->
Updating config with the following assets:
- app\bower_components\angular-resource\angular-resource.js
- app\bower_components\angular-cookies\angular-cookies.js
- app\bower_components\angular-sanitize\angular-sanitize.js
Found a block:
<!-- build:js({.tmp,app}) scripts/scripts.js -->
<script src="scripts/app.js"></script>
<script src="scripts/controllers/main.js"></script>
<!-- endbuild -->
Updating config with the following assets:
- {.tmp,app}\scripts\app.js
- {.tmp,app}\scripts\controllers\main.js
Configuration is now:
cssmin:
{ 'dist\\styles\\main.css': 'dist\\styles\\main.css' }
concat:
{ 'dist\\styles\\main.css':
[ '.tmp\\styles\\bootstrap.css',
'.tmp\\styles\\main.css' ],
'dist\\scripts\\plugins.js':
[ 'app\\bower_components\\bootstrap-sass\\js\\bootstrap-affix.js',
'app\\bower_components\\bootstrap-sass\\js\\bootstrap-alert.js',
'app\\bower_components\\bootstrap-sass\\js\\bootstrap-dropdown.js',
'app\\bower_components\\bootstrap-sass\\js\\bootstrap-tooltip.js',
'app\\bower_components\\bootstrap-sass\\js\\bootstrap-modal.js',
'app\\bower_components\\bootstrap-sass\\js\\bootstrap-transition.js',
'app\\bower_components\\bootstrap-sass\\js\\bootstrap-button.js',
'app\\bower_components\\bootstrap-sass\\js\\bootstrap-popover.js',
'app\\bower_components\\bootstrap-sass\\js\\bootstrap-typeahead.js',
'app\\bower_components\\bootstrap-sass\\js\\bootstrap-carousel.js',
'app\\bower_components\\bootstrap-sass\\js\\bootstrap-scrollspy.js',
'app\\bower_components\\bootstrap-sass\\js\\bootstrap-collapse.js',
'app\\bower_components\\bootstrap-sass\\js\\bootstrap-tab.js' ],
'dist\\scripts\\modules.js':
[ 'app\\bower_components\\angular-resource\\angular-resource.js',
'app\\bower_components\\angular-cookies\\angular-cookies.js',
'app\\bower_components\\angular-sanitize\\angular-sanitize.js' ],
'dist\\scripts\\scripts.js':
[ '{.tmp,app}\\scripts\\app.js',
'{.tmp,app}\\scripts\\controllers\\main.js' ] }
uglify:
{ dist: { files: { '<%= yeoman.dist %>/scripts/scripts.js': [ 'dist/scripts/scripts.js' ] } },
'dist\\scripts\\plugins.js': 'dist\\scripts\\plugins.js',
'dist\\scripts\\modules.js': 'dist\\scripts\\modules.js',
'dist\\scripts\\scripts.js': 'dist\\scripts\\scripts.js' }
requirejs:
{}
Running "concurrent:dist" (concurrent) task
Running "copy:styles" (copy) task
Running "imagemin:dist" (imagemin) task
Running "coffee:dist" (coffee) task
Running "htmlmin:dist" (htmlmin) task
Running "svgmin:dist" (svgmin) task
Running "autoprefixer:dist" (autoprefixer) task
File ".tmp/styles/bootstrap.css" created.
File ".tmp/styles/main.css" created.
Running "concat:dist\styles\main.css" (concat) task
File "dist\styles\main.css" created.
Running "concat:dist\scripts\plugins.js" (concat) task
File "dist\scripts\plugins.js" created.
Running "concat:dist\scripts\modules.js" (concat) task
File "dist\scripts\modules.js" created.
Running "concat:dist\scripts\scripts.js" (concat) task
File "dist\scripts\scripts.js" created.
Running "copy:dist" (copy) task
Created 63 directories, copied 367 files
Running "cdnify:dist" (cdnify) task
Going through dist/404.html, dist/index.html to update script refs
Running "ngmin:dist" (ngmin) task
ngminifying dist/scripts/modules.js, dist/scripts/plugins.js, dist/scripts/scripts.js
Running "cssmin:dist\styles\main.css" (cssmin) task
File dist\styles\main.css created.
Running "uglify:dist" (uglify) task
File "dist/scripts/scripts.js" created.
Running "uglify:dist\scripts\plugins.js" (uglify) task
File "dist\scripts\plugins.js" created.
Running "uglify:dist\scripts\modules.js" (uglify) task
File "dist\scripts\modules.js" created.
Running "uglify:dist\scripts\scripts.js" (uglify) task
File "dist\scripts\scripts.js" created.
Running "rev:dist" (rev) task
dist/scripts/modules.js >> 6b865daa.modules.js
dist/scripts/plugins.js >> 76c21dca.plugins.js
dist/scripts/scripts.js >> ff635307.scripts.js
dist/styles/main.css >> a5c01db0.main.css
Running "usemin:html" (usemin) task
Processing as HTML - dist/404.html
Update the HTML to reference our concat/min/revved script files
Update the HTML with the new css filenames
Update the HTML with the new img filenames
Update the HTML with data-main tags
Update the HTML with the data tags
Update the HTML with background imgs, case there is some inline style
Update the HTML with anchors images
Update the HTML with reference in input
Processing as HTML - dist/index.html
Update the HTML to reference our concat/min/revved script files
<script src="scripts/plugins.js" changed to <script src="scripts/76c21dca.plugins.js"
<script src="scripts/modules.js" changed to <script src="scripts/6b865daa.modules.js"
<script src="scripts/scripts.js" changed to <script src="scripts/ff635307.scripts.js"
Update the HTML with the new css filenames
<link rel="stylesheet" href="styles/main.css" changed to <link rel="stylesheet" href="styles/a5c01db0.main.css"
Update the HTML with the new img filenames
Update the HTML with data-main tags
Update the HTML with the data tags
Update the HTML with background imgs, case there is some inline style
Update the HTML with anchors images
Update the HTML with reference in input
Processing as HTML - dist/views/main.html
Update the HTML to reference our concat/min/revved script files
Update the HTML with the new css filenames
Update the HTML with the new img filenames
Update the HTML with data-main tags
Update the HTML with the data tags
Update the HTML with background imgs, case there is some inline style
Update the HTML with anchors images
Update the HTML with reference in input
Running "usemin:css" (usemin) task
Processing as CSS - dist/styles/a5c01db0.main.css
Update the CSS with new img filenames
Done, but with warnings.
Elapsed time
jshint:all 69ms
clean:dist 593ms
useminPrepare:html 49ms
concurrent:dist 2s
autoprefixer:dist 65ms
concat:dist\scripts\scripts.js 26ms
copy:dist 475ms
ngmin 21ms
ngmin:dist 210ms
uglify:dist 37ms
uglify:dist\scripts\plugins.js 252ms
uglify:dist\scripts\modules.js 76ms
usemin:html 313ms
usemin:css 82ms
Total 5s
有了工具的支持,開發效率就是事半功倍了,前提是你要知道如何善用這些工具!




