模块化common.js 规范
文件ma.js
console.log("ma模块");
let a = 10;
class Person {
constructor() {
this.name = "LC";
}
hobby() {
console.log("喜欢动画");
}
}
导出与导出
module.exports = {}
module.exports = {
a,
Person,
};
exports.
exports是module.exports的引用,module.exports = exports
exports.a = a;
exports.Person = Person;
导入
在index.js
文件中调用其他文件的导出
let Ma = require("./ma.js");
console.log(Ma.a)
let lc = new Ma.Person();
console.log(lc.name)
lc.hobby();
目录模块化
- home目录下有
index.js
/a.js
/b.js
三个文件 - 其中a,c都是需要导出的模块
- 为了方便,可以现在index里面导入模块a和b
- 再从外部直接导入home这个目录,就会默认自动导入home下的index文件
require("./home");
默认模块文件
- 在相对目录下新建一个
node_modules
文件 - 然后在这个文件下建立目录模块
- 导入时只需要导入
node_modules
文件下的目录名就行了,不需要加前缀路径,
导出
目录结构
外部index.js
调用node_modules
文件下的模块
JSON配置(描述与功能)
固定命名配置文件package.json
参数:
- main,模块目录的默认入口文件,原来默认为
index
{
"name": "myTest",
"version": "1.0",
"main": "main.js"
}
内置模块
http模块是内置模块,不需要自定义,本身存在于nodejs中
例如
Buffer,C/C++Addons,Child Processes,Cluster,Console,Crypto,
Debugger,DNS,Domain,Errors,Events,File System,
Globals,HTTP,HTTPS,Modules,Net,OS,Path,Process,
P unycode,Query Strings,Readline,REPL,Stream,
String De coder,Timers,TLS/SSL,TTY,UDP/Datagram,
URL, Utilities,V8,VM,ZLIB
内置模块不需要安装,外置模块需要安装;
npm包管理工具
通过npm管理第三方模块
登录与发布
-
注册账号:https://www.npmjs.com/ (邮箱验证)
-
npm adduser 输入刚刚注册好的用户名和密码 ;
如果注册地址不对需要重新改回来:
npm config set registry https://registry.npmjs.org/
(官方地址)https://registry.npm.taobao.org/
(淘宝源地址)查询源地址
npm config list
发布
- npm publish 命令
- npm version major | minor | patch 命令
npm版本管理工具 mvn
NVM 常用指令;
nvm --version查看版本
nvm install stable //安装最新稳定版nodejs
nvm install 8.11.1 //安装指定版本
nvm install 8.11 //安装 8.11.x系列最新版本
nvm ls-remote //列出远程服务器上所有可用的版本
nvm use 8.11.1 //切换到8.11.1版本
nvm use 8.11 //切换到8.11.x最新版本
nvm use node //切换到最新版本
nvm alias default node //设置默认版本为最新版本
nvm ls //列出所有已经安装的版本
npm常用指令;
npm init
:引导创建一个package.json文件npm help(npm -h)
:查看npm帮助信息npm version (npm -v)
: 查看npm版本;npm search
:查找npm install (npm i)
:安装 默认在当前目录,如果没有node_modules 会创建文件夹;npm install module_name -S
或者–save 即 npm install module_name --save 写入dependenciesnpm install module_name -D
或者 —save-dev 即 npm install module_name --save-dev 写入devDependenciesnpm install module_name -g
全局安装(命令行使用)- 指定版本安装模块 npm i module_name @1.0 通过 "@"符号指定;
- npm update(npm -up):更新
- npm remove 或者 npm uninstall:删除
- npm root 查看当前包安装的路径 或者通过 npm root -g 来查看全局安装路径;
package.json 配置参数
依赖
- dependencies 运行依赖
通过npm i 安装的三方库就会放到这里,删除也就会消失
- devDependencies 开发依赖
通过npm i axios --save-dev命令安装的三方库则会放到这里
开发依赖和运行依赖的区别
- 开发依赖知识开发的时候需要用到,但是正式上线,跑代码的时候不需要用
例如:sass,less等css预编译工具
安装命令:npm i axios -S
- 运行依赖则两种都需要用
例如:jQuery
命令:npm i axios -D
依赖的好处
上传文件给别人使用时只需要上传这个配置文件
然后别人通过命令npm i
自动下载配置文件中的所有依赖
node_modules特性
会从相对路径开始,依次往上层文件查找node_modules
文件
最终会找到全局目录
全局安装与局部安装
-g,会安装到npm root -g
所示目录下,所有项目都可使用这个目录下的三方模块
指定版本安装
通过@指定版本
npm i jquery@3.4.1
常用内置模块
fs 模块
文件操作
1. 文件写入
let fs = require("fs");
//flag配置 "a":追加写入,"w":写入,"r":读取
fs.writeFile("2.txt","我是要写入的内容",{flag:"w"},err=>{
if(err){
return console.log(err);
}
console.log("写入成功");
})
2. 文件读取
fs.readFile("1.txt", "utf8", (err, data) =>{
if (err) {
return console.log(err)
}
console.log(data)
})
当不加utf8
编码时会打印出node文件的二进制
这个时候可以通过toString
方法转换为字符串
console.log(data.toString())
异步操作
所有文件操作没有加上Sync
就都是异步,否则是同步
let data = fs.readFileSync("1.txt");
console.log(data.toString())
同步操作没有回调直接返回
3. 文件修改
fs.rename("1.txt", "2.txt", err => {
if (err) {
return console.log(err);
}
console.log("文件名修改成功");
});
4. 文件删除
fs.unlink("2.txt", err => {
if (err) {
return console.log(err);
}
console.log("删除成功");
});
5. 文件复制
fs.copyFile("1.txt", "myTxt.txt", err => {
if (err) {
return console.log(err);
}
console.log("复制成功");
});
自己实现的思路:先读取,再写入
function myCopy(src, dest) {
fs.writeFileSync(dest, fs.readFileSync(src));
}
myCopy("myTxt.txt", "2.txt");
目录操作
// 创建
fs.mkdir("myDir", err => {
if (err) {
return console.log(err);
}
console.log("创建成功");
});
// 修改目录名
fs.rename("myDir", "newDir", err => {
if (err) {
return console.log(err);
}
console.log("修改成功");
});
// 读取目录
fs.readdir("newDir", (err, data) => {
if (err) {
return console.log(err);
}
console.log(data);
});
// 删除空目录
fs.rmdir("newDir", (err) => {
if (err) {
return console.log(err);
}
console.log("删除成功");
});
删除非空目录
- 先删除目录下的所有文件
- 删除这个空目录
- 如果里面还有非空目录则向下递归执行
function removeDir(path) {
let data = fs.readdirSync(path);
for (let i = 0; i < data.length; i++) {
let url = path + "/" + data[i];
let stat = fs.statSync(url);
if (stat.isDirectory()) {
removeDir(url);
} else {
fs.unlinkSync(url);
}
}
fs.rmdirSync(path);
}
removeDir("newDir");
文件目录通用方法
1 判断是否存在
fs.exists("myTxt.txt", exists => {
console.log(exists);
});
2 获取详细信息
fs.stat("newDir", (err, stat) => {
if (err) {
return console.log(err);
}
console.log(stat);
});
可用于判断是文件还是目录
let res = stat.isFile();
let res = stat.isDirectory();
console.log(res)
buffer缓冲区
let buffer = Buffer.alloc(10)
let buffer = Buffer.from("hello world");
let buffer = Buffer.from([0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64]);
console.log(buffer);
console.log(buffer.toString());
拆分转换乱码
let buffer1 = Buffer.from([0xe4, 0xbd, 0xa0, 0xe5]);
let buffer2 = Buffer.from([0xa5, 0xbd, 0xe4, 0xb8, 0x96, 0xe7, 0x95, 0x8c]);
console.log(buffer1.toString());
通过拼接解决
let newBuffer = Buffer.concat([buffer1, buffer2])
console.log(newBuffer.toString());
性能更高的方式
let buffer1 = Buffer.from([0xe4, 0xbd, 0xa0, 0xe5]);
let buffer2 = Buffer.from([0xa5, 0xbd, 0xe4, 0xb8, 0x96, 0xe7, 0x95, 0x8c]);
let {StringDecoder} = require("string_decoder");
let deCoder = new StringDecoder();
let res1 = deCoder.write(buffer1);
let res2 = deCoder.write(buffer2);
console.log(res1, res2)
此方法会自动保存多余的二进制码,然后下次调用时补在前面
stream流
当文件特别大时,会导致内存溢出
steam会将文件切割为多个小块,依次传输,不停循环去发送存储
// 创建一个65kb大小的文件
const fs = require("fs");
let buffer = Buffer.alloc(65 * 1024);
fs.writeFile("65kb", buffer, { flag: "w" }, err => {
if (err) {
return console.log(err);
}
console.log("写入成功");
});
let cnt = 0;
let res = fs.createReadStream("65kb");
res.on("data", chunk => {
cnt++;
// console.log(chunk);
console.log(cnt);
});
每次分64kb的小块传输
监听读取完成
res.on("end", () => {
console.log(str);
});
管道
每次读取的内容通过管道依次存入另一个文件中
let res = fs.createReadStream("1.txt");
let ws = fs.createWriteStream("2.txt");
res.pipe(ws);
通过fs模块搭建简易服务器
http模块
const http = require("http");
const server = http.createServer((req, res) => {
res.write("hello,kkb");
res.end();
console.log(req.url);
});
server.listen(8080);
fs模块渲染html文件
利用stream流以读取,以及pipe管道传输
const http = require("http");
const fs = require("fs");
const server = http.createServer((req, res) => {
// res.write("hello,kkb");
res.setHeader("content-type", "text/html;charset=utf-8");
const readStream = fs.createReadStream("./index.html");
readStream.pipe(res);
});
server.listen(8080);
渲染css文件
所有文件都是通过req.url
的路径拼接而拿到的
path.extname() 方法获取文件后缀
const extname = path.extname(req.url);
console.log(extname)
通过预定义好的mime.json文件获取文件类型
const http = require("http");
const fs = require("fs");
const path = require('path');
const mimeData = require('./mime.json');
const server = http.createServer((req, res) => {
res.setHeader("content-type", "text/html;charset=utf-8");
if (req.url === "/") {
const readStream = fs.createReadStream("./index.html");
readStream.pipe(res);
}
else {
const extname = path.extname(req.url);
console.log(req.url, extname);
const mimeType = mimeData[extname];
res.setHeader("content-type", `${mimeType};charset=utf-8`);
console.log(req.url);
const css = fs.readFileSync("." + req.url);
res.end(css);
}
});
server.listen(8080);
不同路由的不同渲染
else if (req.url === "/detail") {
const readStream = fs.createReadStream("./detail.html");
readStream.pipe(res);
}