Node.js与Express 基础,学习npm常用命令,使用Express搭建web服务器

148 阅读6分钟

Node.js简介

Node 是 JavaScript 的运行环境(与系统进行交互),使用 V8 引擎。需要注意的是,Node不能调用 DOM 和 BOM 等浏览器内置的API;

传统的服务器都是多线程的,每进来一个请求,就会创建一个线程去处理请求,而Node的服务器是单线程的。Node使用事件驱动、非阻塞和异步I/O模型等技术来提高性能。

如果没有下载Node的小伙伴,可以访问官网进行下载:

运行Node.js

打开命令行窗口,转到当前项目目录下执行:node xxx.js

image-20221027203821801.png

Node模块化

模块分类及其导入

  1. 内置模块:const http = require('http') http 是模块名

内置模块的加载优先级最高,怎么理解呢,就是如果内置模块和第三方模块同名,Node会优先加载内置模块。

  1. 自定义模块:const mymodule = require('./mymodule.js') ./mymodule.js 是文件路径

引入自定义模块时,有要路径标识,如要有 ./ 或 ../,不然会被误为内置模块或第三方模块

  1. 第三方模块:const moment= require('moment') moment 是模块名

引入第三方模块时,Node 会在 node_modules 文件夹里查找相关的文件

使用 require() 加载模块时,会执行其里面的代码:

被引入的文件(模块):myPackage.js

// myPackage.js
console.log('Hello,dada!');

module.exports = {}

引入的文件:nodeStu.js(运行该文件的代码)

const myPackage = require('./myPackage')

image-20221027204218939.png

从这个结果可以验证,使用 require() 加载模块时,确实会执行被引入文件里的代码。

模块的加载机制

模块在第一次加载后会被缓存,也就是说多次调用require()不会使模块代码执行多次。require()会优先从缓存中加载,从而提高模块的加载效率。

// myPackage.js
console.log(6666);

另一个js文件:

image-20221027211027326.png

从该结果可以验证,虽然多次调用 require,但myPackage.js 文件里的代码只会执行一次。

对外共享模块作用域:module.exports

模块作用域可以避免全局变量污染的问题

不经过 module.exports 导出作用域,外界是访问不了的。

module.exports 默认是一个空对象 {}。

// 文件:mymodule.js
var student = {
    name: '达达',
    age: 19
}

module.exports = student;		// 导出作用域
// 另一个js文件
const mymodule = require('./mymodule.js')   //  引入模块(.js可省略)

console.log(mymodule)			// { name: '达达', age: 19 }
console.log(mymodule.name)		// 达达

小贴士:exports 也可实现 module.exports 的作用,不过还是不同等的。

npm命令汇总:下载模块

安装第3方模块后,会生成 node_modules 文件夹,在协作时(git)不要发送该文件,因为其体积比较大;另外还会生成 package.json 文件,该文件用来记录安装了哪些项目包,当然还会生成其他文件,这里就不一一列举了。下面来看常用的命令吧:

  • 初始化包管理:npm init -y 会先创建package.json文件(注:根目录要全英文)
  • 安装包:npm install name 简写形式:npm i name
  • 安装指定版本号:npm i name@1.22.1
  • 安装全局包:npm i nrm -g
  • 一次性安装所有的包:npm i 默认安装package.json里所有的包
  • 卸载项目包:npm uninstall name
  • 卸载全局包:npm uninstall name -g
  • 安装为devDependencies:npm i name -D 适用于上线之后不用的包( -D--save-dev的简写 )
  • 安装为dependencies:npm i name -S 适用于开发阶段和上线之后都要用到的包(-S是可省略的)

切换下载镜像源:提高下载速度

先安装便捷工具:npm i nrm -g

查看所有镜像源:nrm ls

nrmquerysource.png

切换镜像源:nrm use taobao

开发包与发布

开发包需要创建一个文件夹,在该文件夹下要有如下文件:

  1. package.json
{
    "name": "dada-package-test",
    "version": "1.0.0",
    "main": "index.js",
    "description": "this is a test",
    "keywords": ["test"],
    "license": "ISC"
}
  1. README.md

  2. index.js

// 包的入口文件
module.exports = {

}

以上文件做好之后,登录npm账号(可在终端执行npm login进行登录),登录后将终端切换到包的根目录,运行 npm publish 即可将包发送到 npm;

如果想删除,可在72小时以内执行:npm unpublish 包名 -- force

注:需将镜像源调回npm官方服务器;建议不要发布没有意义的包(可进行学习测试,然后删掉)。

fs文件系统模块

fs 是 Node 内置的模块,可直接导入,该文件主要用来操作文件,比如写入文件和读取文件:

const fs = require('fs')		// 导入fs模块

// 写入文件
function writeFile(content) {
    fs.writeFile('test.txt', content, function (err) {  // 不止txt格式,JSON格式也可
        if (err) {                                      // 写入成功,err值为null
            console.log(err.message);                   // 不会自动创建文件夹
        } else {                                        // 回调函数前有编码格式参数(可选)
            console.log('写入成功!');
        }
    })
}

let content = '你好啊!Hello!达达!';
writeFile(content);

// 读取文件
function readFile(file) {
    fs.readFile(file, 'utf8', function(err, data){      // 默认就是 utf8
        if (err) {
            console.log(err.message);
        } else {
            console.log('读取成功:');
            console.log(data);
        }
    })
}

let file = 'test.txt';
readFile(file);

path路径模块

path 是 Node 内置的模块,用来处理路径相关的问题:

const path = require('path');

// 路径拼接
const pathStr = path.join('/test', '/day1', '/study')
console.log(pathStr);       // \test\day1\study

const pathStr2 = path.join(__dirname, 'imgs')       // __dirname --当前文件夹
console.log(pathStr2);      // D:\Web_Develop\web-server\imgs

Express基础

Express 是基于 Node.js 平台,快速、开放、极简的 Web 开发框架

安装express:npm i express

安装nodemon:npm i nodemon -g 此时要使用 nodemon xx.js 来启动项目而不再使用 node xx.js

nodemon的作用是:

当更新代码后,会被nodemon监听到,从而使项目能够得到重启,这样就不用再手动重启了。

监听Get请求

const express = require('express')	// 引入express

// 创建web服务器
const app = express()

// 挂载路由  监听get请求
app.get('/index',(request, response) => {
    response.setHeader('Access-Control-Allow-Origin', '*')   // 允许跨域
    response.send('Hello,dada!This is get!')    // 发送响应体(只能发送字符串?!)
    console.log('/index 正在被访问!!');
})

// 启动服务
const PORT = 5001;		// 端口
app.listen(PORT, ()=> {
    console.log(`GET服务器正在运行:http://localhost:${PORT}/index`)
})

监听Post请求

app.post('/index', function (request, response) {
    response.setHeader('Access-Control-Allow-Origin', '*')   // 允许跨域
    response.send('Hello,dada!This is post')   // 发送响应体
})

监听All请求

app.all('/index', function (request, response) {
    response.setHeader('Access-Control-Allow-Origin', '*')   // 允许跨域
	response.send('Hello,dada!You can get all!')   // 发送响应体
})

接收query 、params参数

接收 query 参数:很简单,只需:request.query (query 是 request 里的一个属性)

app.all('/index', function (request, response) {
    response.setHeader('Access-Control-Allow-Origin', '*')   // 允许跨域
    console.log(request.query);
})

接收params参数:需要占位,如:/:name/:age,然后访问 request.params

app.all('/index/:name/:age', function (request, response) {
    response.setHeader('Access-Control-Allow-Origin', '*')   // 允许跨域
    console.log(request.params);    // { name: '达达', age: '19' }
})

托管静态资源

在本地搭建服务器,通过 URL 访问本地静态文件,如html、css、js等文件

const express = require('express')
const app = express()

// 挂载路径前缀 dada
app.use('/dada', express.static('./test1'))   // ./test1 是一个文件夹

// 可调用多次
app.use('/lolo', express.static('./test2'))    // 里面含有 html css等文件

app.listen(80, function () {
    console.log('服务器正在运行在localhost,80端口...')
})

image-20221028105701000.png

小贴士:如果 html 文件名为 index.html,则可省略文件名直接访问 html 文件,如:

http://localhost/dada/

如果html文件名是其他的,那么就需要写全文件名,其他文件也如此,如:

http://localhost/dada/xxx.html

路由模块化

// 创建路由模块
var express = require('express')
var router = express.Router()   // 创建路由对象

router.get('/user', function (request, response) {
    response.send('this is get')
})

router.post('/login', function (request, response) {
    response.send('this is post')
})

module.exports = router     // 对外导出路由对象
// 另一个文件
const express = require('express')
const app = express()

const router = require('./router')  // 导入路由模块,省略了 .js

// 添加路由前缀 dada    访问url:http://localhost/dada/user
app.use('/dada', router)     // 注册路由模块

app.listen(80, function () {
    console.log('服务器正在运行在localhost...')
})

结语

好了,本篇就学到这里咯。希望对你有帮助!拜拜,下期再见!