Nodejs
Nodejs
搭建环境
使用仓库安装
apt-get install nodejs从官网下载安装
- 下载并解压
cd /opt
curl -O https://nodejs.org/dist/v16.15.0/node-v16.15.0-linux-x64.tar.xz
tar -xvf node-v16.15.0-linux-x64.tar.xz - 设置环境变量
- 设置全局环境变量
echo 'export PATH="$PATH:/opt/node-v16.15.0-linux-x64/bin"' >> /etc/profile 设置临时环境变量
export PATH="$PATH:/opt/node-v16.5.0-linux-x64/bin"
- 设置全局环境变量
- 注销并重新登录后即可生效
logout - 安装coffee script(可选)
npm install -g coffee-script
- 下载并解压
包管理工具
cnpm(使用国内淘宝源,速度较快)
- 安装 cnpm
npm install -g cnpm --registry=https://registry.npm.taobao.org - 使用 cnpm 代替 npm,如
cnpm install -g typescript
- 安装 cnpm
yarn
- 安装
npm install -g yarn - 配置淘宝源,用于加速
yarn config set registry 'https://registry.npm.taobao.org'
- 安装
npm
配置
通过 config 命令
- 查看当前配置内容
npm config ls
npm config list - 设置远程仓库地址(使用 taobao 源镜像加速)
npm config set registry https://registry.npm.taobao.org - 设置 npm 安装 package 的全局 node_modules 路径
npm config set prefix "E:\nodejs" - 设置代理服务器
npm config set proxy http://username:password@server:port
npm config set https-proxy http://username:password@server:port - 设置不校验 SSL 证书
npm config set strict-ssl false
- 查看当前配置内容
通过编辑配置文件 ~/.npmrc(或 nodejs 安装目录下的 node_modules/npm/.npmrc 或 node_modules/npm/npmrc 文件)
# 设置远程仓库地址 # registry = https://registry.npm.taobao.org # 设置 npm 安装 package 的全局 node_modules 路径 prefix = E:\nodejs
从 npm 默认远程仓库下载安装 uglify-js 到全局 node_modules 路径下(参数 “-g” 表示下载到全局 node_modules 路径下并安装到 node_modules 的上一级目录,这里即 nodejs 安装目录下)
npm install uglify-js -g从 npm 默认远程仓库下载安装 uglify-js 到当前路径下的 node_modules 目录中
npm install uglify-js
从 npm 远程仓库 “–registry https://registry.npm.taobao.org" 下载安装 uglify-jsnpm install uglify-js --registry https://registry.npm.taobao.org在当前目录下,初始化一个 node 工程
npm init安装依赖(package.json 中定义的依赖)
npm install
安装 express 并将依赖添加至 package.json 中
npm install express --save自定义运行
- 编辑 package.json 如下
"scripts": { "start": "electron ." } - 运行上一步骤中的 start 命令
npm run start
- 编辑 package.json 如下
第三方 nodejs 应用
快速搭建本地 http 服务器
# 安装 npm i -g http-server # 在当前目录下启动 http 服务器 http-server . # 在当前目录下启动 https 服务器 http-server \ -p 443 \ # 要使用的端口(默认为8080) -S \ # 启用 https -C server.crt \ # 证书文件的路径(默认值:cert.pem) -K server.key \ # 密钥文件的路径(默认值:key.pem) --cors \ # 通过 Access-Control-Allow-Origin 标题启用 CORS .使用 uglify-js 压缩 js 文件
- 安装 uglify-js
npm install -g uglify-js 压缩 js 文件 template.js 并将结果打印到控制台
uglifyjs template.js
使用 uglify-js 高度压缩(混淆变量名)js 文件 template.js,并保存到 文件 template.min.js 中
uglifyjs -m toplevel template.js -o template.min.js
- 安装 uglify-js
gitbook
- 安装 gitbook
npm install -g gitbook-cli - 在当前目录下,初始化一个 gitbook 工程
gitbook init - 构建
gitbook build
gitbook build --gitbook=2.6.72.6.7 版本支持离线 html 跳转链接
- 运行服务
gitbook serve
浏览器中访问 http://127.0.0.1:4000/ 即可浏览
- 安装 gitbook
docsify
- 安装 docsify
npm install -g docsify-cli - 在当前目录下,初始化一个工程
docsify init . - 运行服务
docsify serve .
浏览器中访问 http://127.0.0.1:3000/ 即可浏览
- 安装 docsify
node-rtsp-rtmp-server(RTSP/RTMP/HTTP hybrid server)
- 下载源码
git clone https://github.com/iizukanao/node-rtsp-rtmp-server.git - 安装依赖(需要nodejs版本 >= 0.12)
cd node-rtsp-rtmp-server
npm install -d - 安装 coffeescript
npm install -g coffeescript - 运行服务(服务配置见config.coffee)
- 直接使用coffee运行
coffee server.coffee 使用coffee编译后,使用nodejs运行
coffee -c .
node server.js
- 直接使用coffee运行
- 访问(192.168.1.200为服务器ip,80端口和1935端口号配置见config.coffee)
- 点播
- 复制媒体文件video.mp4到file目录下
- 访问
rtsp://192.168.1.200:80/file/video.mp4
rtmp://192.168.1.200/file/mp4:video.mp4
- 直播
- 使用ffmpeg推流
ffmpeg -re -i input.mp4 -c:v copy -c:a copy -f rtsp rtsp://192.168.1.200:80/live/video
ffmpeg -re -i video.mp4 -c:v copy -c:a copy -f flv rtmp://192.168.1.200/live/video - 访问
rtsp://192.168.1.200:80/live/video
rtmp://192.168.1.200/live/video
- 使用ffmpeg推流
- 点播
- 下载源码
-
- 运行当前目录下的工程
electron .
- 运行当前目录下的工程
electron-packager
- 打包成可执行程序
electron-packager . electron-quick-start
- 打包成可执行程序
grunt
npm install -g grunt grunt-electron-installer构建安装程序
在项目根目录下(即与 package.json 同级目录下),新建 Gruntfile.js 文件如下
var grunt = require("grunt"); grunt.config.init({ pkg: grunt.file.readJSON("package.json"), "create-windows-installer": { x64: { appDirectory: "./electron-quick-start-win32-x64", authors: "no one", exe: "electron-quick-start.exe", description:"electron-quick-start", } } }) grunt.loadNpmTasks("grunt-electron-installer"); grunt.registerTask("default", ["create-windows-installer"]);执行命令
grunt
使用 zan-proxy 代理服务器
npm install zan-proxy -g zan-proxy --no-update使用 whistle 代理服务器,浏览器可搭配使用 SwitchyOmega
npm install whistle -g w2 start使用 marp-cli 转换 markdown 为 ppt/pdf
npm install -g @marp-team/marp-cli marp-cli readme.md marp-cli readme.md -o readme.pptx marp-cli -p --server .增强 shell 脚本工具 zx
安装(依赖 node.js 需 ≥ 14.8 版本)
npm i -g zx示例
将编写的脚本放在 .mjs 后缀的文件中,或者使用 .js 后缀,但是需要 void async function () {…}() 对脚本进行包装
#!/usr/bin/env zx $.verbose = false; // 默认为 true。关闭打印所有命令以及输出 await $`cat package.json | grep name` let branch = await $`git branch --show-current` await $`dep deploy --branch=${branch}` await Promise.all([ $`sleep 1; echo 1`, $`sleep 2; echo 2`, $`sleep 3; echo 3`, ]) let name = "foo bar" await $`mkdir /tmp/${name}`执行脚本
# 执行远程脚本 zx https://medv.io/example-script.mjs
使用 ssh2 连接 sftp 服务器
安装
npm install ssh2示例
const { readFileSync } = require("fs"); const { Client } = require("ssh2"); const conn = new Client(); conn.on("ready", () => { console.log("SSH connection ready."); conn.sftp((err, sftp) => { if (err) throw err; // 读取 "./" 目录 sftp.readdir("./", (err, list) => { if (err) throw err; console.dir(list.map(f => f.filename)); conn.end(); // 退出 ssh 连接 }); // 读取文件内容 sftp.readFile("./webdav.txt", (err, buf) => { if (err) throw err; console.log(buf.toString("base64")); conn.end(); }); // 删除文件 sftp.unlink("./webdav.txt", (err) => { if (err) throw err; console.log("Delete file successfully."); conn.end(); }); // 下载 "./webdav.txt" 到本地当前目录下 sftp.fastGet("./webdav.txt", "./webdav.txt", (err) => { if (err) throw err; console.log("Download file successfully."); conn.end(); }); // 上传文件 sftp.fastPut("./package.json", "./package.json", (err) => { if (err) throw err; console.log("Upload file successfully."); conn.end(); }); }); }).on("error", (err) => { throw err; }).connect({ host: "127.0.0.1", port: 22, username: "sftpuser", // privateKey: readFileSync("~/.ssh/id_rsa"), password: "123456", // debug: function(s) { console.log(new Date(), s); } // 打开调试日志 });
使用 PEG.js 自定义 DSL 解析
安装
npm install -g pegjs编写语法文件,可参考在线语法设计
Expression = head:Term tail:(_ ("+" / "-") _ Term)* { return tail.reduce(function(result, element) { if (element[1] === "+") return result + element[3]; if (element[1] === "-") return result - element[3]; }, head); } Term = head:Factor tail:(_ ("*" / "/") _ Factor)* { return tail.reduce(function(result, element) { if (element[1] === "*") return result * element[3]; if (element[1] === "/") return result / element[3]; }, head); } Factor = "(" _ expr:Expression _ ")" { return expr; } / Integer / arr:Array "[" _ idx:Expression _ "]" { return arr[idx]; } Array = "[" _ "]" { return []; } // 空数组 / "[" head:(_ Integer _ ",")* tail:(_ Integer _) "]" { return head.concat([tail]) .map((element) => element[1]); } Integer "integer" = _ [0-9]+ { return parseInt(text(), 10); } _ "whitespace" = [ \t\n\r]*根据步骤二的语法文件(如 arithmetics.pegjs),生成 js 解析代码
pegjs arithmetics.pegjs # pegjs -o arithmetics-parser.js arithmetics.pegjs使用
const parser = require("./arithmetics"); parser.parse("2 * (3 + 4)"); parser.parse("[1,2][1] + 2");
使用 inliner 转换 web 页面到单个 html 文件中
- 安装
npm install -g inliner - 压缩
inliner https://www.baidu.com > baidu.html
- 安装
Snippets
-
process.memoryUsage(); // { // 单位:字节(byte) // rss: 34009088, // 常驻集大小, 是为进程分配的物理内存(总分配内存的子集)的大小,包括所有的 C++ 和 JavaScript 对象与代码 // heapTotal: 5455872, // V8 堆内存大小,包括已使用的和未使用的 // heapUsed: 3022072, // V8 已使用堆内存大小 // external: 1583051, // V8 管理的绑定到 Javascript 对象的 C++ 对象的内存使用情况 // arrayBuffers: 9399 // 分配给 ArrayBuffer 和 SharedArrayBuffer 的内存,包括所有的 Node.js Buffer。这也包含在 external 值中。当 Node.js 被用作嵌入式库时,此值可能为 0,因为在这种情况下可能无法跟踪 ArrayBuffer 的分配。 // } Socket(TCP&UDP)
- TCP
- 服务端
var net = require("net"); var server = net.createServer(); server.on("connection", function(socket) { socket.setEncoding("utf8"); socket.on("data", function(data) { console.log(data.toString()); }); socket.on("end", function() { console.log("end"); }); }); server.listen(8765, "127.0.0.1"); - 客户端
var net = require("net"); var client = new net.Socket(); client.setEncoding("utf8"); client.connect(8765, "127.0.0.1", function() { console.log("connect"); client.write("to server"); client.end("end"); }); client.on("data", function(data) { console.log("receive data from server"); });
- 服务端
- UDP
- 服务器
var dgram = require("dgram"); var server = dgram.createSocket("udp4"); server.on("message", function(msg, rinfo) { console.log(msg); var buf = new Buffer("测试"); server.send(buf, 0, buf.length, rinfo.port, rinfo.address); }); server.on("listening", function() { console.log("listen"); }); server.bind(12345, "127.0.0.1"); - 客户端
server.on("message", function(msg, rinfo) { console.log(msg); var buf = new Buffer("测试"); server.send(buf, 0, buf.length, rinfo.port, rinfo.address); });
- 服务器
- TCP
读取文件内容
var fs = require("fs"); fs.readFile("./services.txt", "utf-8", function(err, data) { if (err) throw err; console.info(data); });创建一个简单的 http 服务
var http = require("http"); var server = http.createServer(function(req, res) { res.writeHead(200, { "Content-Type": "text/html" }); res.end("<!DOCTYPE html><html lang=\"en\"><head><meta charset=\"UTF-8\"><title>greeting</title></head><body>hello, world</body></html>"); }); server.listen(8080, function() { console.log("Server is running at http://localhost:8080/"); });创建一个简单的 https 服务(双向认证)
# 生成 CA 自签名证书 openssl genrsa -out ca.key 4096 openssl req -new -x509 -days 7300 -key ca.key -subj "/C=CN/ST=JS/L=NJ/O=Sunke, Inc./CN=Sunke Root CA" -out ca.crt # 生成服务器证书 openssl req -newkey rsa:2048 -nodes -keyout server.key -subj "/C=CN/ST=JS/L=NJ/O=Sunke, Inc./CN=localhost" -out server.csr openssl x509 -sha256 -req -extfile <(printf "subjectAltName=DNS:localhost,IP:127.0.0.1") -days 365 -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt # cat server.crt ca.crt > server.b.crt # 生成客户端证书 openssl req -newkey rsa:2048 -nodes -keyout client.key -subj "/C=CN/ST=JS/L=NJ/O=/CN=" -out client.csr openssl x509 -sha256 -req -days 365 -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out client.crtconst https = require("https"); const fs = require("fs"); https.createServer({ key: fs.readFileSync("./server.key"), // passphrase: "123456", // server.key 加密秘钥 cert: fs.readFileSync("./server.crt"), ca: fs.readFileSync("./ca.crt"), requestCert:true, // 请求客户端证书 rejectUnauthorized: true // 如果请求的客户端没有来自信任 CA 颁发的证书,拒绝客户端的连接 }, (req, res) => { res.writeHead(200, { "Content-Type": "text/html" }); res.write("<!DOCTYPE html><html lang=\"en\"><head><meta charset=\"UTF-8\"><title>greeting</title></head><body>hello, world</body></html>"); res.end(); }).listen(8443, function() { console.log("Server is running at https://127.0.0.1:8443/"); });curl --cacert ./ca.crt --cert ./client.crt --key ./client.key https://127.0.0.1:8443sqlite
npm install sqlite3const sqlite3 = require("sqlite3"); const db = new sqlite3.Database("mydb.db");
node-webkit
创建项目(hello World)
- 创建页面文件 index.html
<!DOCTYPE html> <html> <head> </head> <body> <h1>Hello World!</h1> </body> </html> - 创建配置文件 package.json
{ "name": "helloworld", "main": "index.html" }
- 创建页面文件 index.html
运行
- 将index.html和package.json这两个文件压缩到一个zip压缩包里,命名为helloworld.zip
- 把helloworld.zip这个文件的扩展名改为nw,变为 helloworld.nw
- 之前得到的helloworld.nw这个文件就可以用nw.exe来执行了,直接把helloworld.nw拖到nw.exe上就可以了。
- 把helloworld.nw这个文件跟node-webkit的环境文件一起打包成一个可执行文件,打开windows的cmd,然后输入如下命令:
copy /b nw.exe+app.nw app.exe - 但我们大多数人想的是给用户一个exe文件,用户就可以使用了,不用再附带一些其他文件。需要一个软件叫Enigma Virtual Box,首先下载和安装这个软件,然后打开它。然后在Enter Input File Name那里输入我们的app.exe的路径,在Enter Output File Name那里填写我们要把打包出来的可执行文件输出到哪里。最后是把除app.exe外的其它文件拖入到Files那里,遇到提示的话默认就可以了。
- The nw.pak and icudt.dll must be shipped along with nw.exe, the former one contains important javascript lib files, and the latter one is a important network library.
- ffmpegsumo.dll are media library, if you want to use <video> and <audio> tag, or other media related features, you should ship it.
- libEGL.dll and libGLESv2.dll are used for WebGL and GPU acceleration, you had better ship them. And D3DCompiler_43.dll and d3dx9_43.dll as well if you want to make sure WebGL works on more hardware. These 2 files are from DirectX redistributable.
electron
环境搭建
- npm install electron
- npm install electron-packager –save-dev
- npm install electron-packager -g
创建项目(hello World)
创建目录helloworld
在helloworld目录下创建页面文件 index.html
<h1>Hello World!</h1>在helloworld目录下创建脚本文件 main.js
const {app, BrowserWindow} = require("electron"); let mainWindow; app.on("ready", () => { mainWindow = new BrowserWindow({ height: 600, width: 800 }); mainWindow.loadURL("file://" + __dirname + "/index.html"); });在helloworld目录下创建配置文件 package.json
{ "name": "helloworld", "version": "1.0.1", "main": "main.js" }
运行
electron .发布
electron-packager <sourcedir> <appname> --platform=<platform> --arch=<arch> [optional flags...]-
const electron = require("electron"); const app = electron.app; const path = require("path"); app.on("ready", function() { var protocol = electron.protocol; protocol.registerFileProtocol("atom", function(request, callback) { var url = request.url.substr(7); callback({path: path.normalize(__dirname + "/" + url)}); }, function(error) { if (error) console.error("Failed to register protocol") }); // protocol.interceptHttpProtocol("http", handler[, completion]); // 拦截 http 请求 });
express
安装 express
npm install express创建 app.js
const app = require("express")(); const bodyParser = require("body-parser"); app.use(bodyParser.json()); // for parsing application/json app.post("/greeting", function(req, res, next) { console.log(req.body); res.json(req.body); });运行
node app.js
node-fetch
安装
npm install node-fetch调用
const fetch = require("node-fetch"); fetch("https://www.baidu.com");代理访问
安装
npm install https-proxy-agent调用
const HttpsProxyAgent = require("https-proxy-agent"); fetch("https://www.baidu.com", { agent: new HttpsProxyAgent("http://192.168.0.1:5566") });