快速搭建Web环境 Angularjs + Express3 + Bootstrap3

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-express3-bootstrap3/

angular-basic

前言

Angularjs越用越顺手,不仅代码量比jQuery少很多,而且实现思路特别清晰,构建大型的Web前端项目,真是最适合不过了。

Bootstrap让界面美观大方,就连像我这种不懂UE的人,也能做出专业级的水准。再结合Nodejs的Express做后端,三剑合并,太无敌了,大有统一前端开发的趋势,前途不可估量!

目录

  1. 从零开始手工创建Express3项目
  2. 新建Angularjs目录及文件
  3. 配置bower
  4. 配置Angularjs项目
  5. 增加Bootstrap
  6. 完整的项目

1. 从零开始手工创建Express3项目

系统环境:

  • Win7 64bit 旗舰版
  • node v0.10.5
  • npm 1.2.19
  • bower 1.1.2

本文截图中使用的开发工具是WebStorm,请参考文章:AngularJS最理想开发工具WebStorm

创建express项目


~ D:\workspace\javascript>express -e angular-basic
~ D:\workspace\javascript>cd angular-basic && npm install

生成的express项目目录

express

修改app.js的配置

  • 修改ejs: 文件扩展名ejs为html
  • 设置angular: 启动路径为”/”
  • 设置angular: 启动文件为app/index.html

~ vi app.js

var express = require('express')
    , path = require('path')
    , ejs = require('ejs')
    , app = express()
    , server = require('http').createServer(app);

app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.engine('.html', ejs.__express);
app.set('view engine', 'html'); //替换文件扩展名ejs为html
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
app.use(express.static(path.join(__dirname, 'app')));

if (app.get('env') === 'development') {
    app.use(express.errorHandler());
}

// angular启动页
app.get('/', function (req, res) {
    res.sendfile('app/index.html');
});

server.listen(app.get('port'), function () {
    console.log('Express server listening on port ' + app.get('port'));
});

如何单独创建Express3的项目,请参考文章:Nodejs开发框架Express3.0开发手记–从零开始

2. 新建Angularjs目录及文件

创建Angularjs需要的目录及文件


D:\workspace\javascript\angular-basic>mkdir app
D:\workspace\javascript\angular-basic>mkdir app\scripts
D:\workspace\javascript\angular-basic>mkdir app\scripts\angular
D:\workspace\javascript\angular-basic>mkdir app\styles
D:\workspace\javascript\angular-basic>mkdir app\views
D:\workspace\javascript\angular-basic>mkdir app\views\component
D:\workspace\javascript\angular-basic>mkdir app\views\tpl

D:\workspace\javascript\angular-basic>touch app\index.html
D:\workspace\javascript\angular-basic>touch app\scripts\angular\app.js
D:\workspace\javascript\angular-basic>touch app\scripts\angular\controllers.js
D:\workspace\javascript\angular-basic>touch app\styles\main.css
D:\workspace\javascript\angular-basic>touch app\views\tpl\welcome.html

D:\workspace\javascript\angular-basic>echo "aaaa" > app\index.html

创建的Angularjs目录及文件

angular

目录解释:

  • app目录: Angular项目的根目录
  • scripts目录: 存放Javascript脚本目录
  • scripts\angular目录: 存放Angular Javascript脚本目录
  • styles目录: 存放css的目录
  • views目录: 存放html的目录
  • views\component目录: 存放html的自定义组件目录
  • views\tpl目录: 存放html的目录

文件解释:

  • app\index.html: Angular项目的入口文件
  • styles\main.css: Angular项目的css文件
  • scripts\angular\app.js: Angular项目全局配置文件
  • scripts\angular\controllers.js: Angular项目全局控制器文件/li>
  • views\tpl\welcome.html: 欢迎页

删除不需要的文件目录


D:\workspace\javascript\angular-basic>rm -rf public
D:\workspace\javascript\angular-basic>rm -rf routes

启动node服务器,检查入口页的配置


D:\workspace\javascript\angular-basic>node app.js
Express server listening on port 3000
GET / 200 11ms - 9b

indexpage

界面显示”aaaa”,说明node启动express,已经指向到app\index.html的页面。

3. 配置bower

接下来,我要通过bower来安装Angularjs和Bootstrap,以及其他依赖的前端库。关于bower的详细使用,请参考文章:bower解决js的依赖管理

新建文件:

    • .bowerrc: bower的环境设置,用于指定bower的依赖库的存放位置
    • bower.json: bower的依赖管理

新建文件: .bowerrc


~ vi .bowerrc

{
    "directory": "app/bower_components"
}

新建文件: bower.json


~ vi bower.json

{
    "name": "angular-basic",
    "version": "0.0.1",
    "dependencies": {
        "angular": "~1.2.12-build.2226",
        "angular-route": "~1.2.12-build.2226"
    },
    "devDependencies": {
    }
}

运行bower,下载Angular依赖库


D:\workspace\javascript\angular-basic>bower install
bower angular-route#~1.2.12-build.2226           cached git://github.com/angular/bower-angular-route.git#1.2.13-build.2242
bower angular-route#~1.2.12-build.2226         validate 1.2.13-build.2242 against git://github.com/angular/bower-angular-route.git#~1.2.12-build.2226
bower angular#~1.2.12-build.2226                 cached git://github.com/angular/bower-angular.git#1.2.13-build.2242
bower angular#~1.2.12-build.2226               validate 1.2.13-build.2242 against git://github.com/angular/bower-angular.git#~1.2.12-build.2226
bower angular#1.2.13-build.2242+sha.e645f7c      cached git://github.com/angular/bower-angular.git#1.2.13-build.2242
bower angular#1.2.13-build.2242+sha.e645f7c    validate 1.2.13-build.2242 against git://github.com/angular/bower-angular.git#1.2.13-build.2242+sha.e645f7c
bower angular-route#~1.2.12-build.2226          install angular-route#1.2.13-build.2242
bower angular#~1.2.12-build.2226                install angular#1.2.13-build.2242

angular-route#1.2.13-build.2242 app\bower_components\angular-route
└── angular#1.2.13-build.2242

angular#1.2.13-build.2242 app\bower_components\angular

下载最新版本的angular和angular-route,类库存放在app/bower_components目录下面。

bower-angular

4. 配置Angularjs项目

  • 修改index.html: 在入口文件,页面模板
  • 修改welcome.html: 欢迎页
  • 修改app.js: 全局配置
  • 修改controller.js: 控制器

修改index.html


<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="utf-8">
<title>Angular-basic</title>
<meta name="description" content="Copyright http://blog.fens.me">
<link rel="stylesheet" href="styles/main.css">
</head>
<body ng-app="app">

<ul>
<li><a href="http://blog.fens.me/angularjs-express3-bootstrap3/">快速搭建Web环境 Angularjs + Express3 + Bootstrap3</a></li>
<li>http://blog.fens.me/angularjs-express3-bootstrap3</li>
</ul>

<div ng-view></div>

<script src="bower_components/angular/angular.min.js"></script>
<script src="bower_components/angular-route/angular-route.min.js"></script>
<script src="scripts/angular/app.js"></script>
<script src="scripts/angular/controllers.js"></script>

</body>
</html>

修改welcome.html


Welcome {{ username }}

修改app.js


'use strict';

var app = angular.module('app', ['ngRoute']);

app.config(['$routeProvider', '$locationProvider', function ($routeProvider, $locationProvider) {
    $routeProvider
        .when('/', {templateUrl: '/views/tpl/welcome.html', controller: 'WelcomeCtrl'})
        .otherwise({redirectTo: '/'});
    $locationProvider.html5Mode(true);
}]);

修改controller.js


'use strict';

function WelcomeCtrl($scope){
    $scope.username = 'Conan_Z';
}

重新启动node,查看Angular项目。


D:\workspace\javascript\angular-basic>node app.js
Express server listening on port 3000
GET / 304 8ms
GET /styles/main.css 304 3ms
GET /scripts/angular/app.js 304 6ms
GET /scripts/angular/controllers.js 304 11ms
GET /bower_components/angular-route/angular-route.min.js 200 18ms - 3.82kb
GET /bower_components/angular/angular.min.js 200 19ms - 98.03kb
GET /views/tpl/welcome.html 304 9ms
GET /bower_components/angular-route/angular-route.min.js.map 200 21ms - 9.61kb
GET /bower_components/angular/angular.min.js.map 200 26ms - 264.16kb

界面显示:

angular-start

index.html中配置的链接已经显示,同时welcome.html页面中配置的Welcome Conan_Z,也显示出来了。关于路由和模板配置,请参考文章:AngularJS路由和模板

5. 增加Bootstrap

接下来,增加Bootstrap-v3,让界面好看起来。我们还是有bower来管理Bootstrap的依赖。

通过命令行,增加类库,并写入的bower.json文件


D:\workspace\javascript\angular-basic>bower install bootstrap --save
D:\workspace\javascript\angular-basic>bower install angular-bootstrap --save
  • 修改index.html: 增加css, js的引用
  • 修改welcome.html: 增加bootstrap的效果

修改index.html


<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="utf-8">
<title>Angular-basic</title>
<meta name="description" content="Copyright http://blog.fens.me">
<link rel="stylesheet" href="bower_components/bootstrap/dist/css/bootstrap.min.css">
<link rel="stylesheet" href="styles/main.css">
</head>
<body ng-app="app">

<div class="container">
<h2 class="text-primary">
<a href="http://blog.fens.me/angularjs-express3-bootstarp3/">快速搭建Web环境 Angularjs + Express3 + Bootstarp3</a>
</h2>
<p>http://blog.fens.me/angularjs-express3-bootstarp3</p>

<div class="row">
<div class=".col-lg-12">
<div ng-view></div>
</div>
</div>
</div>

<script src="bower_components/angular/angular.min.js"></script>
<script src="bower_components/bootstrap/dist/js/bootstrap.min.js"></script>
<script src="bower_components/angular-route/angular-route.min.js"></script>
<script src="bower_components/angular-bootstrap/ui-bootstrap-tpls.min.js"></script>
<script src="scripts/angular/app.js"></script>
<script src="scripts/angular/controllers.js"></script>

</body>
</html>

修改welcome.html


<hr/>
<form class="form-inline" role="form">
<div class="form-group">
<label>Welcome</label>
<input type="text" class="form-control" ng-model="username" placeholder="Enter email">
</div>
</form>
<p> {{ username }}</p>

angular-bootstrap

这样就用手动的方式的搭建了:Angularjs + Express3 + Bootstrap3的组合。

6. 完整的项目

项目代码已上传的github,项目地址: https://github.com/bsspirit/angular-basic

项目下载及安装


git clone https://github.com/bsspirit/angular-basic
npm install
bower install

项目运行


node app.js

当然,对于大型的Angular项目,我们可以选择用Yeoman的种子构建,请参考文章:AngularJS从构建项目开始

但有时Yeoman的项目,更新不够及时,比如bootstrap已到v3了,种子项目还是bootstrap的v2,而且v3不兼容v2。这时也许手动构建自己的项目,才是更好的选择。

转载请注明出处:
http://blog.fens.me/angularjs-express3-bootstrap3/

打赏作者

This entry was posted in Javascript语言实践, 架构设计

  • 曾浩

    哇塞!太崇拜你了!正需要这样的教程呢!

    • 过奖:-)

      • 曾浩

        期待博主写angularjs+node.js+mongodb的教学。

        • 等过段时间吧,最近在忙别的事情。

        • xiaoqian

          我也很期待

  • 狂奔的蜗牛

    太棒了,准备好好研究

  • 酷酷虫

    楼主用的是webstrom7么,我用的webstrom7 不支持angularjs 插件,是否遇到过,如何处理的

  • mikan

    最近正好学习了bootstrap,过来学学angularjs,问下博主开发node用的什么ide啊

  • Dickey Vivi

    我比较好奇的是如果要满足开发阶段和生产环境对js和css的不同引用处理,比如线上需要使用grunt或者gulp构建后的js和css,怎么样使开发阶段和生产环境引用的资源文件不一样?用2份略有差异的index.html吗?

    • 你可以参考这篇文章的:
      http://blog.fens.me/angularjs-webstorm-ide/

      • Dickey Vivi

        唔,你发的链接似乎是介绍webstorm的使用,我一直在使用中,关于上面的问题我后来找到了grunt-useref插件可以帮忙来解决这个问题,gulp也有类似的插件

        • webstorm使用只是一方面,和yeoman构建的项目,已都都配置好了grunt,也区分了开发环境和生产环境。

    • anota

      grunt 可以配置dev参数用来调试开发阶段代码,然后再自定义一份proudce的任务 shell执行的时候 分别跑任务就好。

  • Maopy

    Express V4 各种404~ 请问怎么解决呢~

    • Express V4 昨天才正式发布,我还没有看呢。

    • 估计是静态路径的设置问题,public那里改成app?

  • 小问题:页面中没有引用jquery会报错

  • acegank

    所以必须要引用jquery啊,楼主干嘛不写进去,我等新人不容易啊

    • mayusa

      我感觉新人不适合这篇文章。建议新同学先学习下bower, bootstrap的基本使用,官网都写的很详细。

  • Pingback: Angular结合Bootstrap3的导航菜单 | 粉丝日志()

  • anamary

    博主,问你一下,在shell执行bower时候,出现Cannot be run with sudo,因为是阿里云,所以只有root全选,怎么解决这个不能使用sudo的问题?

    • 增加–allow-root参数
      比如:bower install –allow-root

  • anamary

    这个用express+angular+bootstrap+mongodb,如何应用mongodb,是放到app文件夹还是继续用express的model。

    • 通过express连接mongodb,与express项目一样。

  • Nicholas

    您好,我想问一下那个控制器部分,

    $routeProvider .when(‘/’, {templateUrl: ‘/views/tpl/welcome.html’, controller: ‘WelcomeCtrl’})

    中,index.html与view文件夹是在同一目录下,为什么templateUrl 不写成“views/tpl/welcome.html”?

    • 可能是我个人的习惯,/views/tpl/welcome.html 这种写法是以站点域名为根的路径,查找文件, ./views/tpl/welcome.html 是以当前文件目录为相对路径,查找文件。

      • Nicholas

        谢谢,那在这个项目当中,站点域名的根目录是这个angular-basic文件夹吗?

        • 这个目录你自己可以配置,对Angularjs项目,我会指定在app目录。

          • Nicholas

            哦,我懂了,那就是说这条语句app.use(express.static(path.join(__dirname, ‘app’)));
            设定了根目录吧

  • inix

    博主你好,我最近打算搭建一个静态小网站,不复杂,用bootstrap做前端;我自己就是懂一点html,css,js,有些问题请教一下:
    1.刚开始的想法是找个bootstrap现成的模板,然后随便删除和编辑一些html代码就可以了。
    但是我觉得html标签特别繁琐,很容易出错和不易维护,所以想到用别的容易理解的语言来生成这些html代码。

    2.后来发现了jade。我觉得这个挺不错。

    3.后来又看到很多javascript的项目,比如说nodejs,express,angular js等;对javascript不熟悉,不知道这些js框架时候能够满足我的要求?我还需要学习这些框架吗?因此我的疑问就是:是直接用jade,还是用这些框架?

    谢谢

    • 1. 静态网站,只需要html, js, css就行了,不用考虑node。
      2. jade是基于node渲染的,不能直接用于前端,或者用前端的其他渲染器。
      3. angular.js作为前端框架,可以直接用于和html, js, css的集成,不需要后台node支持。
      4. 如果想好好学习知识,你列出的所有技术都需要花时间看;如果仅仅是建个网站,那么网上随便复制点代码就行了。

      • inix

        还有就是,这个网站是打算面向业务的,刚开始内容可能不是很多,但是以后页面添加的内容会越来越多,我害怕到时候如果更改html代码会变得不可维护;希望能够管理生成的css,html等,我也看到有less,spass等等这些;所以博主推荐使用那些提到的工具吗?

        • 那就是动态网站了,需要前后台一起配合。比如就node, php, python, java等。

          用可以基于node去开发,参考我的nodejs系列文章,如果你能都学明白,开发个网站是很容易的。
          http://blog.fens.me/series-nodejs/

          • inix

            好的,谢谢,我在看看博主其他nodejs的文章。

  • 请教:
    在项目中执行 bower install

    报:

    bower ENOGIT git isnot installed or not in the path

    • 先安装bower
      参考:http://blog.fens.me/nodejs-bower-intro/

      • 感谢您的回答:

        bower 已经安装好了,

        在执行 bower install

        的时候 还是报:bower ENOGIT git isnot installed or not in the path

        • 执行 bower install

          • 在项目里面,也没有bower_components 这个文件夹,这个那里来的啊

          • bower执行需要git的环境,还要装git,最好把github的账号也配置好。

          • git github 项目我是通过 https://github.com/bsspirit/angular-basic 下载的,–还是不行,系统win7 32

          • 从图中看,要把git命令配置到环境变量中

          • 终于搞好了,感谢您的帮助,具体问题我也不知道,我把nodejs,git全部删了,从nodejs开始一个个安装,配置,–最好就好了,再次感谢您的帮助!!

          • 解决就好 🙂

          • 把git的bin目录和cmd目录添加到PATH即可

  • Guest

    我按最新的ExpressV4配好了,最后还是报一一个错,不是很明白,我是才学习的

  • Guest

    我是按照Express v4配的,最后报了这个错,麻烦看下是什么问题?

  • cqak47

    我是按照express v4配的,报了下面这个错,看下是怎么原因。

    Error: [$injector:modulerr] http://errors.angularjs.org/1.2.26/$injector/modulerr?p0=app&p1=%5B%24injector%3Anomod%5D%20http%3A%2F%2Ferrors.angularjs.org%2F1.2.26%2F%24injector%2Fnomod%3Fp0%3DappC%2F%3C%40http%3A%2F%2Flocalhost%2Fbower_components%2Fangular%2Fangular.min.js%3A6%3A450Zc%2Fb.module%3C%2F%3C%2Fb%5Be%5D%3C%40http%3A%2F%2Flocalhost%2Fbower_components%2Fangular%2Fangular.min.js%3A20%3A1Zc%2Fb.module%3C%2F%3C%40http%3A%2F%2Flocalhost%2Fbower_components%2Fangular%2Fangular.min.js%3A20%3A1e%2F%3C%40http%3A%2F%2Flocalhost%2Fbower_components%2Fangular%2Fangular.min.js%3A33%3A267r%40http%3A%2F%2Flocalhost%2Fbower_components%2Fangular%2Fangular.min.js%3A7%3A288e%40http%3A%2F%2Flocalhost%2Fbower_components%2Fangular%2Fangular.min.js%3A33%3A207gc%40http%3A%2F%2Flocalhost%2Fbower_components%2Fangular%2Fangular.min.js%3A36%3A309fc%2Fc%40http%3A%2F%2Flocalhost%2Fbower_components%2Fangular%2Fangular.min.js%3A18%3A170fc%40http%3A%2F%2Flocalhost%2Fbower_components%2Fangular%2Fangular.min.js%3A18%3A387Xc%40http%3A%2F%2Flocalhost%2Fbower_components%2Fangular%2Fangular.min.js%3A17%3A415%40http%3A%2F%2Flocalhost%2Fbower_components%2Fangular%2Fangular.min.js%3A215%3A30n.Callbacks%2Fj%40http%3A%2F%2Flocalhost%2Fbower_components%2Fjquery%2Fdist%2Fjquery.min.js%3A2%3A26855n.Callbacks%2Fk.fireWith%40http%3A%2F%2Flocalhost%2Fbower_components%2Fjquery%2Fdist%2Fjquery.min.js%3A2%3A27673.ready%40http%3A%2F%2Flocalhost%2Fbower_components%2Fjquery%2Fdist%2Fjquery.min.js%3A2%3A29465I%40http%3A%2F%2Flocalhost%2Fbower_components%2Fjquery%2Fdist%2Fjquery.min.js%3A2%3A29656

    …gify(arguments[c]):arguments[c]);return Error(a)}}function Pa(b){if(null==b||Ga(…

  • jack

    有个问题

    这个还需要引用吗,如果要引用就要引用jq,我发现 ui-bootstrap-tpls-0.11.0.min.js 其实已有类似功能
    这个引用来做什么用呢。

    • 我没有注意 ui-bootstrap-tpls-0.11.0.min.js 文件的内容,如果代码重复能更少的引用最好。

  • lyh

    不需要引入jquery吗?

  • zuidaima.com

    bootstrap demo实例教程源代码下载:http://www.zuidaima.com/share/kbootstrap-p1-s1.htm

  • ethan

    angular已经到1.3.8了 .when(‘/’, {templateUrl: ‘/views/tpl/welcome.html’, controller: ‘WelcomeCtrl’}) 这一段在1.3.8下无效 不知道如何解决 换到1.2.28就是好的

    • 我目前使用的版本 1.3.7-build.3691+sha.7fd2dc1,这样写是正常的。

      • zkaip

        app.controller(‘WelcomeCtrl’, function($scope){
        $scope.username = ‘FanFou’;
        });

        代码这样写就OK了,必须模块化加载,1.38版本以上就默认关闭$scope全局变量了

  • jacens

    我修改了welcome.html,app.js,也修改了controller.js,却没有看到效果呢?

    • 要看到什么效果?

      • 现在可以看到效果了。如果我想调用之前用Express创建好的项目的方法,可以实现动态地与MongoDB交互,该怎么配置呢?例如我写了一个查询的用户的方法
        User.get = function get(username, callback) {
        mongodb.open(function (err, db) {
        if (err) {
        return callback(err);
        }
        // 读取 users 集合
        db.collection(‘users’, function (err, collection) {
        if (err) {
        mongodb.close();
        return callback(err);
        }
        // 查找 name 属性为 username 的文档
        collection.findOne({ name: username }, function (err, doc) {
        mongodb.close();
        if (doc) {
        // 封装文档为 User 对象
        var user = new User(doc);
        callback(err, user);
        } else {
        callback(err, null);
        }
        });
        });
        });
        };
        我怎么能在控制器中调用这个方法呢?

  • Henry

    index.html里应该是ui-view而非ng-view吧?

    • Henry

      没错误,你在用ngRouter而非ui-router,不好意思

  • pi_dear

    博主好 是否能解释一下 npm start 和 node app.js 区别

    • 1. npm start 是通过命令启动调用node app.js
      2. node app.js是直接启动。

      没有明显的区别。

  • Henry Yong

    第二步中,运行node app.js时报错

    YangHenrydeMacBook-Pro:angular-basic Yong$ node app.js
    /Users/Yong/Desktop/code/apps/angular-basic/node_modules/express/lib/express.js:99
    throw new Error(‘Most middleware (like ‘ + name + ‘) is no longer bundled with Express and must be installed separately. Please see https://github.com/senchalabs/connect#middleware.’);
    ^

    Error: Most middleware (like favicon) is no longer bundled with Express and must be installed separately. Please see https://github.com/senchalabs/connect#middleware.
    at Function.Object.defineProperty.get (/Users/Yong/Desktop/code/apps/angular-basic/node_modules/express/lib/express.js:99:13)
    at Object. (/Users/Yong/Desktop/code/apps/angular-basic/app.js:11:16)
    at Module._compile (module.js:398:26)
    at Object.Module._extensions..js (module.js:405:10)
    at Module.load (module.js:344:32)
    at Function.Module._load (module.js:301:12)
    at Function.Module.runMain (module.js:430:10)
    at startup (node.js:141:18)
    at node.js:980:3

    • 如果是express3的版本是可以的,之后的版本由于express变化比较大,所以整个配置就都变了。