欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

前端模块化:AMD,CMD,Commonjs

程序员文章站 2022-06-13 21:26:52
...

commonjs规范

前端模块化:AMD,CMD,Commonjs

Node 应用由模块组成,采用 CommonJS 模块规范。

定义module

每个文件就是一个模块,有自己的作用域。在一个文件里面定义的变量、函数、类,都是私有的,对其他文件不可见。

暴露接口

CommonJS规范规定,每个模块内部,module变量代表当前模块。这个变量是一个对象,它的exports属性(即module.exports)是对外的接口。加载某个模块,其实是加载该模块的module.exports属性。

 	var x = 5;
	var addX = function (value) {
	  return value + x;
	};
	module.exports.x = x;
	module.exports.addX = addX;
引用

require方法用于加载模块。

 	var example = require('./example.js');
	console.log(example.x); // 5
	console.log(example.addX(1)); // 6

模块的分类

  • 内置模块

    案例: 打包压缩包

    • 流程:

    ​ 读取文件

    ​ 创建压缩包

    ​ 将读取的数据流写入压缩包

    ​ 输出压缩包

    const fs=require('fs');// 引入内置模块fs 读取文件
    
    const zlib=require('zlib');// 引入内置模块zlib 创建压缩包
    
     // const inp = fs.createReadStream( 路径 )
    
    const inp=fs.createReadStream('./ys.txt');//读出数据
    
    const gzip=zlib.createGzip();// 创建压缩包
    
    const outp=fs.createWriteStream('./ys.txt.gz'); // const outp = fs.createWriteStream(路径)  流正在写入的文件的路径
    
    inp
    
    .pipe(gzip)// pipe管道
    
    .pipe(outp)
    
  • 自定义模块

    // 自定义模块
    
    const name={
    
        name:"zhanagz",
    
        age:12
    
    }
    
    const str="lisi";
    
    // 导出模块
    
    // 方式一    可以输出多个模块  安全性高
    
    module.exports={
    
        name,
    
        str
    
    }
    
    // 方式二
    
    // module.exports=name;   一次只能导出一个模块   安全性不高
    
    // 使用导出模块方式一时使用的模块导入方式
    
    // const {name,str} =require('路径');
    
    
    
    // const {name,str} =require('./2-name-definition.js');
    
    
    
    // console.log(name.name,str);//zhanagz lisi
    
    // console.log(name,str);//{ name: 'zhanagz', age: 12 } 'lisi'
    
    
    
    // 使用导出模块方式二时使用的模块导入方式
    
    // const name=require('./2-name-definition.js')
    
    // console.log(name);//{ name: 'zhanagz', age: 12 }
    
    
    
    // const {name}=require('./2-name-definition.js')
    
    // console.log(name);//zhanagz
    
  • 第三方模块

    
    //     使用流程: 
    
    //       1. 安装
    
    //         先创建package.json 文件 npm init -y //ackage.json记录安装了那些包的详细信息
    
    //         npm/cnpm i request -S/-D     
    
    //           -S   --save  生产环境
    
    //           -D   --save-dev  dev development的简写   开发环境  
    
    //       2. 使用
    
    //         request这个模块是做数据请求
    
    
    
    //       3. Node中数据请求存在跨域吗?
    
    //         - 不存在
    
    
    
    const request = require('request');
    
    // request('url',function)url数据接口   function回调函数   格式如下
    
    request('https://m.lagou.com/listmore.json', function (a, b, c) {//三个参数分别是error, response, body
    
      console.log('a:', a); //error
    
      console.log('b:', b); //response 返回所有结果
    
      console.log('c:', c); // body 数据   string类型
    
      // console.log(typeof c);//检测是string类型
    
    });
    

npm 使用

官网:https://www.npmjs.com/

安装:无需安装

查看当前版本:

 $ npm -v

更新:

 $ npm install [email protected] -g

初始化工程

 $ npm init

 $ npm init --yes 默认配置

安装包

使用npm install会读取package.json文件来安装模块。安装的模块分为两类
dependencies和devDependencies,分别对应生产环境需要的安装包和开发环境需要的安装包。

 $ npm install

 $ npm install <package_name> 

 $ npm install <package_name> --save

 $ npm install <package_name> --save-dev

更新模块

 $ npm update

卸载模块

 $ npm uninstall <package_name>

 $ npm uninstall --save lodash

配置npm源

  • 临时使用, 安装包的时候通过–registry参数即可

    $ npm install express --registry https://registry.npm.taobao.org

  • 全局使用

      $ npm config set registry https://registry.npm.taobao.org
      // 配置后可通过下面方式来验证是否成功
      npm config get registry
      // 或
      npm info express
    
  • cnpm 使用

    	 // 安装cnpm
    	  npm install -g cnpm --registry=https://registry.npm.taobao.org
    
    	  // 使用cnpm安装包
    	  cnpm install express
    

常用的内置模块

node 常用内置api

(1) URL 网址解析
解析URL相关网址信息
url.parse(urlString[, parseQueryString[, slashesDenoteHost]])
url.format(urlObject)
url.resolve(from, to)
(2) QueryString 参数处理
querystring.escape(str)
querystring.unescape(str)
querystring.parse(str[, sep[, eq[, options]]])
querystring.stringify(obj[, sep[, eq[, options]]])
(3) HTTP 模块概要
http.createServer([options][, requestListener])
http.get(options[, callback])
简易的爬虫
代理跨域处理

  • HTTP操作

1:从nowapi中找一个免费接口,进行数据请求

/* 

  http模块 有三个方法

    1:http.get   用作数据请求     数据接口可以到nowapi找

    2:http.request

    3:http.post(不重要)



    业务: 找一个接口,进行数据请求

*/
const http=require('http')

http.get('http://api.k780.com/?app=weather.city&cou=1&appkey=10003&sign=b59bc3ef6191eb9f747dd4e83c99f2a4&format=json', (res) => {

  const { statusCode } = res; // 获取请求状态码  200 301 302 303 304 404  500 

  const contentType = res.headers['content-type'];// 获取请求类型数据类型

 // json数据的content-type         'content-type': 'application/json'

  let error;

  if (statusCode !== 200) {// 如果状态码不是200 ,输出报错信息

​    error = new Error('请求失败\n' +

​                      `状态码: ${statusCode}`);

  } else if (!/^application\/json/.test(contentType)) {//不是json数据的

​    error = new Error('无效的 content-type.\n' +

​                      `期望的是 application/json 但接收到的是 ${contentType}`);

  }

  if (error) {// 如果报错了,将报错信息存入日志

​    console.error(error.message);

​    // 消费响应数据来释放内存。

​    res.resume();

​    return;

  }



  res.setEncoding('utf8');// 字符编码

  let rawData = '';

  res.on('data', (chunk) => { rawData += chunk; });// 通过data事件拼接数据流

  res.on('end', () => {// 获取数据结束了 

​    try {// 高级编程语法         捕获错误信息

​      const parsedData = JSON.parse(rawData);

​      console.log(parsedData);

​    } catch (e) {

​      console.error(e.message);

​    }

  });

}).on('error', (e) => {

  console.error(`出现错误: ${e.message}`);

});

2:自定义静态服务器

/ 自定义静态服务器

/* 

  \* 后端服务器有两种类型

​    \1. web服务器  【 静态服务器 】

​    \2. api服务器  【 暴露接口 】



  \* 请求头部报文 4部分

​    \1. general 请求基本信息

​    \2. response Headers  响应头

​    \3. request Headers  请求头

​    \4. 携带参数

​      \- query string paramters   用于get请求

​      \- form data  用于post请求



*/

const http=require('http');

const host = 'localhost'  

const port = 8000 

http.createServer((request, response) => {//创建一个静态服务器

​    // response.writeHead( 状态码,请求头 )

​    response.writeHead( 200, {

​        'Content-type': 'text/html;charset=utf8'

​      })

​      response.write('<h3> 这里使用Node创建的一个静态服务器 </h3>') // 往前端发送信息

​      

​    response.end();// 告诉前端信息已经结束了  如果没有这一条会一直在请求

  }).listen(port,host,()=>{

​    console.log( `The server is running at: http://${ host }:${ port }` )

  })

3:爬虫

/* 

  http模块

  爬虫

​    \* 步骤:爬取一段数据 -> 数据清洗(需用到第三方类库 cheerio) -> 后端服务器 -> 发送前端 -> 渲染数据

​    \* 不是所有网站都可以爬取   (一般爬后端渲染的网站)

​    \* 反爬虫 

​    \* 爬虫: 后端渲染的网站

​    */





const host = 'localhost'  

const port = 8000 

http.createServer((request, response) => {//创建一个静态服务器

​    // response.writeHead( 状态码,请求头 )

​    response.writeHead( 200, {

​        'Content-type': 'text/html;charset=utf8'

​      })





​      const http = require('http');



​      //清洗数据 引入第三方类库

​      const cheerio=require('cheerio')

​      

​      const options = {

​          hostname: '',//域名

​          port: 80,//端口号

​          path: '',//地址

​          method: 'get',//请求方式

​          headers: { //请求头
				.......
​              'Content-Type': 'application/x-www-form-urlencoded',

​              'Content-Length': 0

​          }

​      };

​      

​      

​      

​      http.get(options, (res) => {//获取数据

​          const { statusCode } = res; // 获取请求状态码  200 301 302 303 304 404  500 

​          const contentType = res.headers['content-type'];// 获取请求类型数据类型

​          // json数据的content-type         'content-type': 'application/json'

​          res.setEncoding('utf8');// 字符编码

​          let rawData = '';

​          res.on('data', (chunk) => { rawData += chunk; });// 通过data事件拼接数据流

​          res.on('end', () => {// 获取数据结束了 

​              try {// 高级编程语法         捕获错误信息

​                  // const parsedData = JSON.parse(rawData);//先不将其转化为json格式 

​                  // console.log(rawData);

​                  // 清洗数据

​                  const $ = cheerio.load( rawData )

​            $('td.student a').each(function (index,item) {

​            //   console.log( $( this ).text())  

​              response.write(`<h4>${$( this ).text()}</h4>`) // 往前端发送信息

​            })

​            response.end();// 告诉前端信息已经结束了  如果没有这一条会一直在请求

​              } catch (e) {

​                  console.error(e.message);

​              }

​          });

​      }).on('error', (e) => {

​          console.error(`出现错误: ${e.message}`);

​      });

​      

​      

  }).listen(port,host,()=>{

​    console.log( `The server is running at: http://${ host }:${ port }` )

  })

(4) 事件 events 模块

Node.js中event模块

*/
const fs=require('fs')

const http=require('http')

const host='localhost'

const port=3000



class myEvent extends Events{}; //类的继承

const myevent= new myEvent();// 实例化类得到一个实例

// console.log(myevent);//输出对象



// 事件发布

// myevent.on("事件名称",回调函数)

myevent.on("aa",function(){ 

​      // 书写任务

  // 任务: 将yyb.txt中的内容发送前台

​    http.createServer((req,res)=>{

​        res.writeHead(200,{

​            'Content-type':'text/html;charset=utf8'

​        })

​    fs.readFile('./ev.txt','utf8',(error,docs)=>{// error作为第一个参数的回调函数,我们叫做错误优先的回调函数

​       res.write(`<h4>${docs}</4>`)

​       res.end()

​        })

​         // 2

​    // why? 错误? 为什么res.end()不能放在fs.readFile外面

​    // res.end()   因为fs.readFile在队列中 代码先执行完主线程后执行队列  在执行主线程的时候res.end()就结束了任务

​    }).listen(port,host,()=>{

​        console.log(`服务器运行在:http://${host}:${port}`)

​    })

​    console.log('aa');//aa

})

// 事件的订阅

// myevent.emit('事件名称');

myevent.emit('aa');

(5) 文件fs模块
打印目录树
(6) Stream 流模块
歌词播放
音乐下载
(8) request 方法

2、Node.js 基础应用
1、应用 HTTP 模块编写一个小爬虫工具
(1) 利用爬虫获取“拉勾网”首页列表数据
(2) 通过 npm 安装 cheerio 模块获得数据
2、后端表单的提交
要求:
(1) 应用 request post 模拟提交表单

文件读取

Node中文件读取的方式主要有:

fs.readFile(file[, options], callback(error, data))

fs.readFile('c:\\demo\1.txt', 'utf8', (err, data) => {
  if (err) throw err;
  console.log(data);
});

fs.readFileSync(file[, options])

try {
  const data = fs.readFileSync('c:\\demo\1.txt', 'utf8');
  console.log(data);
} catch(e) {
  // 文件不存在,或者权限错误
  throw e;
}

fs.createReadStream(path[, options])

const stream = fs.createReadStream('c:\\demo\1.txt');
let data = ''
stream.on('data', (trunk) => {
  data += trunk;
});
stream.on('end', () => {
  console.log(data);
});

由于Windows平台下默认文件编码是GBK,在Node中不支持,可以通过iconv-lite解决

Readline模块逐行读取文本内容

const readline = require('readline');
const fs = require('fs');

const rl = readline.createInterface({
  input: fs.createReadStream('sample.txt')
});

rl.on('line', (line) => {
  console.log('Line from file:', line);
});
例如:
// 字符编码的转换

/* 

  Node.js读取文件都是二进制流 

​    Buffer 

​    binary

*/

const fs=require('fs');

// fs.readFile('./index.txt', (err, data) => {//readFile()异步地读取文件的全部内容。

//     if (err) throw err;

//     // console.log(data);//<Buffer 3c 21 44 4f 43 54 59 50 45 20 68 74 6d 6c 3e 0d 0a 3c 68 74 6d 6c 20 6c 61 6e 67 3d 22 65 6e 22 3e 0d 0a 3c 68 65 61 64 3e 0d 0a 20 20 20 20 3c 6d 65 ... >

​    

//     // console.log(data.toString());//我是用来强制转换的

// });



fs.readFile('./index.txt','utf8', (err, data) => {//readFile()异步地读取文件的全部内容。

​    if (err) throw err;

​    console.log(data);//我是用来强制转换的

});

文件写入

Node中文件写入的方式主要有:

fs.writeFile(file, data[, options], callback(error))

fs.writeFile('c:\\demo\a.txt', new Date(), (error) => {
  console.log(error);
});

fs.writeFileSync(file, data[, options])

try {
  fs.writeFileSync('c:\\demo\a.txt', new Date());
} catch (error) {
  // 文件夹不存在,或者权限错误
  console.log(error);
}

fs.createWriteStream(path[,option])

var streamWriter = fs.createWriteStream('c:\\demo\a.txt');
setInterval(() => {
  streamWriter.write(`${new Date}\n`, (error) => {
    console.log(error);
  });
}, 1000);

###node中的异步操作

node中的异步操作

  • fs模块对文件的几乎所有操作都有同步和异步两种形式
  • 例如:readFile() 和 readFileSync()
  • 区别:
    • 同步调用会阻塞代码的执行,异步则不会
    • 异步调用会将读取任务下达到任务队列,直到任务执行完成才会回调
    • 异常处理方面,同步必须使用 try catch 方式,异步可以通过回调函数的第一个参数
console.time('sync');
try {
  var data = fs.readFileSync(path.join('C:\\Users\\iceStone\\Downloads', 'H.mp4'));
  // console.log(data);
} catch (error) {
  throw error;
}
console.timeEnd('sync');

console.time('async');
fs.readFile(path.join('C:\\Users\\iceStone\\Downloads', 'H.mp4'), (error, data) => {
  if (error) throw error;
  // console.log(data);
});
console.timeEnd('async');