node 模块系统 npm
什么是模块化:
- 文件作用域
- 通信规则
加载 require,导出
commonJs模块规范
在Node中的JavaScript还有一个很重要的概念:模块系统
- 模块作用域
- 使用require方法用来加载模块
- 使用exports接口对象来导出模块中的成员
main.js中的代码
//默认得到的是对象
//使用对象中的成员必须点出来某个成员才能访问
//有时候对于一个模块,我仅仅就是希望导出一个方法就可以了
var fooExports=require('./foo')
console.log(fooExports)
foo.js中的代码
var foo='bar'
function add(x,y){
return x+y
}
//只能得到我想要给你的成员
//这样做的目的是为了解决变量命名冲突的问题
// exports.add=add
//exports是一个对象
//我们可以通过多次为这个对象添加成员实现对外导出多个内部成员
//如果一个模块需要直接导出某个成员,而非挂载的方式
//那这个时候必须使用下面这种方式
module.exports='hello'
require两个作用:
执行被加载模块中的代码
得到被加载模块中的exports导出接口对象
exports
Node中是模块作用域,默认文件中所有成员只在当前文件模块有效
对于希望可以被其他模块访问的成员,我们就需要把这些公开的成员都挂载到exports接口对象中就可以了
导出多个成员(必须在对象中):
exoports.a=123
exports.b='hello'
exports.c=function(){
console.log('ccc')
}
exports.d={
foo:'bar'
}
导出单个成员(拿到的就是:函数,字符串)
module.exports='hello'
以下情况会 覆盖
module.exports='hello'
//以这个为准,后者会覆盖前者
module.exports=function(x,y){
return x+y
}
也可以导出多个成员
module.exports={
add:function(){
return x+y
},
Str:'hello'
}
exports 和 module.exports的联系
在node中是有一个代码是var exports=module.exports
也就是说
exports是moduel.exports的一个引用
他们指向同一个地址
当这个两个混用是要特别特别注意分清他们的地址,
因为无论怎么样最后都会默认return moduel.exports
也就是说最后返回的都是moduel.exports地址里的东西
如果你实在分不清只使用moduel.exports
//这个是添加对象
module.exports.add="hello"
// 这个是直接赋值,如果重复用回被覆盖
module.exports='hello'
require方法加载规则
优先缓存加载
由于a中已经加载过b了,所以这里不会重复加载,可以拿其中这个借口对象,但是不会重复执行里面的代码
这样做的目的是为了避免重复加载,提高模块加载效率
判断模块标识
自己写的模块
//如果是非路径形式的模块标识
//路径形式的模块
// ./ 当前目录,不可省略
// ../ 上一级目录,不可省略
// /xxx 几乎不用
// d:/a/foo.js 几乎不用
// 首位的/在这里表示的是当前 文件模块所属磁盘根路径
// require('./foo.js')
核心模块
//核心模块的本质也是文件
//核心模块的文件已经被编译到了二进制文件中了,我们只需要按照名字来加载就可以了
// require('fs')
// require('http')
第三方模块
//第三方模块
// 凡是第三方模块都必须通过npm来下载
// 使用的时候就可以通过require('包名')的方式来进行夹杂才 可以使用
// 不可能有任何一个第三方包和核心模块的名字是一样的
// 实际上最后加载的还是文件
npm
node package manager
npm 网站
npmjs.com
npm命令行工具
只要你安装了node就已经安装了npm
npm install 包名 --save
下载并保存依赖项(在package.json文件中的dapendencies选项)
npm uninstall --save 包名
删除的同时也会把依赖信息也去除
package.json
我们建议每一个项目都要有一个package.json文件(包描述文件,就像产品说明书 一样)
这个文件可以通过npm init的方式自动初始化出来
对于我们来讲,最有用的是哪个dependencis选项,可以用来帮我们保存第三方包的依赖信息。
如果你的node_modules
删除了也不用担心,我们只需要:npm install
就会自动把package.json
中的 dependencies
中的所有依赖都下载回来
- 建议每个项目的跟目录下都有一个
package.json
文件 - 建议执行
npm install包名的时候都加上 --save
这个选项,目的是用来 保存依赖项信息
Express
原生的http在某些方面表现不足以应对我们的开发需求,所以我们就需要使用框架来加快我们的开发效率,让代码更高度统一
在Node中。有很多web开发框架,我们这里以学习express为主
Express 中的文件资源开放
在Express中开放资源就是一个API 的事
app.use(’/public/’,express.static(’./public/’))
//0.安装
//1.引入包
var express= require('express')
//2.创建服务器应用 程序
//也就是原来的http.createServer
var app=express()
//在Express中开放资源就是一个API的事儿
//公开指定目录
//只要这样做了,你就可以直接通过/public/xxx的方式访问public目录中的所有资源了
app.use('/public/',express.static('./public/'))
//当服务器 收到get请求/时,执行回调处理函数
app.get('/',function(req,res){
res.send('hello world')
})
app.get('/about',function(req,res){
res.send('你好,我是express')
})
//相当于server.listen
app.listen(3000,function(){
console.log('app is running at port 3000')
})
//当以/public/开头的时候,去./public/目录中找到对应的资源
// app.use('/public/',express.static('./public/'))
//当省略第一个参数的时候,则可以在网址上通过省略/public/的方式访问
//app.use(express.static('./public/'))
在express中使用art-template
// 安装
//npm i art-template --save
//npm i art-template express-art-template --save 在express中下载模板引擎
//配置使用art-template模板引擎
//第一个参数,表示,当渲染.html结尾的文件的时候,使用art-template模板
// express-art-template 是专门用来在Expree中吧art-template 整合到Express中
//虽然外面这里不需要记载art-tempalte但是也必须 安装
//原因就在于express-art-template依赖了art-template
app.engine("html",require('express-art-template'))
//Express为Response相应对象提供了一个方法
//render方法默认是不可使用,但是配置了模板引擎就 可以使用了
//res.render('html模板名',{模板数据})
//第一参数不能写路径,默认会去项目中的views目录 查找该模板文件
//也就是说express有一个约定,开发人员吧所有的视图文件都 放到view目录中
const art=require('express-art-template')
小练习将基础的留言评论用express再写一遍
首先还是index.html
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title></title>
</head>
<body>
<h1>这是首页</h1>
<h2><a href="/post">点击评论</a></h2>
<ul>
{{each comments}}
<li>{{$value.name}}说:{{$value.message}}--{{$value.dataTime}}</li>
{{/each}}
<li>
</li>
</ul>
</body>
</html>
然后是post.html
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title></title>
</head>
<body>
<h1>这是post页面</h1>
<h2><a href="/">首页</a></h2>
<form action="/pinglun" method="get">
<label for="input_name">你的名字</label>
<input type="text" required minlength="2" maxlength="10" id="input_name" name="name"><br>
<!-- required minlength="2" maxlength="10"这是验证长度最长和最短 -->
<label for="form-message">留言内容</label>
<textarea required minlength="5" maxlength="20" rows="10" cols="30" id="form-message" name="message">
</textarea>
<button type="submit">发表 </button>
</form>
</body>
</html>
最后是app.js
var express= require('express')
var app=express()
var fs=require('fs')
// npm i art-template express-art-template --save 在express中下载模板引擎
//然后引用模板引擎
const art=require('express-art-template')
app.engine("html",art)
var comments=[
{
name:"小叶",
message:"今天天气不错",
dataTime:"2020-11-12"
},
{
name:"小叶1",
message:"今天很困",
dataTime:"2020-11-12"
},
{
name:"小叶2",
message:"今天天气不错",
dataTime:"2020-11-12"
},
{
name:"小叶3",
message:"今天天气不错",
dataTime:"2020-11-12"
},
{
name:"小叶4",
message:"今天天气不错",
dataTime:"2020-11-12"
},
{
name:"小叶5",
message:"今天天气不错",
dataTime:"2020-11-12"
},
]
app.get('/',function(req,res){
res.render('index.html',{
comments
})
})
app.get('/post',function(req,res){
res.render('post.html')
})
app.get('/pinglun',function(req,res){
console.log(req.query)
var comment=req.query
comment.dataTime='2020-11-12-17:49:49'
comments.push(comment)
// console.log(comments)
// res.statusCode=302
// res.setHeader('Location','/')
// res.render()
res.redirect('/')
})
app.listen(3000,function(){
console.log('app is running at port 3000')
})
修改完代码自动重启
使用一个第三方命名工具:nodemon来帮我们解决频繁修改代码重启服务器问题
nodemon是一个基于node.js开发的一个第三方命名行工具,我们使用的时候需要独立安装
//全局安装
npm install --global nodemon
//使用
nodemon app.js
基本路由
路由器
- 请求方法
- 请求路径
- 请求处理函数
get:
//当你以GET方法请求/的时候,执行对应的 处理函数
app.get('/post',function(req,res){
res.send('hello world')
})
post:
//当你以POST方法请求/的时候,执行对应的 处理函数
app.post('/',function(req,res){
res.send('Got a POST request')
})
在express获取表单GET请求参数
在express中内置一个API,可以直接通过req.query来获取
req.query
在express获取表单POST请求数据
在express中没有内置表单POST请求的API,这里我们需要一个第三方包:body-parser。
安装:
npm install --save body-parser
配置:
var express = require('express')
//0.引入包
var bodyParser = require('body-parser')
var app = express()
//配置body-parser
//只要加入这个配置,则在req请求对象上多出来一个属性:body
//也就是说你可以直接通过req.body来获取表单里请求数据了
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))
// parse application/json
app.use(bodyParser.json())
app.use(function (req, res) {
res.setHeader('Content-Type', 'text/plain')
res.write('you posted:\n')
//可以通过req.body来获取 表单POST请求数据
res.end(JSON.stringify(req.body, null, 2))
})