The previous article"Node.js First Experience" is also well written, interested friends can check it out.
The installation of Node and NPM is convenient enough. Without going into details... there are a few basic points to mention:
1. “-g” in the installation command means global
2. The version of express is not viewed by the usual “-v”, but by “-V”
3. The command to install the express project is as follows
express -e nodejs-product -e, --ejs add ejs engine support -J, --jshtml add jshtml engine support (defaults to jade)
PS: Template engines don’t need to be taken care of for the time being, but I used ejs when I first learned to build Node express, so I just kept using it
Node’s little friend supervisor
It will automatically restart after each code modification. Lazy programmers rely on this kind of trouble-saving tool to survive:)
Installation: npm install -g supervisor
Execution: supervisor app.js
Another little gay friend forever
The node service will be shut down as soon as the virtual machine is shut down. However, forever can keep the node service from stopping. The introduction is as follows. I will not go into details about the installation and execution. I am too lazy:
Forever is a simple imperative nodejs daemon that can start, stop, and restart App applications. Forever is completely based on command line operation. Under the forever process, a child process of node is created, and the running status of the node child process is monitored through the monitor. Once the file is updated or the process hangs, forever will automatically restart the node server to ensure the normal operation of the application.
express project directory
The picture above is an express project structure. Let’s briefly review it:
app.js: Project entrance. Express prefers to call it app.js anyway. You can change it to index.js or main.js. Equivalent to index.php, index.html
in the php project
node_modules: Stores project dependency libraries
package.json: Project dependency configuration and developer information (this is too much to say, it’s better to read the documentation, so I won’t mislead others. I’ll take a short paragraph to talk about the Node module in the next issue)
public: static files such as css, js, img (PS: I am actually used to calling them static)
routes: Routing file (an important target for learning. Whether your business is good or not, routing is the key)
Views: Page file (Ejs or jade template, the default is jade, I use Ejs here, the most important thing is to practice at the beginning, so you can try it)
When I opened the View file, I found that index.ejs was not something I was used to, so I made small changes to app.js:
"app.set('view engine', 'ejs');" becomes "app.engine('.html', ejs.__express);app.set('view engine', 'html'); ”
The ejs variable appearing in the previous line requires the require ejs module, add the code "var ejs = require('ejs');"
The final app.js is as follows:
Code explanation:
Because we are aiming at entry-level entry, we will continue to go through the use of express and the method of Node:
require() is used to load and use other modules in the current module; this method is the basis of the module, and the concept of path is sufficient for use. PS: JS files can remove the ".js" suffix
Exports represents the export object of the module, which is used to export the attributes and public methods of the module. There are index.js and users.js under the project routes folder (routing is detailed), both of which use the exports object to export objects, such as routes.index on line 33 and user.list on line 34;
PS: The code of a module will only be executed when the module is used for the first time, and will not be initialized multiple times due to require multiple times.
Express() means creating an express application. You can actually create an application with just a few lines of code, as follows:
var express = require('express'); var app = express(); app.get('/', function(req, res){ res.send('hello world'); console.log('hello world'); }); app.listen('8808');
app.listen() 就是在给定的主机和端口上监听请求,这个和node中http模块的http.createServer(function(){...}).listen()效果一致;
app.set(name, value)和app.get(name)就是你想的那样,set()为设置 name 的值设为 value,get()为获取设置项 name 的值。如俺app.js的图片16行中的一句“app.set('port', process.env.PORT || 3000)”就是设置项目的port,在下面使用http.createServer时就可以使用app.get('port')来获取,只是俺偷懒没用来着;
了解app.engine()方法之前先看看express应用的安装命令:“express -e nodejs-product”,其中的 -e 和 -J 我们一开始已经提到,表示ejs和jade模板。
如果想把模板后缀改成“.html”时就会用到app.engine方法,来重新设置模板文件的扩展名,比如想用ejs模板引擎来处理“.html”后缀的文件:app.engine('.html', require('ejs').__express);
app.engine(ext, callback) 注册模板引擎的 callback 用来处理ext扩展名的文件。
PS:__express不用去care,其实就是ejs模块的一个公共属性,表示要渲染的文件扩展名。
app.use([path], function) 使用中间件 function,可选参数path默认为"/"。使用 app.use() “定义的”中间件的顺序非常重要,它们将会顺序执行,use的先后顺序决定了中间件的优先级(经常有搞错顺序的时候);
最后介绍个很有用的express API:
app.render(view, [options], callback) 渲染 view, callback 用来处理返回的渲染后的字符串。
路由实战:
路径代码应该是项目中最本机的一部分了。express中创建一个或者一套新的handle非常简单,先看看express现有的,一会儿我们创建俩个实际的规则。
变量 routes 和 user 都是刚才require的模块,他们各自exports了index方法和list方法;其中Response.render()表示渲染view,同时传进对应的数据,Response.send()为发送一个响应;在设置路由时index和list方法作为回调函数最终执行。
流程大概了解啦,俺们也就实际搞一把,最easy的一种方式,简单俩步:
第一种方式就是在当前的routes/index.js或者routes/test.js中加几行代码如下
exports.test = function(req, res){ res.send('test welcome.'); };
在app.js文件设置路由那块加上app.get('/test', routes.test);
第二种方式就是多了两步,先新建一个模块如test.js文件,输出然后exports对应的方法;在app.js中require这个模块,再加一行设置路由即完成了。
快速炫起来,集成Bootstrap:
JS工程师使用Nodejs上手还是以快速搭建网站为主,所以才会介绍Express,那么为了让网站更快的体面起来,集成使用Bootstrap就是上佳选择,非常喜欢其响应式布局和整体系的脚手架。
PS:因为Bootstrap的JS插件都依赖jQeury,所以jQuery也一并引入了。
前文已经说到了,静态文件都放在public文件夹中,切文件夹内已经帮我们把类目都分好了,images、 javascripts、 stylesheets。
分别引入bootstrap.min.css文件至stylesheets目录下;jquery-1.x.x.min.js和bootstrap.min.js放到javascripts文件夹下。
然后俺们修改view/index.html把文件引入使用即可,下面放出俺在bootstrap demo的基础改的index.html,大家随意拿去使用和修改。
<!DOCTYPE html> <html lang="zh-cn"> <head> <title><%= title %></title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <link href="/stylesheets/bootstrap.min.css" rel="stylesheet"> <!--<link href="/stylesheets/base.css" rel="stylesheet">--> <!--<link href="/stylesheets/common.css" rel="stylesheet">--> <!--<link href="/stylesheets/page.css" rel="stylesheet">--> <!-- 建议在项目中把CSS分好level,好维护和管理 --> <style> html, body { overflow-x: hidden;} body { padding-top: 70px;background:#f1f1f1; } footer { padding:20px 0 10px;text-align:center;font-weight:bold;border-top:1px solid #ddd;margin-top:30px;} .header-navbar-style { filter:alpha(opacity=90); -moz-opacity:0.9; -khtml-opacity: 0.9; opacity: 0.9; background: linear-gradient(45deg, rgb(60, 8, 34) 0%, rgb(49, 79, 117) 100%); border:1px solid #aaa; font-size:16px; } .beige {background:beige;} .bisque {background:bisque;} .darkseagreen{ background:darkseagreen;} </style> </head> <body> <div class="navbar navbar-fixed-top header-navbar-style navbar-inverse" role="navigation"> <div class="container"> <div class="navbar-header"> <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="/">Product</a> </div> <div class="collapse navbar-collapse"> <ul class="nav navbar-nav"> <li class="active"><a href="/">Home</a></li> <li class=""><a href="/contactus">Contact</a></li> <li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <b class="caret"></b></a> <ul class="dropdown-menu beige"> <li><a href="#">Action</a></li> <li><a href="#">Another action</a></li> <li><a href="#">Something else here</a></li> <li class="divider"></li> <li><a href="#">Separated link</a></li> <li class="divider"></li> <li><a href="#">One more separated link</a></li> </ul> </li> <li class=""><a href="/faq">FAQ</a></li> </ul> </div><!-- /.nav-collapse --> </div><!-- /.container --> </div><!-- /.navbar --> <!-- 以上位置建议创建个header.html维护起来 --> <style> @media screen and (max-width: 767px) { .row-offcanvas { position: relative; -webkit-transition: all 0.25s ease-out; -moz-transition: all 0.25s ease-out; transition: all 0.25s ease-out; } .row-offcanvas-right .sidebar-offcanvas { right: -50%; /* 6 columns */ } .row-offcanvas-left .sidebar-offcanvas { left: -50%; /* 6 columns */ } .row-offcanvas-right.active { right: 50%; /* 6 columns */ } .row-offcanvas-left.active { left: 50%; /* 6 columns */ } .sidebar-offcanvas { position: absolute; top: 0; width: 50%; /* 6 columns */ } } </style> <div class="container"> <div class="row row-offcanvas row-offcanvas-right"> <div class="col-xs-12 col-sm-9"> <p class="pull-right visible-xs"> <button type="button" class="btn btn-primary btn-xs" data-toggle="offcanvas">Toggle nav</button> </p> <div class="jumbotron bisque"> <h1>Welcome <%= title %>!</h1> <p>This is an example to show the potential of an offcanvas layout pattern in Bootstrap. Try some responsive-range viewport sizes to see it in action.</p> </div> <div class="row"> <div class="col-6 col-sm-6 col-lg-4"> <h2>Heading</h2> <p>Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod. Donec sed odio dui. </p> <p><a class="btn btn-default" href="#" role="button">View details »</a></p> </div><!--/span--> <div class="col-6 col-sm-6 col-lg-4"> <h2>Heading</h2> <p>Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod. Donec sed odio dui. </p> <p><a class="btn btn-default" href="#" role="button">View details »</a></p> </div><!--/span--> <div class="col-6 col-sm-6 col-lg-4"> <h2>Heading</h2> <p>Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod. Donec sed odio dui. </p> <p><a class="btn btn-default" href="#" role="button">View details »</a></p> </div><!--/span--> <div class="col-6 col-sm-6 col-lg-4"> <h2>Heading</h2> <p>Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod. Donec sed odio dui. </p> <p><a class="btn btn-default" href="#" role="button">View details »</a></p> </div><!--/span--> <div class="col-6 col-sm-6 col-lg-4"> <h2>Heading</h2> <p>Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod. Donec sed odio dui. </p> <p><a class="btn btn-default" href="#" role="button">View details »</a></p> </div><!--/span--> <div class="col-6 col-sm-6 col-lg-4"> <h2>Heading</h2> <p>Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod. Donec sed odio dui. </p> <p><a class="btn btn-default" href="#" role="button">View details »</a></p> </div><!--/span--> </div><!--/row--> </div><!--/span--> <div class="col-xs-6 col-sm-3 sidebar-offcanvas" id="sidebar" role="navigation"> <div class="list-group"> <a target="_blank" href="#" class="list-group-item">Link</a> <a href="#" class="list-group-item">Link</a> <a href="#" class="list-group-item">Link</a> <a href="#" class="list-group-item">Link</a> <a href="#" class="list-group-item">Link</a> <a href="#" class="list-group-item">Link</a> <a href="#" class="list-group-item">Link</a> <a href="#" class="list-group-item">Link</a> <a href="#" class="list-group-item">Link</a> <a href="#" class="list-group-item">Link</a> </div> </div><!--/span--> </div><!--/row--> </div><!--/.container--> <!-- 从header.html之后到此可分为page层 --> <footer class="darkseagreen"> <p>Copyright © 2014. Designed by nieweidong.</p> </footer> <script src="/javascripts/jquery-1.11.0.min.js"></script> <script src="/javascripts/bootstrap.min.js"></script> <script> $(document).ready(function() { $('[data-toggle=offcanvas]').click(function() { $('.row-offcanvas').toggleClass('active'); }); }); </script> </body> </html>
如果样式有问题请检查下bootstrap的路径是否正确引入。
启动项目之后觉得高大上很简单,有木有!!
FAQ&总结:
俺们的express项目暂时,且express也并没有涉及到任何数据库,这个事情需要第三方node模块,比如mysql或者MongoDB,后续俺会有一章单独介绍这块。
express也不是Node中web框架的唯一选择,不过由于其文档较全,所以才以其为示例为大家介绍,其原理和实现其实细化之后并不复杂,也希望更多的JS工程师折腾出自己的Web框架。
好了,今天先给大家絮叨到这里,希望本文分享大家喜欢。