入门

创建项目

mkdir example01
cd example01
npm install colors

image.png

编辑index.js文件

require('colors');
console.log('Hello World'.rainbow)

image.png

通过package.json创建项目

{
  "name": "example01",
  "version": "0.0.1",
  "dependencies": {
    "colors": "^1.4.0"
  }
}

生成项目并运行

npm install
node index

发布项目

发布自己的工程(发布前需要指定入口文件main属性)

  • 指定入口文件main
  • 禁止发布private

image.png

其他

显示package-json的帮助文档
npm help package-json
image.png
安装工具
npm install -g express
搜索仓库
npm search realtime
查看模块相关属性
npm view realtime

JavaScript基础

JavaScript类型可以简单的分为两组:基本类型和复杂类型,基本类型访问的是值,复杂类型访问的是值得引用。

  • 基本类型包括number、boolean、string、null和undefined
  • 复杂类型包括array、function和object
// 基本类型
var a = 5;
var b = a;
b = 6; // 基本类型,修改b不会影响a
a; // 结果为 5
b; // 结果为 6

// 复杂类型
var a = ['hello','world'];
var b = a;
b[0] = 'bye';
a[0]; // 结果为 "bye"
b[0]; // 结果为 "bye"

类型的困惑

var a = 'woot';
var b = new String('woot');
console.log(a + b); // 'wootwoot'

console.log(typeof a); // 'string'
console.log(typeof b); // 'object'
console.log(a instanceof String); // false
console.log(b instanceof String); // true

console.log(a.substr == b.substr); // true
console.log(a == b); // true
console.log(a === b); // false

// null、undefined、' '、0 都会被当成false
console.log(typeof null == 'object'); // true
console.log(typeof [] == 'object'); // true

a = []
b = new Array();
console.log(Object.prototype.toString.call(a) == '[object Array]'); // true
console.log(Object.prototype.toString.call(b) == '[object Array]'); // true

数组方法

Array.isArray(new Array); // true
Array.isArray([]); // true
Array.isArray(null); // false

[1,2,3].forEach(v => console.log(v)); // 1,2,3
[1,2,3].filter(v => v<3); // 1,2
[1,2,3].map(v => v*10); // 10,20,30
[1,2,3].includes(1); // true
[1,2,3].indexOf(2); // 下标:1,不存在:-1
[1,2,3].join("-"); // 拼接 1-2-3
[1,2,3].findIndex(v => v%2==1) // 寻找第一个出现的元素下标, 找不到:-1
[1,2,3].find(v => v% 2 == 1); // 寻找第一个出现的元素, 找不到:undefined

存取器

Date.prototype.__defineGetter__('ago', function () {
    var diff = (new Date().getTime() - this.getTime()) / 1000;
    var day_diff = Math.floor(diff / 86400);
    return day_diff == 0 && (
        diff < 60 && "just now" ||
        diff < 120 && "1 minute ago" ||
        diff < 3600 && Math.floor(diff / 60) + " minutes ago" ||
        diff < 7200 && "1 hour ago" ||
        diff < 86400 && Math.floor(diff / 3600) + " hours ago"
    ) ||
        day_diff == 1 && "Yesterday" ||
        day_diff < 7 && day_diff + " days ago" ||
        Math.ceil(day_diff / 7) + " weeks ago"

});
var a = new Date("12/12/2021");
console.log(a.ago)

image.png

使用时间格式化:

function formatUseTime(diff_ms) {
  let seconds = Math.floor(diff_ms/1000)
  let minutes = Math.floor(seconds/60)
  let hours = Math.floor(minutes/60)
  let days = Math.floor(hours/24)
  let array = []
  if(days > 0 )array.push(days+"天");
  hours %= 24; 
  if(hours > 0 )array.push(hours+"时");
  minutes %= 60; 
  if(minutes > 0 )array.push(minutes+"分");
  seconds %= 60; 
  if(seconds > 0 )array.push(seconds+"秒");
  if(array.length == 0 ) array.push("<1秒");
  return array.join("");
}

console.log(formatUseTime(1000 * 60 * 30 + 1000 * 20))
console.log(formatUseTime(1001))
console.log(formatUseTime(1000 * 60 * 60 *24 + 10000))

image.png

node基础

模块系统

相对引用

编辑module_a.js

console.log("this is a")

编辑module_b.js

console.log("this is b")

引用这两个模块index.js

require('./module_a')
require('./module_b')

运行: node index
image.png

暴露API

编辑module_a.js

exports.name = 'john';
exports.data = 'this is some data';
var privateVariable = 5;
// 导出私有变量
exports.getPrivate = function () {
    return privateVariable;
}

编辑index.js

var a = require('./module_a')
console.log(a.name)
console.log(a.data)
console.log(a.getPrivate())

image.png

重写exports

编辑person.js

module.exports = Person
function Person(name) {
    this.name = name;
}
Person.prototype.talk = function () {
    console.log("我的姓名是", this.name);
}

编辑index.js

var Person = require('./person')
var john = new Person("john")
john.talk()

image.png

事件分发

var EventEmitter = require('events').EventEmitter;
var MyClass = function () { };
// 继承
MyClass.prototype.__proto__ = EventEmitter.prototype;

var a = new MyClass;
a.on('hello', function () {
    console.log("响应事件");
})
a.emit('hello');

buffer

const buf = Buffer.from('12345');
console.log(buf.toString('hex'));
console.log(buf.toString('base64'));
console.log(buf.toString('ascii'));
console.log(buf.toString('utf8'));

image.png

文件读取器

ANSI_escape_code

const fs = require('fs');
const path = require('path');
const stdin = process.stdin;
const stdout = process.stdout;

function showFile(fullpath) {
    stdin.pause();
    fs.readFile(fullpath, 'utf8', function (err, data) {
        console.log('');
        console.log('\033[90m' + data.replace(/(.*)/g, '  $1') + '\033[39m');
    })
}
function listFile(dir) {
    fs.readdir(dir, function (err, files) {
        console.log('');
        if (!files.length) {
            return console.log('  \033[31m No files to show!\033[39m\n');
        }
        console.log('  ls ' + dir + '\n');
        const cache = {};
        for (let i = 0; i < files.length; i++) {
            fs.stat(path.join(dir, files[i]), function (err, stat) {
                cache[i] = { name: files[i], stat: stat }
                if (stat.isDirectory()) {
                    console.log('  ' + i + '  \033[36m' + cache[i].name + '/\033[39m');
                } else {
                    console.log('  ' + i + '  \033[90m' + cache[i].name + '\033[39m');
                }
                // 注意: stat 是异步接口
                if (Object.keys(cache).length == files.length) {
                    console.log('');
                    stdout.write('  \033[33mEnter your choice: \033[39m');
                    stdin.resume();
                    stdin.setEncoding("utf8");
                    // 采用 once 代替 on,防止重复监听
                    stdin.once('data', handleReadInput);
                }
            })
        }
        function handleReadInput(data) {
            const value = data.trim()
            const obj = cache[Number(value)]
            // console.log('value => [' + value + ']')
            if (!obj) {
                stdout.write('  \033[31mEnter your choice: \033[39m');
                stdin.once('data', handleReadInput);
                return;
            }
            const { name, stat } = obj;
            if (stat.isDirectory()) {
                listFile(path.join(dir, name))
            } else {
                showFile(path.join(dir, name))
            }
        }
    })
}

listFile(__dirname)

image.png

监听文件

const fs = require('fs');
const path = require('path');
// 监听目录
const dir = process.cwd();
const files = fs.readdirSync(dir);
files.forEach(f => {
    // 监听所有的js文件
    if (/\.js$/.test(f)) {
        fs.watchFile(path.join(dir, f), function () {
            console.log(' - ' + f + ' changed!')
        })
    }
})

image.png

创建http服务

const http = require("http");
http.createServer(function(req,res){
    res.writeHead(200,{'Content-Type':'text/html'});
    res.end('<h1>Hello World</h1>');
}).listen(3000);

image.png

图片服务器

const http = require("http");
const fs = require("fs");
http.createServer(function(req,res){
    res.writeHead(200,{'Content-Type':'image/png'});
    const stream = fs.createReadStream('D:\\Data\\1.png');
    stream.on('data',data => res.write(data));
    stream.on('end',() => res.end());
    // 另一种写法,重定向流
    // stream.pipe(res);
}).listen(3000);

image.png