Node-模块加载及包

Posted 我真的爱敲代码

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Node-模块加载及包相关的知识,希望对你有一定的参考价值。


1. Node.js模块化开发

JavaScript开发弊端

  • JS在使用时存在两大问题,文件依赖(引入文件时,依赖关系的不确定)和命名冲突(导致代码覆盖,后续引入的文件的同名变量会覆盖掉之前的,而Node中文件与文件是半封闭的状态,需要使用哪些代码就把其开放出去)
  • 模块化开发能解决这两个问题。
  • 电脑组装的方式就属于模块化方式。某一个模块化的损坏并不会影响其它模块化的运行。

软件中的模块化开发:
一个功能就是一个模块,多个模块可以组成完整应用,抽离一个模块不会影响其他功能的运行。

比如:

Node.js中模块化开发规范

  • Node.js规定一个javascript文件就是一个模块,模块内部定义的变量和函数默认情况下在外部无法得到
  • 模块内部可以使用exports对象进行成员导出, 使用require方法导入其他模块。


模块成员导出:

// a.js
// 在模块内部定义变量
 let version = 1.0;   默认情况下该变量和函数无法在外部进行访问和导出
 // 在模块内部定义方法
 const sayHi = name => `您好, ${name}`;
 // 向模块外部 !!导出数据!! 
 exports.version = version;    将变量和函数作为exports的属性值
 exports.sayHi = sayHi;

模块成员的导入:导入模块时后缀可以省略

  // b.js
  // 在b.js模块中导入模块a(路径前提:a模块和b模块在同一个目录下)
 let a = require('./b.js');    require方法会有一个返回值,实际上就是b模块的export对象
  // 输出b模块中的version变量
 console.log(a.version);
  // 调用b模块中的sayHi方法 并输出其返回值
 console.log(a.sayHi('黑马讲师')); 

模块成员导出的另一种方式:
exportsmodule.exports的别名(地址引用关系),导出对象最终以module.exports为准

module.exports.version = version;
module.exports.sayHi = sayHi;

模块导出两种方式的联系与区别:

若改变指向,最终导出以module.exports指向为主

即当exports对象和moudle.exports对象指向的不是同一个对象时,以module.exports为准,exports导出不生效(exports=对象的写法是错误的)


2. 系统模块

系统模块指:Node运行环境提供的API. 因为这些API都是以模块化的方式进行开发的, 所以又称Node运行环境提供的API为系统模块

例,文件操作模块:

系统模块fs文件操作

f:file 文件 ,s:system 系统,文件操作系统。

const fs = require('fs');

读取文件内容:
应用场景:常用于当客户端访问服务器端时请求index.html(首页),服务器端需要现在硬盘中找到这个文件并读取出文件的内容然后返回给客户端。

fs.reaFile('文件路径/文件名称'[,'文件编码'], callback);   //callback为回调函数

读取文件语法示例:

写入文件内容:
应用场景:常用于在网站的运行中要监控网站的运行情况,例如在网站运行中是否报错的情况,因此希望在程序运行报错时候将错误情况写入程序日志中,只需查看程序日志就可查看程序是否存在报错。

fs.writeFile('文件路径/文件名称', '数据', callback);
写入文件实例:
 const content = '<h3>正在使用fs.writeFile写入文件内容</h3>';
 fs.writeFile('../index.html', content, err => {
   if (err != null) { 
       console.log(err);
       return;
   }
   console.log('文件写入成功');
 });

系统模块path路径操作

进行路径拼接的原因:

  • 不同操作系统的路径分隔符不统一,即:/public/uploads/avatar
  • Windows 上是 \\ /
  • Linux 上是 / (Linux操作系统通常被用作网站的服务器)
  • 实际应用场景:网站中的头像上传功能,用户上传的头像实际上存在服务器硬盘中的某个文件夹中,在程序文件中要想找到这个文件夹就必须拼接这个文件夹的路径

路径拼接语法:

path.join('路径', '路径', ...)  //path本身指路径,join即加入
//所有参数都是路径
路径拼接语法示例:
  // 导入path模块
 const path = require('path');
  // 路径拼接
 let finialPath = path.join('itcast', 'a', 'b', 'c.css');
  // 输出结果 itcast\\a\\b\\c.css
  //path.join不属于耗时操作,可以通过返回值来直接返回其拼接结果
 console.log(finialPath);

相对路径和绝对路径:

  • 大多数情况下使用绝对路径,因为相对路径有时候相对的是命令行工具的当前工作目录,如文件读取操作
  • 在读取文件或者设置文件路径时都会选择绝对路径
  • 使用 __dirname 获取当前文件所在的绝对路径

3. 第三方模块

即:别人写好的、具有特定功能的、能直接使用的模块即第三方模块,由于第三方模块(代码量巨大)通常都是由多个文件组成并且被放置在一个文件夹中,所以又名

第三方模块有两种存在形式:

  • js文件的形式存在,提供实现项目具体功能的API接口(与jQuery相似)。
  • 命令行工具形式存在,辅助项目开发

获取第三方模块:
npmjs.com:第三方模块的存储和分发仓库

npm (node package manager) : node的第三方模块管理工具(npm不需要单独安装,在node安装好的时候就已经集成)

  • 下载:npm install 模块名称
  • 卸载:npm unintall package 模块名称

全局安装与本地安装:

  • 命令行工具:全局安装(将模块下载到公共目录,所有项目都可以使用该模块)
  • 库文件:本地安装(将模块下载到当前项目下,供当前项目使用)

nodemon

nodemon是一个命令行工具,用以辅助项目开发。
(在修改文件后,帮助执行该文件的工具)—>监控文件的保存操作,当文件发生保存操作时会重新执行该文件
在Node.js中,每次修改文件都要在命令行工具中重新执行该文件,非常繁琐。

使用步骤:

  1. 使用npm install nodemon –g 下载它(-g,g代表globle全局安装)
  2. 在命令行工具中用nodemon命令替代node命令执行文件
  3. 在命令行工具中,ctrl+c表示终止操作

nrm

nrm ( npm registry manager ):npm下载地址管理工具,可以快速切换npm的下载地址,因为npm默认的下载地址在国外,国内下载速度慢,且经常发生下载失败情况

而如今国内(如阿里巴巴)有专门的服务器去和国外的服务器做同步,开发者就不需要再专门去国外下载,速度很快

使用步骤:

  1. 使用npm install nrm –g 下载它
  2. 查询可用下载地址列表 nrm ls
  3. 切换npm下载地址 nrm use 下载地址名称

Gulp

  • 基于node平台开发的前端构建工具(即允许将机械化操作编写成任务, 想要执行机械化操作时执行一个命令行命令任务就能自动执行了)
  • 用机器代替手工,提高开发效率。

Gulp功能:

  • 项目上线,HTML、CSS、JS文件压缩合并
  • 语法转换(es6转为es5、less转为css …)
  • 公共文件抽离(将网站头部代码抽取到公共文件)
  • 修改文件浏览器自动刷新

Gulp使用:

  1. 使用npm install gulp下载gulp库文件
  2. 在项目根目录下建立gulpfile.js文件(文件名为Gulp要求,不能随意更改)
  3. 重构项目的文件夹结构,新建src目录放置源代码文件,新建dist目录放置构建后文件
  4. gulpfile.js文件中编写任务.
  5. 在命令行工具中执行gulp任务

Gulp中提供的方法

方法说明
gulp.src()获取任务要处理的文件
gulp.dest()输出文件
gulp.task()建立gulp任务
gulp.watch()监控文件的变化
 const gulp = require('gulp');
  // 使用gulp.task()方法建立任务
 gulp.task('first', () => {   //'first'为当前要建立的任务的名字,后一个参数为回调函数
    // 获取要处理的文件
    gulp.src('./src/css/base.css')     //取到要处理的文件的目录
    // 将处理后的文件输出到dist目录
    .pipe(gulp.dest('./dist/css'));
 });

Gulp插件

(了解)

插件说明
gulp-htmlminhtml文件压缩
gulp-csso压缩css
gulp-babelJavaScript语法转化
gulp-lessless语法转化
gulp-uglify压缩混淆JavaScript
gulp-file-include公共文件包含
browsersync浏览器实时同步

4. package.json文件

node_modules文件夹的问题:

  1. 文件夹以及文件过多过碎,当项目整体拷贝给别人的时候,,传输速度会很慢.
  2. 复杂的模块依赖关系需要被记录,确保模块的版本和当前保持一致,否则会导致当前项目运行报错

package.json文件的作用:

  • 项目描述文件,记录了当前项目信息,例如项目名称、版本、作者、github地址、当前项目依赖了哪些第三方模块等(一般这些信息都放在项目的根目录下),因此项目在别人的电脑上也可以运行。
  • 使用npm init -y命令生成(y即yes,表示不填写任何信息,全部使用默认值)。

通常文件依赖分为项目依赖和开发依赖两种

项目依赖

  • 在项目的开发阶段和线上运营阶段,都需要依赖的第三方包,称为项目依赖,这种依赖指项目在运行过程中所要依赖的提供API接口的第三方库文件
  • 使用npm install包名命令下载的文件(安装的第三方模块)会默认被添加到 package.json 文件的 dependencies 字段中
 {
    "dependencies": {
        "jquery": "^3.3.1//例如在项目中写了很多jQuery代码,若在项目运行中缺少了jQuery模块则会运行失败
    }
 } 

开发依赖

  • 在项目的开发阶段需要依赖,线上运营阶段不需要依赖的第三方包(例如Gulp),称为开发依赖
  • 使用npm install 包名 --save-dev命令将包添加到package.json文件的devDependencies字段中
 {
    "devDependencies": {
        "gulp": "^3.9.1}
 } 

package-lock.json文件的作用:

  • 锁定包的版本,确保再次下载时不会因为包版本不同而产生问题
  • 加快下载速度,因为该文件中已经记录了项目所依赖第三方包的树状结构和包的下载地址,重新安装时只需下载即可,不需要做额外的工作(下次下载中npm不用再分析模块的依赖关系)

5. Node.js模块的加载机制

无论使用哪种方法都需要使用require方法对模块进行引用。
(模块查找规则)

当模块拥有路径但没有后缀时

require('./find.js');
require('./find');
  1. require方法根据模块路径查找模块,如果是完整路径直接引入模块。
  2. 如果模块后缀省略,先找同名JS文件再找同名JS文件夹
  3. 如果找到了同名文件夹,找文件夹中的index.js
  4. 如果文件夹中没有index.js就会去当前文件夹中(find的文件夹)的package.json文件中查找main选项中的入口文件
  5. 如果找指定的入口文件不存在或者main中没有指定入口文件就会报错,模块没有被找到

当模块没有路径且没有后缀时

(即只有模块的名字)

require('find');
  1. Node.js假设它是系统模块
  2. Node.js会去node_modules文件夹中
  3. 首先看是否有该名字的JS文件,(如果有就执行)
  4. 再(在node_modules文件夹中)看是否有同名文件夹
  5. 如果是文件夹看里面是否有index.js,(如果有就执行)
  6. 如果没有index.js查看该文件夹中的package.json中的main选项确定模块入口文件
  7. 否则找不到报错

以上是关于Node-模块加载及包的主要内容,如果未能解决你的问题,请参考以下文章

Python之模块及包的导入

Python3之模块及包的导入

[python]模块及包

selenium + python自动化测试unittest框架学习python导入模块及包知识点

Python 生成器 匿名函数 递归 模块及包的导入 正则re

Node.js:如何重新加载模块