第三十二章 node

一、初始node

1、含义:一个基于ChromeV8解析引擎的JavaScript运行时环境。可以理解为一个运行js的软件

2、特点:没有图形化界面,不能先打开在运行,需要配合你的文件和软件(node)一起运行

3、node为什么可以运行js

  • 我们每天写的 js 代码需要引入到我们的.html文件中
  • 就是因为在浏览器中有js的解析引擎
  • node 基于ChromeV8解析引擎
  • 专门用来解析我们的 js 的
  • 就可以执行(运行)我们的js

4、node的组成

  • ECMAscript:这是一个标准
  • 操作电脑的能力 I/O(input/output) 后端的代码 数据库的操作
  • node 不能操作DOM和BOM

5、什么是前端js,什么是后端nodejs

  • js 就是 js
  • 就是看你要运行到那个环境中了
  • 如果是你要运行到 .html 文件中,你就可以书写 除了标准以外的 DOM和BOM
  • 如果你要运行在node中,只能书写node认识的 ECMAscript,不能书写 和 DOM和BOM相关的内容,因为node不认识

注意:node.js的版本一般在8以上就可以了

二、node的命令行操作

1、启动我们的node

  • win + r
  • 之后输入cmd
  • 按回车
  • 就会看见一个黑窗口,在这里实行我们的node

注意:你要知道你在哪个文件夹或者是哪个目录中进行,如果你找错了目录写了也没有意义

2、常用的指令

(1)切换目录

cd 文件名称

注意:只能切换相同盘符的

(2)返回上一目录

cd ..

(3)查看当前文件夹下的内容

dir

(4)切换盘符

盘符:  

eg: d: 切换到D盘

注意: 大小写无所谓 

(5) 清屏指令:当我们的黑窗口里面的内容比较多的时候,不利于我们阅读,需要清楚一些没有用的内容

window系统:

cls

MAC系统:

 clear

三、如何让我们的node执行js文件

第一种

  • 就是直接书写我们的js代码
  • 就是在我们的黑窗口中书写
  • 执行一个指令: $ node 回车
  • 之后就会进入到一个编辑状态
  • 这个时候就可以书写我们的js代码了
  • 不要书写 node 不认识

缺点:没有提示以及不能保存

 第二种:就是执行我们的.js结尾的文件

  • 首先要找到你要执行的.js文件
  • 也就是你的黑窗口需要和你要执行的文件同一层级
  • 执行的指令: $ node 你要执行的文件的名称
  • 之后就会执行你的.js中的内容了

四、node的开发方式

第一种:把所有的代码都放到一个.js文件中,是可以的,但是不利于阅读和维护,我们不建议

第二种:模块化开发

1、导入

语法: require(你要到导入的文件的路径)

注意: 在node中 如果是以.js结尾的文件 , .js可以省略不写

2、导出

语法一: module.exports = 你要导出的内容,这样的导出方式只能导出一个

语法二: module.exports.属性名 = 属性值

module.exports 是一个对象

3、模块化的分类

  • 自定义模块:就是我们书写的每一个.js文件
  • 内置模块:就是node自带的一些模块
  • 第三方模块:就是别人写好的我们拿来使用的模块

五、自定义模块

1、module:在每一个我们的.js文件中,都会自带一个变量: module

2、我们输出module会打印出:

 
    Module {
        // 这个表示的是模块的表示符
        id: '.',
        //表示的是文件所在的文件路径
        path: 'F:\\04_day\\03_代码\\005_自定义模块',
        //我们向外导出的内容 , 没有就是一个空对象
        exports: {},
        // 表示的是文件的绝对路径
        filename: 'F:\\04_day\\03_代码\\005_自定义模块\\out.js',
        // 表示的是这个文件有没有被加载过
        loaded: false,
        // 表示的是我这个文件中有没有导入其它的模块(子模块)
        children: [],
        // 第三方模块的一个查找路径
        paths: [
            'F:\\node_modules'
        ]
    }

3、exports:在我们的node中 , 每一个js文件,还单独定义了一个变量 , 这个变量叫做: exports,这个变量保存的是 module.exports 的地址

  • 如果你想要想本身的module.exports 内添加内容,可以使用

module.exports.xxx = yyy

exports.xxx = yyy 

  • 如果你想要修改本身的module.exports,只能使用:

module.exports = xxx

console.log(module.exports === exports)  //true 

六、内置模块 fs

1、fs 是node中的一个内置模块,使用的时候直接导入即可,因为内置相当于node已经导出了

// 导入我们的内置模块 fs

const fs = require('fs')

2、fs含义:是一个专门用来操作文件或者是文件夹的模块,里面保存的都是一些和操作文件或者是文件夹相关的方法

3、常用的几个方法(fs是我随便取的变量名可更换)

(1)语法: fs.readFile(路径地址,格式,回调函数)

=>路径地址: 就是你要读取的那个文件所在的地址

=>格式: 选填的,默认走的是Buffer格式,如果写 我们可以写 utf-8 或者是utf8

=>回调函数: 读取文件完毕以后要执行的函数,读取成功了 是完毕,读取失败了 也是完毕

作用:读取文件 , 异步读取文件

const fs = require('fs')

console.log('start')
// 因为是异步读取,所以要在回调函数里面获取结果
fs.readFile('./text.txt', 'utf8', function (err, data) {
    // err 表示读取的时候出现的错误
    // data 表示读取到的内容,如果出现错误,那么是 data 是没有内容的
    console.log(deat)
})
console.log('end')

(2)语法: fs.readFileSync(路径地址,格式)

作用: 也是来读取文件的 , 这个是同步读取

const fs = require('fs')

// 因为是同步读取,所以直接以返回值的形式接收读取的内容就可以
const res = fs.readFileSync('./text.txt', 'utf8')
// 同步读取的时候,如果出错会直接在控制台报错,并中断程序继续执行
// 如果没有错误,res 就会得到文件中的内容
console.log(res)

(3)语法: fs.writeFile(路径地址,你要写入的内容,回调函数)

作用: 异步写入文件

特点:如果你要写入的这个文件不存在 , 会自动创建这个文件并写入,会完全覆盖式的替换掉之前的所有内容

fs.writeFile('./text.txt', '我是要写入的内容', function () {
    console.log('写入完成')
})

(4)语法: fs.writeFileSync(路径地址,你要写入的内容)

作用: 就是同步写入文件

fs.writeFileSync('./text.txt', '我是要写入的内容')

2、http模块

(1)作用:用来创建一个服务,这个服务就是我们自己开启一个服务器,提供数据的,当你创建完毕以后 , 你的电脑上就有了一台自己的服务器,接收请求 , 返回响应

(2)创建一个服务

语法: const 变量名 = http.createServer(function () {})

函数的触发时机: 前端发来的每一个请求都会触发这个函数

作用: 就是创建一个服务 , 或者说开启一个服务器

返回值: 就是一个服务

const server = http.createServer(function (req, res) { 
    // req(request): 表示的是所有的前端的请求信息
    // res(response): 表示的是后端给出的响应

    /*
        在我们的 req 中有几个需要大家知道的
            => 在我们的req中有一个成员:url
                -> 表示的是本次请求的地址
            => 在我们的req中有一个成员:method
                -> 表示的是本次请求的一个请求方式
    */
    
    // console.log(req.url);
    // console.log(req.method);
    // 我们是可以通过 req.url 获取到用户的请求地址的
    // 我们后端就可以根据不同的地址给出不同的响应

    // 后端给出的响应
    // 语法: res.end(后端返回的响应信息)
    // 注意: 只能返回字符串

    if (req.url === '/test/first') { 
        // 代码执行到这里 , 说明你请求的地址是 /test/first
        res.end('hello world')
    }
    if (req.url === '/test/second') { 
        // 代码执行到这里 , 说明你请求的地址是 /test/second
        const obj = {
            name: 'Rose',
            age: 25
        }
        // 后端返回我们的数据
        res.end(JSON.stringify(obj))
    }
})

// 2. 需要我们监听一个端口号
// 语法: server.listen(端口号,function() {})
server.listen(8080, function () { 
    // 当我们的这行代码执行成功以后 , 这个函数就执行了
    console.log('监听8080端口号成功 , 服务器开启');
    // 一旦说这个服务开启 , 黑窗口就变成了一个服务器
    // 会一直在监听服务的变化
    // 这个时候是不能在黑窗口中书写指令的
})

3、内置模块 path

(1)作用:是一个和我们的路径相关的模块,里面保存的都是一些和路径相关的方法,专门用来处理一些路径想法的操作

导入我们的path模块

// 导入我们的path模块
const path = require('path')
// console.log(path);
/* 
    <ref *1> {
  resolve: [Function: resolve],
  normalize: [Function: normalize],
  isAbsolute: [Function: isAbsolute],
  join: [Function: join],
  relative: [Function: relative],
  toNamespacedPath: [Function: toNamespacedPath],
  dirname: [Function: dirname],
  basename: [Function: basename],
  extname: [Function: extname],
  format: [Function: bound _format],
  parse: [Function: parse],
  sep: '\\',
  delimiter: ';',
  win32: [Circular *1],
  posix: <ref *2> {
    resolve: [Function: resolve],
    normalize: [Function: normalize],
    isAbsolute: [Function: isAbsolute],
    join: [Function: join],
    relative: [Function: relative],
    toNamespacedPath: [Function: toNamespacedPath],
    dirname: [Function: dirname],
    basename: [Function: basename],
    extname: [Function: extname],
    format: [Function: bound _format],
    parse: [Function: parse],
    sep: '/',
    delimiter: ':',
    win32: [Circular *1],
    posix: [Circular *2],
    _makeLong: [Function: toNamespacedPath]
  },
  _makeLong: [Function: toNamespacedPath]
}
*/

(2)常用方法

=> join()

  • 语法: path.join('路径碎片1','路径碎片2',...)

  • 作用: 就是把碎片拼接成一个相对路径

  • 返回值: 就是一个拼接好的相对路径

// join()
let res = path.join('a', 'b', 'c', 'd', 'e')
// console.log(res); // a\b\c\d\e

=> resolve()

  • 语法: path.resolve('路径碎片1','路径碎片2',...)

  • 作用: 就是把碎片拼接成一个绝对路径

  • 返回值: 就是一个拼接好的绝对路径

// resolve()
let res1 = path.resolve('a', 'b', 'c', 'd', 'e')
// console.log(res1); // F:\2217班\第六周\05_day\03_代码\01_内置模块\a\b\c\d\e

=> parse()

  • 语法: path.parse(路径信息)

  • 作用: 就是把我们的路径信息解析成一个详细的内容

  • 返回值: 是一个对象, 里面就是我们路径的详细的信息

// parse()
let res2 = path.parse('d:/a/b/c/d/e/index.html')
console.log(res2);
/* 
    {
        表示的是根目录
        root: 'd:/',
        表示的是根目录下的详细信息
        dir: 'd:/a/b/c/d/e',
        完整的文件名
        base: 'index.html',
        后缀名
        ext: '.html',
        文件名
        name: 'index'
    }
*/

3、内置模块 url

1、导入我们的内置模块

// 导入我们的内置模块
const url = require('url')

// console.log(url);
/* 
    {
  Url: [Function: Url],
  parse: [Function: urlParse],
  resolve: [Function: urlResolve],
  resolveObject: [Function: urlResolveObject],
  format: [Function: urlFormat],
  URL: [class URL],
  URLSearchParams: [class URLSearchParams],
  domainToASCII: [Function: domainToASCII],
  domainToUnicode: [Function: domainToUnicode],
  pathToFileURL: [Function: pathToFileURL],
  fileURLToPath: [Function: fileURLToPath],
  urlToHttpOptions: [Function: urlToHttpOptions]
}
*/

2、常用方法

// parse()
// let res = url.parse('http://www.xiaodengwei.com:6666/a/b/c/index.html?name=xiaodengwei&age=18')
// console.log(res);
/* 没有经过深度解析的
    Url {
        表示的是我们的请求协议
        protocol: 'http:',
        如果后面跟的是两个斜杠 // 
        slashes: true,
        认证信息
        auth: null,
        url内的 域名 + 端口号
        host: 'www.xiaodengwei.com:6666',
        就是我们的端口号
        port: '6666',
        表示的就是我们的域名
        hostname: 'www.xiaodengwei.com',
        表示的是我们的哈希值
        hash: null,
        表示的是url的查询字符串 参数
        search: '?name=xiaodengwei&age=18',
        表示的是真实的参数
        query: 'name=xiaodengwei&age=18',
        url内的完整的请求地址
        pathname: '/a/b/c/index.html',
        表示的是我们的路径
        path: '/a/b/c/index.html?name=xiaodengwei&age=18',
        url的完整信息
        href: 'http://www.xiaodengwei.com:6666/a/b/c/index.html?name=xiaodengwei&age=18'
    }
*/

let res = url.parse('http://www.xiaodengwei.com:6666/a/b/c/index.html?name=xiaodengwei&age=18',true)
console.log(res);

/* 
    Url {
        protocol: 'http:',
        slashes: true,
        auth: null,
        host: 'www.xiaodengwei.com:6666',
        port: '6666',
        hostname: 'www.xiaodengwei.com',
        hash: null,
        search: '?name=xiaodengwei&age=18',
        query: [Object: null prototype] { name: 'xiaodengwei', age: '18' },
        pathname: '/a/b/c/index.html',
        path: '/a/b/c/index.html?name=xiaodengwei&age=18',
        href: 'http://www.xiaodengwei.com:6666/a/b/c/index.html?name=xiaodengwei&age=18'
    }
*/

console.log(res.query); // { name: 'xiaodengwei', age: '18' }
console.log(res.query.age);  // 18

七、第三方模块

1、 发送邮件的第三方node-mailer

(1)打开命令行工具 , 切换到项目的根目录,输入指令: $ npm install nodemailer

(2)导入第三方

const nodemailer = require('nodemailer')

(3)创建一个邮件发送器

语法: const transporter = nodemailer.createTransport({配置项})

(4)使用邮件发送器发送邮件

语法: 发送器(transporter).sendMail({邮件的内容配置},回调函数)

2、moment

 打开文件所在目录,输入指令

npm install moment

// 导入我们的第三方
const moment = require('moment');

// 定义一个时间
moment.locale('zh-cn')
const time = new Date()
let res = moment(time).format('LLLL')
console.log(res);

3、express

(1)含义:首先是一个第三方,是node开发的一个框架,相当于我们把原声node进行深度的封装,将来我们使用的时候直接进行调用

(2)使用:当我们使用的时候需要下载,打开cmd,切换到项目的根目录,执行

npm install express

(3)导入我们的express

 const express = require('express')

(4) 利用我们的express创建一个服务
​​​​​​​

const server = express()
server.use('/static', express.static('./client/'))
server.get('/goods/list', (req, res) => {
     let obj = {
        code: 1,
        message: '请求成功了'
    }
    res.send(obj)
})
// 发送一个post请求
server.post('/users/login', (req,res) => { 
    // 我们这里不考虑参数的问题
    res.send({
        code: 1,
        message:'post请求成功了, 我们这里不考虑参数的问题'
    })
})
// 3. 就是需要监听一个端口号
server.listen(8080,() => console.log('成功监听8080端口号 , 服务器启动成功'))

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值