meface/docs/article/web/tool/npmTool.md

257 lines
7.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: 'Node npm'
date: 2020-10-15
author: 'ac'
categories:
- Web
tags:
- Node
- npm
---
> Node.js不是一门语言也不是库或框架而是一个js运行时环境js引擎可解析执行js文件
<!-- more -->
## Node
以前只有浏览器的js引擎解析执行js代码后来谷歌浏览器的V8js引擎被移植出来开发了Node这个独立的js运行时环境。 但Node.js中的API中没有了BOM、DOM等对象的操作新增了许多服务器级别的API如文件读写、网络服务构建、网络通信等。
### 模块系统
模块是Node.js 应用程序的基本组成部分,**文件和模块是一一对应的**。 一个 Node.js 文件就是一个模块这个文件可能是JavaScript 代码、JSON 或者编译过的C/C++ 扩展。<br>
Node.js 提供了 exports 和 require 两个对象:
- **exports** 是模块公开的接口;
- **require** 用于从外部获取一个模块的接口,即所获取模块的 exports 对象。<br>
**require和import的区别** :
1. 遵循规范
- require 是 CommonJS/AMD规范引入方式
- import是es6的一个语法标准如果要兼容浏览器的话必须转化成es5的语法
2. 调用时间
- require是运行时调用所以require理论上可以运用在代码的任何地方
- import是编译时调用所以必须放在文件开头
本质
- require是赋值过程其实require的结果就是对象、数字、字符串、函数等再把require的结果赋值给某个变量
- import是解构过程但是目前所有的引擎都还没有实现import我们在node中使用babel支持ES6也仅仅是将ES6转码为ES5再执行import语法会被转码为require
<br>
模块定义的两种方式:`exports`、`module.exports`
```javascript
//方式一a文件(模块),exports
//在使用require("a文件路径")加载这模块就可以直接访问文件中exports对象的属性获取到的是exports对象
exports.world = function(){
console.log("exports对象把world作为模块的访问接口");
}
//方式二定义文件创建对象通过module.exports暴露
//使用模块require("文件路径")获取到的是要暴露的Hello 对象,可以直接使用其属性和方法。
function Hello() {
var name;
this.setName = function(thyName) {
name = thyName;
};
this.sayHello = function() {
console.log('Hello ' + name);
};
};
module.exports = Hello;
```
require方法接受以下几种参数的传递
- http、fs、path等原生模块。
- ./mod或../mod相对路径的文件模块。
- /pathtomodule/mod绝对路径的文件模块。
- mod非原生模块的文件模块。
在 Node.js 中存在 4 类模块原生模块和3种文件模块require方法查找文件模块的策略为
1. 从**文件模块缓存**中加载
2. 从**原生模块**中加载
3. 从**文件模块**中加载
![image-20201015101035944](./images/image-20201015101035944.png)
### 全局对象
Node 中没有全局作用域只有模块作用域,模块作用域简单地说就是文件作用域,超出这个文件的就无法访问 。<br>
> require() 加载只能是执行模块中的代码,模块是完全封闭的,加载执行多个文件时即便变量重名也不会有污染问题。<br>
在浏览器 JavaScript 中,通常 window 是全局对象, 而 Node.js 中的全局对象是 global所以可以通过global对象来挂载全局变量。<br>
所有全局变量(除了 global 本身以外)都是 global 对象的属性。 <br>
global 最根本的作用是作为全局变量的宿主。 <br>
ECMAScript 全局变量的定义:<br>
1. 在最外层定义的变量;
2. 全局对象的属性;
3. 隐式定义的变量(未定义直接赋值的变量)。
当定义一个全局变量时,这个变量同时也会成为全局对象的属性。<br>
常用的全局变量(常出现在配置文件中):
1. **__filename** 表示当前正在执行的脚本的文件名。它将输出文件所在位置的绝对路径,且和命令行参数所指定的文件名不一定相同。 如果在模块中,返回的值是模块文件的路径。(路径+文件名
2. **__dirname** :表示当前执行脚本所在的目录。(路径)
## npm
NPM是随NodeJS共同发布集成在NodeJS中一起安装的包管理工具。<br>
当执行npm init命令是会创建package.json文件来描述项目中的包名、版本、依赖项等等。<br>
因为npm默认是采用国外的源下载速度比较感人所以可以改成国内厂商的源。
```shell
#查看npm源
npm config get registry
>http://registry.npmjs.org/
#修改npm源为淘宝源
npm config set registry https://registry.npm.taobao.org
```
### package.json 文件
package.json 位于模块的目录下,用于定义项目信息、配置包的属性和依赖关系。
```json
{
"name": "meface",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "vuepress dev docs",
"build": "vuepress build docs"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"vuepress": "^1.7.0",
"vuepress-theme-reco": "^1.5.7"
}
}
/*
name - 包名。
version - 包的版本号。
description - 包的描述。
homepage - 包的官网 url
author - 包的作者姓名。
contributors - 包的其他贡献者姓名。
dependencies - 生产环境使用的依赖包。如果依赖包没有安装npm 会自动将依赖包安装在 node_module 目录下。
devDependencies - 开发环境使用的依赖包
repository - 包代码存放的地方的类型,可以是 git svngit 可在 Github 上。
main - main 字段指定了程序的主入口文件require('moduleName') 就会加载这个文件。
这个字段的默认值是模块根目录下面的 index.js。
keywords - 关键字
*/
```
### 常用命令
```shell
# 初始化项目创建package.json包描述文件包名、版本、项目的依赖项配置默认信息。
npm init -y
# 下载和安装指定的包,--save 会在package.json的dependencies属性中添加依赖项
npm install --save 包名 或 npm install -S 包名
# 安装指定版本
npm install 包名@1.x
# 下载和安装指定包 -dev 会在devDependencies属性中添加依赖
npm install -dev 包名
# 一次性将dependencies选项中的依赖项全部安装简写npm i
npm install 包名
# 删除包,不删除依赖项
npm uninstall 包名
# 删除包及其依赖项
npm uninstall --save 包名
```
npm 5 版本之后会自动生成 package-lock.json 文件,并且安装包的时候都会生成或更新这个文件。<br>
安装包时也不需要加 --save 参数,会自动保存依赖信息 package-lock.json 这个文件会保存 node_modules 中所有包的信息(版本、下载地址),这样的话重新 npm install 的时候速度会更快,另一个作用是锁定下载的包的版本号,防止自动升级新版。
### 全局安装与本地安装
```shell
npm install 包名 #本地安装
npm install 包名 -g #全局安装
```
本地安装:
1. 将安装包放在 ./node_modules 下(运行 npm 命令时所在的目录),如果没有 node_modules 目录,会在当前执行 npm 命令的目录下生成 node_modules 目录。
2. 可以通过 require() 来引入本地安装的包
全局安装:
1. 将安装包放在 /usr/local 下或者你 node 的安装目录
2. 可以直接在命令行里使用