Node.js学习计划(一)——模块化编程
一、创建模块
手动创建一个项目结构:
![](https://img.haomeiwen.com/i6109679/eaedd8327b051428.png)
wise-modules存放模块,app.js是入口文件。
wise-modules下创建模块hello:
'use strict';
function hello(name) {
console.log('hello', name);
}
module.exports = hello;
app.js中引入模块
'use strict';
let hello = require('./wise_module/hello');
hello('test');
二、了解require
![](https://img.haomeiwen.com/i6109679/26394b9948eb8f9a.png)
可以看到 require 后面接的是相对路径,如果改成下图:
![](https://img.haomeiwen.com/i6109679/9943074506ef986f.png)
就会发生异常,提示找不到对应模块。
这是因为在没有具体路径的时候,require 会首先检查 node.js 核心模块(如 "fs"),然后检查 node_modules,最后检查环境变量 NODE_PATH 指定的目录。
将hello.js放进node-modules目录下:
![](https://img.haomeiwen.com/i6109679/844e94a6a60f5f21.png)
![](https://img.haomeiwen.com/i6109679/9943074506ef986f.png)
这样就能正常编译了。
上面的 hello 模块是一个 js 文件,如果 hello 是一个文件夹,就需要在目录下创建一个 index.js 作为模块的入口。实际项目中,node_modules 是由 package.json 生成,里面用来存放第三方依赖库。自己开发的模块还是需要放到其他文件目录下,然后通过 require( /相对路径/ ) 引入。
三、模块的两种导出方式
1、exports导出
![](https://img.haomeiwen.com/i6109679/20ecbcb493920b5a.png)
![](https://img.haomeiwen.com/i6109679/d56b653ee9280e31.png)
用 exports 这种方式导出的时候,将 hello 函数作为导出对象的一个键值给暴露出来
2、module.exports导出
![](https://img.haomeiwen.com/i6109679/0b57e026839990a7.png)
![](https://img.haomeiwen.com/i6109679/7be2d55fa90f84aa.png)
看起来 exports 变量和 module.exports 变量似乎是同一个变量,但实际上还是有些区别,比如 exports 不能直接赋值。
exports 作为 module.exports 的衍生产物,虽然可以应对大多数情况,但仍有不足之处,所以模块导出的时候,建议使用 module.exports = * 这种方式来输出。
Node.js学习计划(二)——使用http模块搭建web服务器
创建项目结构:
![](https://img.haomeiwen.com/i6109679/49c026f31f7fa9df.png)
服务端server.js
let http = require('http');
let fs = require('fs');
let url = require('url');
let path = require('path');
let qs = require('querystring');
let c = require('child_process');
let server = http.createServer(function (req, res) {
// 获取根目录
let root = path.resolve('.');
// 获取请求路径
let filePath = url.parse(req.url).pathname;
if (filePath === '/') filePath = '/index.html';
// 生成文件路径
let absPath = path.join(root, '/public', filePath);
switch (req.method) {
case 'GET':
// 从硬盘读取文件
fs.readFile(absPath, function (err, data) {
if (err) {
// 重写响应头,返回 404
res.writeHead(404, { 'Content-Type': 'text/plain' });
// 响应文件内容
res.write("not found");
} else {
// 重写响应头,返回 200
res.writeHead(200, { 'Content-Type': 'text/html' });
// 响应文件内容
res.write(data);
}
// 结束响应,发送数据
res.end();
});
break;
case 'POST':
let postData = '';
// 监听 data 事件
req.on("data", function (chunk) {
// 拼接 post 过来的数据
postData += chunk;
});
// 监听 end 事件
req.on("end", function () {
// 使用 querystring 模块将字符串数据转为对象
let queryData = qs.parse(postData);
// 将数据以 json 字符串的形式保存到文件中
fs.writeFile(path.join(__dirname, 'wise.txt'), JSON.stringify(queryData), function (err) {
if (err) throw err;
console.log("Export Account Success!");
});
// 重写响应头
res.writeHead(200, { "Content-Type": "text/plain" });
res.end("success");
});
break;
}
});
server.listen(4567, function () {
console.log('Server listening on port 4567');
// 服务启动成功后打开对应链接
c.exec('start http://localhost:4567/');
});
客户端请求form.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form method="post">
<div>
<label for="name">用户名</label>
<input type="text" name="name">
</div>
<div>
<label for="tell">联系方式</label>
<input type="text" name="tell">
</div>
<div>
<label for="gender">性别</label>
<input type="radio" name="gender" checked>男
<input type="radio" name="gender">女
</div>
<div>
<label for="address">籍贯</label>
<input type="text" name="address">
</div>
<button type="submit">提交</button>
</form>
</body>
</html>
开启服务:node ./lib/server.js
浏览器http://localhost:4567/打开的是index.html,页面是空。
打开http://localhost:4567/form.html
![](https://img.haomeiwen.com/i6109679/3e9a54f48a653b17.png)
返回结果:
![](https://img.haomeiwen.com/i6109679/b4cdb9bbadbacbdc.png)
Node.js学习计划(三)——express起航
一、创建项目
1、安装:
npm install -g express-generator
npm install -g express
express --version // 验证是否安装成功
// 如果了解过 vue,express-generator 和 express 的关系就像 vue-cli 和 vue 的关系
2、创建项目
express node-express
![](https://img.haomeiwen.com/i6109679/24932e126d0ed3c4.png)
3、进入目录,安装依赖
cd node-express/
npm install
4、启动命令
npm start
开发过程中建议在 debug 环境中运行,所以通常使用这个命令启动项目:
set DEBUG=node-express & npm start
二、认识路由
在生成的项目文件中,有一个 routes 文件夹,存放着 express 框架预置的基本路由
![](https://img.haomeiwen.com/i6109679/7ab9bfdd2eea66f4.png)
上图中的 users.js 是一个最简单的路由
var express = require('express');
var router = express.Router();
/* GET users listing. */
router.get('/', function(req, res, next) {
res.send('respond with a resource');
});
module.exports = router;
然后在 app.js 中引入模块
var usersRouter = require('./routes/users');
并配置路由结点
app.use('/users', usersRouter);
然后在浏览器中打开 http://localhost:3000/users 就能查看到响应内容
![](https://img.haomeiwen.com/i6109679/1eb119eaeaa69873.png)
如果希望路由对外输出一个 html 页面,只需要使用 res.sendfile(url)
假如已经在 views 文件夹下准备了一个模板 test.html,然后在 users.js 中追加一个句柄
router.get('/test', function(req, res) {
res.sendfile("./views/test.html")
});
然后打开 http://localhost:3000/users/test 就能查看到 test.html
![](https://img.haomeiwen.com/i6109679/244b1e20b54f933b.png)
三、托管静态文件
如果刚才的 test.html 文件中,关联了 views 文件夹下的外部 css 或者 js 文件,就会发现这些文件都没有被加载,只要将 css 文件放到 public 文件夹下,并将文件路径改为绝对路径
![](https://img.haomeiwen.com/i6109679/537a5a59213de799.png)
<link rel="stylesheet" href="/stylesheets/test.css">
这样外部文件就能正常加载了,甚至可以通过http://localhost:3000/stylesheets/test.css 查看到对应的 css 文件
![](https://img.haomeiwen.com/i6109679/721e5aae908ddcd3.png)
这是因为在 app.js 中,已经通过 express.static 中间件将 public 文件夹设置为静态资源的根目录
app.use(express.static(path.join(__dirname, 'public')));
静态资源目录可以有多个,只需要多次调用 express.static 就行
app.use(express.static('public'));
app.use(express.static('wise'));
app.use(express.static('wrong'));
访问静态资源文件时,express.static 中间件会根据目录添加的顺序查找文件
express 允许给这些文件夹指定一个虚拟挂载点
app.use('/static', express.static('public'));
这样就能通过带有 “/static” 前缀的地址来访问 public 目录下面的文件
比如之前的 test.css 文件的地址就变成了 http://localhost:3000/static/stylesheets/test.css
如果有多个静态资源目录,还可以把它们都指定在同一个挂载点下
app.use('/static' ,express.static(path.join(__dirname, 'public')));
app.use('/static' ,express.static(path.join(__dirname, 'wise')));
app.use('/static' ,express.static(path.join(__dirname, 'wrong')));
这种方式必须要保证每个文件的路径不会冲突,如果多个文件都是同一个路径,就只有第一个文件能被正常访问。
四、中间件
上面有提到 express.static 是一个中间件,在软件领域中,中间件在应用与应用之间起到连接的作用。在 express 中,中间件就是处理 http 请求的各种函数,这些函数通过 next() 方法连接,形成了一个流水线。
中间件一般用 app.use() 注册,针对不同的请求,还可以使用 all 或者 HTTP 动词作为方法名,如 get、post,中间件可以接收三个参数,依次为 request(HTTP请求)、response(HTTP响应),next 回调函数(下一个中间件)。每个中间件都可以对 request 进行加工,并使用 next() 将 request 对象传给下一个中间件。
app.use(function(req,res,next){
// doing something
next()
})
如果向 next() 传入参数(字符串 ‘route’ 除外),则代表抛出一个错误,参数为错误文本
app.use(function(req,res,next){
// doing something
next('error')
})
而后的中间件将不再执行,直到发现一个错误处理函数为止。
在注册中间件的时候,还可以传入一个 url,让中间件的调用具有针对性
app.use('/home', function(req,res,next){
// doing something
next()
})
比如这个例子,只会对路径前缀为 “/home” 的请求调用中间件
express 其实就是由路由和中间件构成的,从本质上来说,一个 express 应用就是在调用各种中间件。
Node.js学习计划(四)——express+sql server
一、创建项目
express node-movie
因为使用 SQL Server 作为数据库,所以需要引入 mssql 模块
安装:
npm install --save mssql jquery bootstrap
将 views 目录设置为视图目录,用来存放静态页面,并且只识别 .jade 类型的文件,修改app .js
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
// 如果直接使用 .html 文件,就需要把第二行代码改为
// app.set('view engine', 'html');
jade语法,推荐学习博文(https://segmentfault.com/a/1190000000357534)
如果需要引入 css 或者 js,一般是css 和 js 文件拷贝到 public 目录下,然后在页面中引入,项目中需要引入 bootstrap,如果以这种方式引入,还得去 node_modules 目录下找到对应的文件。
app.use('/lib', express.static(path.join(__dirname, 'node_modules')));
引入文件:
link(rel='stylesheet', href='/static/stylesheets/style.css')
link(rel='stylesheet', href='/lib/bootstrap/dist/css/bootstrap.min.css')
script(src="/lib/jquery/dist/jquery.min.js")
二、创建路由
在routes目录下床建页面对应的路由
如routes/index.js
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index'); // 对应views目录下的index.jade
});
module.exports = router;
然后在app.js里引入:
var index = require('./routes/index');
在 app.js 中配置路由结点
app.use('/', index);
//重定向
app.get('/index', function (req, res) {
res.redirect('/')
})
然后在浏览器中打开项目,就能正确的渲染页面了
二、创建数据库
安装推荐文章,(https://www.cnblogs.com/xuyatao/p/6932885.html)
三、连接数据库
创建配置项
var config = {
user: 'root',
password: '123456789',
server: 'localhost',
database: 'mydatabase'
}
连接数据库
const sql = require('mssql')
router.get('/', function(req, res, next) {
sql.connect(config).then(() => {
// 插入SQL语句
return sql.query`select * from movies`
}).then(result => {
res.render('index', {
title: 'WiseWrong',
movies: result.recordset //查询结果
});
sql.close(); // 断开数据库的连接,很关键
}).catch(err => {
res.render('error');
console.log('出错了 ', err);
})
sql.on('error', err => {
res.render('error');
console.log('出错了 ', err);
})
});
不过在连接数据库过程中出错了,报错内容如下:
![](https://img.haomeiwen.com/i6109679/fe7aae81584c8bc0.png)
Node.js学习计划(五)——Koa基础项目搭建
一、创建项目
1、创建一个文件夹node-koa,生成package.json文件,安装Koa
npm init -y // 生成package.json
npm install koa -S // 安装Koa
2、创建一个app.js
const Koa = require('koa');
const app = new Koa();
app.use(async ctx => {
ctx.body = 'koa 开始了';
});
app.listen(3000);
3、package.json添加命令
![](https://img.haomeiwen.com/i6109679/92c29cd9e32c9b65.png)
4、启动命令:
npm start
5、打开浏览器http://localhost:3000/
![](https://img.haomeiwen.com/i6109679/2a7dd353316403de.png)
二、配置路由
上面 app.js 中有一个 ctx,这是一个 Koa 提供的 Context 对象,封装了 request 和 response,每一次 HTTP Request 都会创建一个 Context 对象。
我们可以通过 Context.request.path 来获取用户请求的路径,然后通过 Context.response.body 给用户发送内容,Koa 默认的返回类型是 text/plain,如果要返回一个 html 文件(或者一个模块文件),就需要修改 Context.response.type。另外,Context.response 可以简写,比如 Context.response.type 简写为 Context.type,Context.response.body 简写为 Context.type。
在项目目录下创建存放html的文件夹views,并在该目录下创建一个 index.html,然后修改 app.js
const Koa = require('koa');
const fs = require('fs');
const app = new Koa();
app.use(async (ctx, next) => {
// ctx.body = 'koa 开始了';
if (ctx.request.path === '/index') {
ctx.type = 'text/html';
ctx.body = fs.createReadStream('./views/index.html');
// 使用fs读取html文件
} else {
await next();
}
});
app.listen(3000);
重启命令,打开浏览器http://localhost:3000/index就能看到index .html页面,而访问别的地址则是 not found。
![](https://img.haomeiwen.com/i6109679/3dd2c06d08fd1a71.png)
![](https://img.haomeiwen.com/i6109679/3d05f9bab9469b17.png)
引入路由中间件koa-router
npm install koa-router -S
创建一个 routes 目录,用来存放路由文件,并在目录下创建 index.js
![](https://img.haomeiwen.com/i6109679/0754ec60c24458f8.png)
routes/index.js:
const fs = require('fs');
const router = require('koa-router')()
router.get('/index', async (ctx, next) => {
ctx.type = 'text/html';
ctx.body = fs.createReadStream('./views/index.html');
});
module.exports = router
修改app.js:
const Koa = require('koa');
const fs = require('fs');
const router = require('koa-router')();
// 相当于
// const koaRouter = require('koa-router');
// const router = koaRouter();
const app = new Koa();
/*app.use(async (ctx, next) => {
// ctx.body = 'koa 开始了';
if (ctx.request.path === '/index') {
ctx.type = 'text/html';
ctx.body = fs.createReadStream('./views/index.html');
} else {
await next();
}
});*/
const index = require('./routes/index')
app.use(index.routes(), index.allowedMethods())
//allowedMethods 用于校验请求的方法,如果用 post 请求访问 get 接口,就会直接返回失败
app.listen(3000);
另外,还可以在 url 中添加变量,然后通过 Context.params.name 访问
router.get('/about/:name', async (ctx, next) => {
ctx.body = `I am ${ctx.params.name}!`;
});
三、静态资源
在上面的 index.html 中,如果需要引入 css 等静态资源,就需要用到 koa-static
npm install koa-static -S
创建一个目录 public 用来存放静态资源
![](https://img.haomeiwen.com/i6109679/17b0d7fdee4d7461.png)
修改app.js:
const static = require('koa-static');
// 将 public 目录设置为静态资源目录
const main = static(__dirname + '/public');
app.use(main);
// 优化app.use(require('koa-static')(__dirname + '/public'));
然后就能在 index.html 中引入对应的文件了,/public默认就是静态资源的根目录
<link rel="stylesheet" href="/css/reset.css">
![](https://img.haomeiwen.com/i6109679/a389e6f327188b95.png)
四、模板引擎
上面的路由是使用 fs 模块直接读取 html 文件,开发的时候更推荐使用koa-views中间件来渲染页面。
在 app.js 中将 views 目录设定为模版目录
const views = require('koa-views')
app.use(views(__dirname + '/views'));
然后在路由文件中,就能使用 render 方法了。
// routes/index.js
const router = require('koa-router')()
router.get('/index', async (ctx, next) => {
await ctx.render('index');
});
module.exports = router
以上是直接渲染 html 文件的方法,如果要引入模板引擎,可以添加 extension 字段来设定模版类型。
app.use(views(__dirname + '/views', {
extension: 'pug' // 以 pug 模版为例
}))
如果将 Express 看作 webstorm,那么 Koa 就是 sublime。当 Express 流行的时候,其冗杂的依赖项被很多开发者所诟病。所以 Express 团队将 Express 拆卸得只剩下最基本的骨架,让开发者自行组装,这就是 Koa。Koa也有自己的脚手架koa-generato,使用脚手架进行快速开发。
推荐[博文]: (https://www.cnblogs.com/wisewrong/category/1042889.html)
网友评论