前端与移动开发----Node.js----npm模块,包

Node.js

回顾

  • Node是一个基于 Chrome V8 引擎的 JavaScript 运行环境用于运行独立的js文件
  • Nodejs因为Node环境执行js文件, 也管他叫Node.js
  • Nodejs可以用于编写后端的代码和项目 (链接和操作数据库)
  • 下载&安装 Nodejs环境到电脑中, 学会终端的使用以及一些常用的命令
  • cmd看好所在目录, 然后node js文件名, 回车即可让node执行这个js里的一切代码
  • path模块 - 用于处理路径字符串
  • fs模块 - 用于读写磁盘上的文件
  • querystring模块 - 用于处理url参数
  • http模块 - 创建web服务(用于给前端浏览器提供数据支持)
  • 学会如何创建一个http服务器, 重点知道什么是请求对象 / 响应对象 以及 Content-Type的作用(MIME类型)
  • 前端请求和后端响应, 静态资源/Ajax的使用

5. 模块

现实生活中, 需要什么游戏, 就把游戏的卡带, 引用归来即可

在这里插入图片描述

Node环境中,每一个js文件就是一个模块 (每个js里封装了很多的功能方法使用, 类似于前端js插件)

使用步骤

Node环境中使用模块化, 离不开三步: 模块定义(导出), 模块标识, 模块引用(导入)

CommonJS规范: 规定了模块的特性和模块之间如何引用, 规范了如下关键字和作用

5.0 全局属性

在node中, 有一个全局对象global, 它的作用和网页中window类似

在node中一定要记住是没有BOM和DOM的, 但是模拟了, setTimeout和setInterval等都是global的属性

注意, 在运行时, 每个模块js都会被套上一个这样的函数, 被系统传入5个参数(此函数无需手写)

此函数也证明, 每个模块都是独立的作用域, 互不影响

function (exports, require, module, __filename, __dirname) {
    
    
	
}
  • exports: 该对象用来将变量或函数暴露到外部
  • require: 用于引入外部的函数
  • module: module代表的是当前模块本身, exports最终要挂载在它身上
  • __filename: 当前模块文件的绝对路径 (带文件名)
  • __dirname: 当前模块文件夹的绝对路径
console.log(global); // node中全局对象
console.log(module); // 模块内置对象
console.log(exports); // module身上的属性, 也可以独立使用
console.log(require); // 方法-用于引入其他模块
console.log(__filename); // 文件绝对路径
console.log(__dirname); // 文件所在文件夹的绝对路径

5.1 导出

导出exports

向外暴露变量和方法, 只将变量或方法设置为exports的属性即可

导出module.exports

exports和module.exports等价的

  • 注意1: module.exports = {}; 会覆盖掉exports上的东西

实际暴露外部的是module.exports, 而exports只是辅助工具

index.js

// 自定义模块 - 导出这里的东西给外面使用
const PI = 3.1415926;
const className = 121;
const add = (a, b) => {
    
    
    return a + b;
}
const sub = (a, b) => {
    
    
    return a - b;
}
const formatTime = () => {
    
    
    var now = new Date("2020/12/30 09:09:04"); // 注意格式:手动修改代码中获取的时间
    var year = now.getFullYear(); // 返回年的4位
    var month = now.getMonth() + 1; // 获取月份从0开始, 所以+1
    var day = now.getDate(); // 返回几号
    var hours = now.getHours();
    var minutes = now.getMinutes();
    var seconds = now.getSeconds();

    // 前补0
    if (month < 10) {
    
    
        month = "0" + month; // 假如month为4, 那么这行代码执行后month值就为"04"
    }
    day = day < 10 ? '0' + day : day;
    hours = hours < 10 ? '0' + hours : hours;
    minutes = minutes < 10 ? '0' + minutes : minutes;
    seconds = seconds < 10 ? '0' + seconds : seconds;

    return `${
      
      year}/${
      
      month}/${
      
      day} ${
      
      hours}:${
      
      minutes}:${
      
      seconds}`;
}
// 因为每个js运行时, 外层都包着一个函数体, 所以想被别人使用的方法, 必须暴露出去
// exports / module.exports
// console.log(exports === module.exports); // true

exports.theKeyA = add; // 属性是theKeyA, 对应模块内的add方法
// module.exports会覆盖exports(最好在最后)
module.exports = {
    
    
    a: add,
    s: sub,
    PI,
    formatTime
}

5.2 导入

导入require

引入模块里暴露出来的属性/方法供我们使用

// 导入使用require关键字
// 1. 导入node核心自带模块 - 直接写模块名字(标识符)
const fs = require("fs");
console.log(fs);

// 2. 导入自己定义的模块js文件 - 相对路径
const toolObj = require("路径");
console.log(toolObj);

// 3. 第三方(其他人自定义的模块) - 标识符
// 需要学了npm后再使用
// const md5 = require("md5");

模块分类

  • 核心模块

    • 由Node引擎提供的核心模块/npm管理的模块
    • 模块的标识, 就是模块的名字, 例如(http, fs, url, path, events等)
  • 例如: require(“fs”)

  • 自定义模块

    • 由用户自己创建的模块js文件
    • 文件模块的标识就是文件的路径(相对路径)
  • 例如: require("./cu/index")

  • 第三方模块

    • 其他程序员上传到npm网站
    • 我们可以用过npm命令下载下来使用
    • 例如: require(“md5”)

require() 本质上就是引入一个对象来使用

6. npm

全称: (Node Package Manager) node的包管理器

什么是包

包是 一个/多个js模块组成的文件夹

npm作用

  1. 可对node中的包进行上传、下载、删除等操作

  2. npm功能会在安装node环境时,自动安装

  3. 建议切换成国内的镜像, 下载的快, 命令: (彻底修改, 以后都不用再执行此命令了)

    npm config set registry https://registry.npm.taobao.org 
    

    在这里插入图片描述

  4. 使用命令 npm config get registry 查看registry选项, 是否变成了taobao.org的地址 - 是就成功了

  5. npm -v 查看npm的版本

6.0 初始化包环境

  • npm init
    
    • 初始化项目(创建package.json), 需要用户输入项:

    • 直接闭眼回车 - 全都用默认值

      输入项 含义 默认值
      package name 包名字 所在文件夹名,不能包含特殊符号和中文
      version 版本号 1.0.0
      description 描述说明 空字符串
      entry point 包入口 文件夹下的index.js
      test command 测试命令 空字符串
      git repository 项目git地址 空字符串
      keywords 关键词 空字符串
      author 包作者名 空字符串
      license ISC开源许可字符串 ISC
    • 产物讲解

      • package.json: 包含npm相关的所有基础信息(包管家)
  • 还可以使用:

 npm init -y
  • -y的意思代表所有项都使用默认值(运行命令所在目录带中文或特殊符号, 则不能用这个)

6.1 下载第三方包 - moment

这是一个时间格式化的包, 可以去https://www.npmjs.com/ 找到你想要的包, 和使用文档

npm install moment

npm install 也可以写成 npm i

包的使用: 查找, 下载 , 引入 , 使用

// 工程需要准备package.json后才能使用npm
// 1. 确定工程根目录有这个文件略过此步  (npm init)

// 2. 使用npm install 命令下载第三方包, 从网上 (npm install 包名)
// 都会下载到当前运行命令所在目录的node_modules文件夹下(自动创建)

// 3. 引用下载的第三方包
const moment = require("moment"); // 会自动从当前文件所在目录下查找node_modules(固定名字-有无这个包)

// 4. 使用
let momentObj = moment();
console.log(momentObj.format("YYYY年-MM月-DD日 HH:mm:ss")); // HH代表24小时制

包环境变化

  • node_modules:第三方包 (只能在当前文件夹/子文件/…夹范围下使用)

  • package-lock.json: 锁定最大版本号(挡不住故意下载大版本), 缓存并加快npm下载

  • 补充package.json里字段解释:

    • scripts里面配置的命令, 是给npm扩展的自定义命令, 只能在package.json文件所在的目录使用
    • npm (run) xxx; 执行script里配置的 run可写可不写
    key名 含义 备注
    scripts 指定npm可以运行的命令 自定义命令
    dependencies 发布环境依赖的 第三方模块 写完项目线上环境
    devDependencies 开发环境使用的 第三方模块 本地开发时候环境
  • 可以去http://npmjs.com网站, 查看它的解释, 会告诉你安装到哪里哦~

npm额外命令

看好终端所在目录

cmd终端命令 作用 备注
npm i 包名@版本号 安装指定版本的包 不受package-lock.json限制
确定版本号再用(不能乱蒙)
npm i 包名 --save-dev 把此包配置到devDependencies中 也可以把–save-dev 换成-D
  • npm i 包名@版本号 - http://npmjs.com 查找你要下载的包的版本

  • npm i 安装多个包, 可以用空格隔开, 例如:

    npm i jquery md5 moment
    

包版本号解释

版本号是以"点分十进制" 形式进行定义的, 总共有3位数字 例如:12.9.103

  • 第一位数字: 大版本
  • 第二位数字: 功能版本
  • 第三位数字: Bug修复更新
  • 规则: 只要前面的数字增长, 后面的归零

卸载包

(就会自动从node_modules找到相关的包从磁盘删除掉)

npm uninstall 包名

多人协同开发(npm精髓)

把源代码+package.json 发给别人即可, 无需把node_modules发给别人(很大) - 发给别人,

别人运行npm install命令就会根据package.json记录的包名和版本号(注意运行命令所在目录应该是package.json所在目录)

他电脑的npm软件就会帮助它下载这些包到他的node_modules本地中使用运行即可

6.2 全局包 - nodemon

上一个monment等都是项目用到的包(本地包)

npm install 模块名 -g - 此包会被安装到全局环境下的node_modules里

window系统: C:\Users\ThinkPad\AppData\Roaming\npm\node_modules

苹果mac系统: /usr/local/lib/node_modules

  • 注意: 只有一些带cmd命令的包, (工具包) 才需要安装到全局
  • 不知道那些需要安装到全局 - 还是看官网的安装解释

全局安装nodemon模块

  • 安装命令

    npm i nodemon -g
    
  • nodemon的作用:

    • 代替node命令,启动服务的工具
    • 当更改代码之后,nodemon会自动重启服务, 妙啊←_←
  • 运行nodemon,如果报错如下:

在这里插入图片描述

  • 解决方案:

    管理员方式打开powerShell (不是普通的cmd) - 这个东西是win10新出的命令窗口

    在这里插入图片描述

然后输入: set-ExecutionPolicy RemoteSigned 命令 然后 输入A 回车即可

在这里插入图片描述

  • 全局模块和本地模块的对比

在这里插入图片描述

使用对比

以前使用node 文件名 - 启动这个文件, 每次修改后还得ctrl+c停止掉, 然后在重新执行新的代码, 再启动web服务才生效新的代码

而nodemon会实时监测你的代码变更, 然后自动重启

6.3 全局包 - i5ting_toc

此全局包, 就是把md文件, 转换成html文件的功能

  1. 执行命令

    npm install i5ting_toc -g
    
  2. 进入到md所在的文件夹, 打开cmd终端, 执行命令

    i5ting_toc -f Day02_npm模块_包.md -o
    

7. 开发自己的包

包的规范

  • 包必须以独立的文件夹而存在
  • 项目目录下, 必须有package.json文件
  • package.json必须包含(name, version, main) 这3个字段(包名字, 包版本号, 包的入口文件是哪个)
  1. 新建包文件夹 (请上https://www.npmjs.com/ 查询看看有人跟你重复没有, 自己加上名字英文拼写, 名字随便起)
  2. 在此文件夹 - cmd - 初始化包管理文件 npm init -y - 得到package.json
  3. 准备入口文件 index.js (名字可以自己随便定义, 只要跟package.json里的main字段的值对应上) - 作用, 别人引用你这个模块, 会根据package.json的main来决定引入哪个js文件里导出的对象使用
  4. 最好再准备一个README.md (可选), 一般 用于给使用者解释说明下你的包的使用方法和作用

封装arr.js / date.js / escape.js

在这里插入图片描述

arr.js - 暴露一个求最大值的功能函数

const getMax = (arr) => Math.max(...arr)

module.exports = {
    
    
    getMax
}

date.js - 暴露一个获取当前系统时间的方法

const formatTime = () => {
    
    
    var now = new Date("2019/02/03 09:09:04"); // 注意格式:手动修改代码中获取的时间
    var year = now.getFullYear(); // 返回年的4位
    var month = now.getMonth() + 1; // 获取月份从0开始, 所以+1
    var day = now.getDate(); // 返回几号
    var hours = now.getHours();
    var minutes = now.getMinutes();
    var seconds = now.getSeconds();

    // 前补0
    if (month < 10) {
    
    
        month = "0" + month; // 假如month为4, 那么这行代码执行后month值就为"04"
    }
    day = day < 10 ? '0' + day : day;
    hours = hours < 10 ? '0' + hours : hours;
    minutes = minutes < 10 ? '0' + minutes : minutes;
    seconds = seconds < 10 ? '0' + seconds : seconds;

    return `${
      
      year}/${
      
      month}/${
      
      day} ${
      
      hours}:${
      
      minutes}:${
      
      seconds}`;
}

module.exports = {
    
    
    formatTime
}

escape.js - 负责格式化标签字符串(防止流氓注入标签)

function htmlEscape(htmlStr) {
    
    
    return htmlStr.replace(/<|>|"|&/g, match => {
    
    
        switch(match){
    
    
            case '<':
                return '&lt;'
            case ">":
                return '&gt;'
            case '"':
                return '&quot;'
            case "&":
                return '&amp;'
        }
    })
}

function htmlUnEscape(str){
    
    
     return htmlStr.replace(/&lt;|&gt;|&quot;|&amp;/g, match => {
    
    
        switch(match){
    
    
            case '&lt;':
                return '<'
            case "&gt;":
                return '>'
            case '&quot;':
                return '"'
            case "&amp;":
                return '&'
        }
    })
}
module.exports = {
    
    
    htmlEscape,
    htmlUnEscape
}

入口index.js修改

const dateObj = require("./src/date");
const arrObj = require("./src/arr");
const escapeObj = require("./src/escape");

// 把对象里的key和值都集成到这里
module.exports = {
    
    
    ...dateObj,
    ...arrObj,
    ...escapeObj
}

使用自己的包

const obj = require("./121_ithm");
console.log(obj);
// arr
console.log(obj.getMax([5, 3, 10, 1]));

// date
console.log(obj.formatTime());

// escape
// <a href="baidu.com">&nbsp;123456</a>
var str = '<a href="baidu.com">&nbsp;123456</a>';
console.log(obj.htmlEscape(str)); // &lt;a href=&quot;baidu.com&quot;&gt;&amp;nbsp;123456&lt;/a&gt;

编写使用文档

我的工具包 - 欢迎使用
1. 引入工具包
​```js
const obj = require("./itheima-tool");
console.log(obj);
​```

arr模块使用
​```js
// arr
console.log(obj.getMax([5, 3, 10, 1]));
​```

date模块使用
​```js
// date
console.log(obj.formatTime());
​```

escape模块使用
​```js
// <a href="baidu.com">&nbsp;123456</a>
var str = '<a href="baidu.com">&nbsp;123456</a>';
console.log(obj.htmlEscape(str)); // &lt;a href=&quot;baidu.com&quot;&gt;&amp;nbsp;123456&lt;/a&gt;
​```

8. 发布包

注册账号

https://www.npmjs.com/ - 右上角 sign up (注册)

一定要记住以下几项, 以后要用

  • Public Email
  • Username
  • Password

一定要登录邮箱点击链接验证, 否则发布包会失败

切换镜像

因为现在我们是本地npm是和淘宝的服务器链接

而刚才注册的npmjs.com是官方的, 所以先把本机的npm镜像切换回官方的国外的镜像地址

npm config set registry https://registry.npmjs.org

等最后发布完包, 可以再切换回来

npm config set registry https://registry.npm.taobao.org

本机登录

注意跟网站右上角登录不同, 是在本地把npm和远程仓库建立登录通道


可能有点慢 - 多等会 - 毕竟国外服务器

  • 提示你输入的时候再输入

输入账号和密码(网站注册的), 提示登录成功, 一定要看好是不是带taobao几个字眼, 如果有就错了, 重新切换后在重新登录

登录成功 - 发布包

(包名不能雷同) - package.json里的name的值不能和npmjs.com网站上现有的同名

  • 发布当前运行命令所在的目录(包根目录)
npm publish

如果不好用, 就ctrl+c 重新来一次

发布完, 可以去官网搜索.让你的小伙伴用用(npm 下载) 妙啊→.→

删除包

  • npm unpublish 包名 --force (72小时内可以用这个)
  • 超过72个小时, 就永远无法删除了
  • 包名发布后, 删除后, 24小时, 不能重复发布
  • 尽量不要把没有意义的包发布上去

9. 模块加载机制

自定义模块

模块在第一次被加载后, 会被缓存, 一个模块被多次require, 只会执行一次被require的那个js文件

require("./9.0.0_index")
require("./9.0.0_index")
require("./9.0.0_index")
require("./9.0.0_index")

查找模块路线

在一个js文件, require(模块名) – 会从当前目录的node_modules里, 如果找不到一直递归往上找

即可看到查找过程

console.log(module.paths);

目录名作为模块

  1. 默认找这个目录下的package.json文件里的main属性
  2. 目录下没有package.json/没有main属性 - 则默认找index.js文件
  3. 如果上面2步都失败了, 则直接报错- Cannot find module “xxx”

参考文档

npm文档

npm下载的包搜索和教程: https://www.npmjs.com/

node-Api文档

node核心模块使用文档: http://nodejs.cn/api/

package.json文档

https://classic.yarnpkg.com/zh-Hans/docs/package-json

开发/发布环境

  1. 开发环境: 指编写代码, 时用到的环境,包含调试工具,打包工具等
  2. 生产环境: 指发布到线上后的环境

面试题

  1. NodeJS环境中, 模块加载的规范和使用规则是什么?

    答案: Nodejs遵循Commonjs规范的模块加载机制,使用require加载文件,使用 exports或module.exports导出文件

  2. npm作用是什么?

    • 允许用户从NPM服务器下载别人编写的第三方包到本地使用
    • 允许用户将自己编写的包或命令行程序上传到NPM服务器供别人使用
  3. 常用的npm指令有哪些?

    • npm init / npm search / npm install / npm remove / npm uninstall / npm config set /
  4. fs模块能否删除一个, 非空的文件夹, 如果不能应该怎么做?

    • 首先封装函数, 用于读取目标路径下所有文件/文件夹的名字
    • 开始遍历每个相对路径, 判断是文件夹, 就递归调用次函数
    • 如果是文件, 则删除此文件
    • 当上面循环结束以后, 则删除当前所在的文件夹即可
  5. module.exports和exports的区别?

    答案: 本质上是无区别的, 最终暴露给外部的都是module.exports, exports只是module.exports的辅助工具, 他们是相等的, 所以既用exports.xxx 也用module.exports, 则之前的exports.xxx会被覆盖掉

如有不足,请多指教,
未完待续,持续更新!
大家一起进步!

猜你喜欢

转载自blog.csdn.net/qq_40440961/article/details/111997214
今日推荐