Node.js是基于Chrome V8引擎的JavaScript运行环境,可以在服务器端运行JavaScript代码。它提供了高效、轻量级的事件驱动I/O模型和非阻塞式I/O操作,使得开发者能够快速构建可扩展的网络应用程序
Yarn
npm i -g yarn
yarn --version
yarn init - 初始化新项目并创建 package.json 文件
yarn add [package] - 将一个或多个包添加到项目中
yarn remove [package] - 从项目中移除一个或多个包
yarn install - 安装项目中所有依赖项
yarn upgrade [package] - 更新一个或多个包至最新版本
yarn run [script] - 运行在 package.json 中定义的脚本
yarn build - 执行构建命令以生成生产环境所需的文件
yarn start - 启动应用程序或服务器
yarn test - 运行测试套件
文件读写
let fs = require('fs')
/**
* 读取数据
*/
function readFile(path) {
try {
return fs.readFileSync(path, { encoding: 'utf-8' })
} catch (e) {
return ''
}
}
/**
* 写入数据
*/
function writeFile(path, content) {
fs.writeFileSync(path, content)
}
开启HTTP服务
var http = require('http')
/**
* 运行服务
*/
function runServer() {
// 启动前梳理一遍排序
neatenSort()
// 项执行一遍目录生成,防止没有文件进行访问
startGenerate()
// 需要访问的文件的存放目录(项目所在位置的文件夹路径)
var documentRoot = './target'
// 启动服务
http.createServer(function (req, res) {
var url = req.url
if (url == '/' || url == '/article' || url == '/article/**') {
url = '/index.html'
}
var file = documentRoot + url
fs.readFile(file, function (err, data) {
if (err) {
res.writeHeader(404, {
'content-type': 'text/html;charset="utf-8"'
})
res.write(readFile('404.html'))
} else {
// 请求头设置
// html的请求头 Content-Type : text/html ; charset=utf-8
// CSS的请求头 content-type: text/css; charset=utf-8
// JavaScript的请求头 content-type: text/javascrpt; charset=utf-8
let contentType = 'text/html;charset="utf-8"'
if (url.indexOf('.css') > -1) {
contentType = 'text/css;charset=utf-8'
} else if (url.indexOf('.js') > -1) {
contentType = 'application/javascript;charset=utf-8'
} else if (url.indexOf('.svg') > -1) {
contentType = 'image/svg+xml;charset=utf-8'
}
res.writeHeader(200, {
'content-type': contentType
})
res.write(data)
}
res.end()
})
}).listen(7981)
// 监听文件变化,由于监听了所有子文件,所以一次改动会刷新多次,解决办法为限时刷新,即同一时间内只允许刷新一次
// 这里注意:VSCode的自动保存会定时触发,也就是开启后这里会每隔一段时间就刷新一次,建议不要使用自动保存,而是手动保存,触发文件动态刷新
let tempTimer = 0
let number = 1
fs.watch('./docs', { recursive: true }, (eventType, filename) => {
let timer = new Date().getTime()
if (timer - tempTimer > 2000 && eventType == 'rename') {
// 监听文件名称改动,进行排序整理和重新生成
setTimeout(() => {
// 延时执行,避免编辑器打开新建文件立刻执行更名操作的异常问题
console.log('A file or directory is renamed: ' + filename + ', resort');
neatenSort()
startGenerate()
}, 500);
tempTimer = timer
} else if (timer - tempTimer > 2000 && eventType == 'change') {
// 监听文件改动,重新生成
console.log('A file is changed: ' + filename + ' > ' + (number++));
startGenerate()
tempTimer = timer
}
})
console.log('Service started successfully, url is http://localhost:7981/')
// 控制台输入
readCommand()
}
文件夹复制
/**
* 文件夹复制(递归支持下级目录)
*/
function cpSync(source, destination) {
let major = process.version.match(/v([0-9]*).([0-9]*)/)[1]
let minor = process.version.match(/v([0-9]*).([0-9]*)/)[2]
// 判断node版本不是16.7.0以上的版本
// 则进入兼容处理
// 这样处理是因为16.7.0的版本支持了直接复制文件夹的操作
if (Number(major) < 16 || Number(major) == 16 && Number(minor) < 7) {
// 如果存在文件夹 先递归删除该文件夹
if (fs.existsSync(destination)) fs.rmSync(destination, { recursive: true })
// 新建文件夹 递归新建
fs.mkdirSync(destination, { recursive: true })
// 读取源文件夹
let rd = fs.readdirSync(source)
for (const fd of rd) {
// 循环拼接源文件夹/文件全名称
let sourceFullName = source + "/" + fd
// 循环拼接目标文件夹/文件全名称
let destFullName = destination + "/" + fd
// 读取文件信息
let lstatRes = fs.lstatSync(sourceFullName)
// 是否是文件
if (lstatRes.isFile()) fs.copyFileSync(sourceFullName, destFullName)
// 是否是文件夹
if (lstatRes.isDirectory()) cpSync(sourceFullName, destFullName)
}
} else {
fs.cpSync(source, destination, { force: true, recursive: true })
}
}