nodejs 安装 调试 常用技巧 汇总

 

 

 

目录

升级 node 到当前稳定版

安装 node

debug

grpc

 

set

主要用途

注意

Map

遍历

转数组

数组转Map

mongodb

cmap

denque

underscore


 

 

升级 node 到当前稳定版

sudo npm install -g n
sudo n stable

查看装好的版本 

node -v
v12.19.0
npm -v
6.14.8

 

typescript, gulp, cnpm

sudo npm un -g typescript
sudo npm i -g typescript

sudo npm un -g gulp
sudo npm cache clean -f
sudo npm i -g gulp@4.0.2

sudo npm un -g cnpm
sudo npm i -g cnpm

 

安装 node

推荐上面 升级的方式(方便快捷)。

https://nodejs.org/en/

下载自己合适的版本。

我下的是 node-v12.18.3-linux-x64, 解压后

把 node-v12.18.3-linux-x64/lib/node_modules 拷贝到 /usr/local/lib
然后在/usr/local/bin 创建 链接
sudo chmod +777 ../lib/node_modules/npm/bin/npm-cli.js
sudo ln ../lib/node_modules/npm/bin/npm-cli.js npm
lrwxrwxrwx   1 root           root           38 2020-08-29 19:27 npm -> ../lib/node_modules/npm/bin/npm-cli.js

sudo ln -s /home/wjs/Downloads/node-v12.18.3-linux-x64/bin/node   /usr/local/bin/

然后查看版本号, 有下面输出表示安装成功

~/Downloads/node-v12.18.3-linux-x64 $ node -v
v12.18.3
~/Downloads/node-v12.18.3-linux-x64 $ npm version
{
  npm: '6.14.6',
  ares: '1.16.0',
  brotli: '1.0.7',
  cldr: '37.0',
  http_parser: '2.9.3',
  icu: '67.1',
  llhttp: '2.0.4',
  modules: '72',
  napi: '6',
  nghttp2: '1.41.0',
  node: '12.18.3',
  openssl: '1.1.1g',
  tz: '2019c',
  unicode: '13.0',
  uv: '1.38.0',
  v8: '7.8.279.23-node.39',
  zlib: '1.2.11'
}

我电脑上曾经提示下面错误 

┌───────────────────────────────────────────────────────┐
│                npm update check failed                │
│          Try running with sudo or get access          │
│         to the local update config store via          │
│ sudo chown -R $USER:$(id -gn $USER) /home/wjs/.config │
└───────────────────────────────────────────────────────┘

用下面的命令来解决 

sudo chown -R wjs:$(id -gn wjs) /home/wjs/.config

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

查看源

npm config ls

 

debug

 

node --inspect acc.js

停在第一句
node --inspect-brk acc.js

 

安装chrome 

wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
sudo dpkg -i google-chrome-stable_current_amd64.deb

卸载
sudo apt-get remove google-chrome-stable

 

打开 chrome

输入

chrome://inspect

点击 页面中的 inspect

断点,源码这些的都有

F10 下一步,不进函数

F11  进函数

 

grpc

node 安装的时候可能会很慢

npm i 后面指定下面的参数

npm i --grpc_node_binary_host_mirror=https://npm.taobao.org/mirrors/

--grpc_node_binary_host_mirror=https://npm.taobao.org/mirrors/

制作docker 镜像时添加  npm install --grpc_node_binary_host_mirror=https://npm.taobao.org/mirrors/

 

set

摘自 https://wangdoc.com/es6/set-map.html

类似于数组,但是成员的值唯一,无重复。

let s = new Set();
[2, 3, 2, 2].forEach(x => s.add(x));
console.log(s); // Set { 2, 3 }

遍历

var engines = new Set(["Gecko", "Trident", "Webkit", "Webkit"]);
for (var e of engines) {
  console.log(e);
}
// Gecko
// Trident
// Webkit

* Set.prototype.add(value):添加某个值,返回 Set 结构本身。
* Set.prototype.delete(value):删除某个值,返回一个布尔值,表示删除是否成功。
* Set.prototype.has(value):返回一个布尔值,表示该值是否为Set的成员。
* Set.prototype.clear():清除所有成员,没有返回值。

* Set.prototype.keys():返回键名的遍历器
* Set.prototype.values():返回键值的遍历器
* Set.prototype.entries():返回键值对的遍历器
* Set.prototype.forEach():使用回调函数遍历每个成员

 

主要用途

// 并集
let union = new Set([...a, ...b]);
// Set {1, 2, 3, 4}

// 交集
let intersect = new Set([...a].filter(x => b.has(x)));
// set {2, 3}

// (a 相对于 b 的)差集
let difference = new Set([...a].filter(x => !b.has(x)));
// Set {1}

去除数组的重复值

[...new Set([1, 2, 3, 4, 4])]    // 1 2 3 4
[...new Set('ababbc')].join('')  // abc

注意

set中两个对象总是不相等的

let set = new Set();

set.add({});
set.size // 1

set.add({});
set.size // 2

 

Map

摘自 https://wangdoc.com/es6/set-map.html

js的Object ,本质上也是个 map,但是key 只能是字符串。

Map 的key 可以是非字符串。Map 的键实际上是跟内存地址绑定的,只要内存地址不一样,就视为两个键

const m = new Map();
const o = {p: 'Hello World'};

m.set(o, 'content')
m.get(o) // "content"

// 虽然 和 o 的值是一样的,但是指向了不同的地址
m.get({p: 'Hello World'}); // undefined

// 键/值对的数量
m.size // 1

m.has(o) // true
m.delete(o) // true
m.has(o) // false

遍历

let map = new Map().set('a', 1).set('b', 2);
for (let pair of map) {
  console.log(pair);
}
// ['a', 1]
// ['b', 2]

for (let [key, value] of map) {
  console.log(key + ' : ' + value);
}
// a : 1
// b : 2

转数组

const map = new Map([
  [1, 'one'],
  [2, 'two'],
  [3, 'three'],
]);

[...map.keys()]
// [1, 2, 3]

[...map.values()]
// ['one', 'two', 'three']

[...map.entries()]
// [[1,'one'], [2, 'two'], [3, 'three']]

[...map]
// [[1,'one'], [2, 'two'], [3, 'three']]

数组转Map

将数组传入 Map 构造函数,就可以转为 Map。

new Map([
  [true, 7],
  [{foo: 3}, ['abc']]
])
// Map {
//   true => 7,
//   Object {foo: 3} => ['abc']
// }

 

mongodb

MongoDB 是一个基于分布式的文档数据库,nodejs的官方驱动是 mongodb

数据库推荐docker 安装 启动 

// 下载
docker pull mongo

// 启动
sudo docker run -p 5555:27017 -v /home/wjs/wjsmongo:/data/db --name wjs_mongodb -d mongo

// 命令解释
-p 指定容器的端口映射,mongodb 默认端口为 27017
-v 为设置容器的挂载目录,这里是将<LocalDirectoryPath>即本机中的目录挂载到容器中的/data/db中,作为 mongodb 的存储目录
--name 为设置该容器的名称
-d 设置容器以守护进程方式运行

安装node驱动

npm i mongodb -s

简单使用

"use strict";

const { MongoClient } = require("mongodb");

// 数据库路径  数据库名 可以在 uri 中指定
const client = new MongoClient("mongodb://192.168.13.4:27017/wjs", {
  useUnifiedTopology: true,
  auth:{user:"wjs", password:"123456"},  // 账号密码只能在这里指定
});

async function run() {
  try {
    await client.connect();

    const db = client.db();
    const user = db.collection('user'); // 这里其实不会去发命令创建表格

    // 表格不存在也没关系,会自动创建
    // name 建唯一索引
    await user.createIndex({name:1}, {unique:true});

    // 增
    let result = await user.insertOne({name:'孙悟空', address:'花果山'});

    const _id = result.insertedId;
    console.log(`插入的成功 ${_id}`);

    // 查
    const monkey = await user.findOne({_id});
    console.log(monkey);

    // 改  且返回 修改后的对象
    const nmonkey = await user.findOneAndUpdate({_id}, { $set: {address:'养马场'} }, { returnOriginal: false });
    console.log(nmonkey);

    // 删
    await user.removeOne({_id});
    
  } finally {
    // Ensures that the client will close when you finish/error
    await client.close();
  }
}
run().catch(console.log);

 

cmap

是mongodb驱动的连接池管理模块, 我猜是 Connection Management Access Protocol 的简称

3.6.2版本的cmap由下面6个文件组成

errors.js   

定义了 PoolClosedError 和 WaitQueueTimeoutError 两个错误, 均以pool 为参数

stream_description.js

连接数据库时,会给数据库发送 admin.$cmd 的 ismaster 命令, 收到数据库应答时调用 StreamDescription的receiveResponse 方法
,得到数据库的类型 是Standalone 还是 RSPrimary 等。同时解析出数据库支持的 压缩,以及
  'minWireVersion',
  'maxWireVersion',
  'maxBsonObjectSize',
  'maxMessageSizeBytes',
  'maxWriteBatchSize',

events.js

定义了连接池所有的事件
const CMAP_EVENT_NAMES = [
  'connectionPoolCreated',
  'connectionPoolClosed',
  'connectionCreated',
  'connectionReady',
  'connectionClosed',
  'connectionCheckOutStarted',
  'connectionCheckOutFailed',
  'connectionCheckedOut',
  'connectionCheckedIn',
  'connectionPoolCleared'
];

message_stream.js

MessageStream ,解析数据库发来的原始数据,装包发给数据库的数据

server.js connect() 的时候 会调用 this[kMonitor].connect();
monitor的connect() 开启了个定时调用,并且立马执行第一次 checkServer
checkServer 发现还没和数据库连接上,就执行 core/connection/connect.js 的 connect
connect(options, ... ) 的options是来自于 monitor, 而monitor在构造函数中就指定了 options.connectionType 是 cmap/connection的Connection
于是connect(options, ... ) 
connect会发起和数据库的连接,成功连上后在回调中根据 options.connectionType 生成了Connection 对象

参数 stream 实际上就是 驱动和数据库建立的 tcp socket
Connection(stream, options) 构造函数中

    // hook the message stream up to the passed in stream
    stream.pipe(this[kMessageStream]);
    this[kMessageStream].pipe(stream);

这样驱动和数据库的连接的socket的数据就流给了 kMessageStream, 而kMessageStream的数据就流给了socket

数据库有数据发给驱动,socket 就收到数据,然后 write 给kMessageStream
驱动有命令发给数据库,就调用 kMessageStream 的writeCommand, 装好命令包后 push 给socket

 

 

denque

高性能的双向队列。 比double-ended-queue还快。

内部维护了个数组,head tail 下标。首部,尾部插入删除都非常快。 随机位置取值也只要计算下偏移位置,O1复杂度。

按2倍扩容,缩容。

用法示例

// npm i denque -s

const Denque = require('denque');

// 栈
let stack = new Denque();
let sz = stack.push(1); // push返回当前stack 尺寸    
stack.push(2);

stack.size(); // 2

console.log(stack.pop());  // 2
console.log(stack.pop());  // 1


// 队列, 初值 1 2 3
let que = new Denque([1, 2, 3])
que.shift();   // 1   shift() 相当于 popFront() 删除并返回头部元素
que.shift();   // 2
que.shift();   // 3

que.push('item3');   // 尾部插入    item3
que.push('item4');   //             item3 item4
que.unshift('item2'); // 头部插入   item2 item3 item4
que.unshift('item1'); //           item1 item2 item3 item4 

que.size();   // 4

que.get(2); // 随机取值,  性能极快   item2
que.get(3); // 随机取值,  性能极快   item3

que.peekFront(); // 获取头部元素   item1
que.peekBack();  // 获取结尾元素   item4


que.removeOne(2);  // 删除中间元素 性能不佳

// que.remove(index, count); // 从index 开始的删除count个元素   

que.clear();  // 清空
que.isEmpty(); // 是否为空


// splice(index, count) 删除 index开始的count个元素, 返回删除的元素,
// splice(index, count, ...args)  用 args 填充删除掉的空间
let q = new Denque([10,11,12,13,14,15,16,17,18,19]);
let ret = q.splice(1,5, 101, 102);  
console.log(q.toArray()); // [10, 101, 102, 16,17,18,19]
console.log(ret); // [11,12,13,14,15]

underscore

npm i underscore
npm i @types/underscore -D
const _ = require('underscore');

// 复制一份
let cp = _.clone({name:'wjs', age:22})

// 删除指定元素  原数组不变
let a = ["wjs", "lj", "zlg", "wjs", "zy"];
let newOne = _.without(a, "wjs"); // [ 'lj', 'zlg', 'zy' ]

// 按指定属性排序
alldevs = _.sortBy(alldevs, 'devname')

let persons = [
    { detail: { age: 21} },
    { detail: { age: 23} },
    { detail: { age: 22} },
];
persons = _.sortBy(persons, p => p.detail.age)

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值