npm 和 node 基础
npm
相信现在的前端同学每天都在接触 npm 这个命名吧,也经常在使用 npm 去构建项目,安装包,但其实 npm 不仅仅知识初始化项目的安装包
1.基本的快捷方式
特别常见的一些快捷键
- 安装 --
npm install--->npm i - 卸载 --
npm uninstall--npm un - 测试 --
npm test--->npm t - 帮助 --
npm --help--->npm -h - 全局标志
--global--->-g - 开发依赖
-save-dev--->-D - 生产依赖
--save--->-S npm init默认值 --npm init --yes||npm init --force--->npm init -y||npm init -f
解释一下
npm i <name>表示安装一个包但是不保存他 <======>npm i <name> --no-save
不是很常见的快捷键
- 将安装包的信息加到
package.json中的optionalDependencies(可选阶段的依赖)简写-O - 精准安装到制定版本 简写
-O
根的快捷方式
.符号通常便是根目录,npm 术语中的应用程序的入口,也就是package.json中所指定的值
2. 设置默认的 npm init 有哪些属性
当运行 npm init 来创建一个新项目时候,你会发现会输入比较多的配置信息,如果你需要的项目比较多的话,配置 npm init 的默认配置信息是有必要的,直接上方法吧
npm config set init.author.name "xuanliao"
npm config set init.author.email "1066788870@qq.com"
npm config set init.author.url "https://github.com/"
npm config set init.license "MIT"
检查是否将这些属性设置成功,可以使用命令 npm config edit 来查看,也可以找到配置文件来查看和修改,如果是想编辑全局的 config 文件可以直接 npm config edit -g 来查看和编辑
3. 让脚本跨平台兼容
任何命令行上的代码,都有兼容性的风险,特别是在windows和unix系统(包括Mac和Linux)之间,如果是当人开发,单台机器那肯定是没有问题,当是大多数时候都是多个人一个项目组联合开发,就必须要做一个项目兼容的问题了,不过好在 nodeJS 中有模块还是很好用的---cross-env,安装不用多说npm i -D cross-env使用如下
{
"scripts": {
"build": "cross-env NODE_ENV=production webpack --config build/webpack.config.js"
}
}
cross-env实现跨平台兼容性的最无缝的方法
rimraf可以安装在全球运行跨平台脚本
ShellJs是 Unix shell 命令在 Node.js API 上的可移植实现。
4. 并行运行脚本
可以使用&&来依次运行两个和多个脚本,但运行起来还是用一定的时间差的,如果说我们想要去并行这其中的几个脚本呢,有点同步异步的意思哈,目前有两种比较流行的解决方案,concurrent和npm-run-all
首先安装是免不了的 npm i concurrently -D
添加脚本
{
"scripts": {
"a": "concurrently \"node a2\" \"node a3\" \"node a1\""
}
}
注意写法
5. 在不同的目录中运行脚本
如果在不同文件夹下面需要同事运行脚本,我们可以使用 cd 来完成
{
"scripts": {
"a": "concurrently \"node a2\" \"cd a && node a3\" \"cd a && node a1\""
}
}
这样完成是可以,但就是有点 low,如何让其优雅起来呢?
我们可以使用--prefix来指定路径
{
"scripts": {
"a": "concurrently \"node a2\" \"npm start --prefix a\""
}
}
注意这种写法必须要有 package.json
6. 延迟运行脚本知道端口准备就绪
通常,在后端使用 nodeJS 书写的时候,坑定是希望同事启动服务端和客户端的,wait-on节点模块提供了一种方便的方法来确保旨在某些进程就绪时候发生,有一种简单的理解,在 nodeJS 中的项目起来之后,再起前端的项目
todo:nodeJS 的东西我自己本身还没有系统的学习过,等我用到前后端项目的会,会考虑使用wait-on的
7. 列出并选择可用脚本
在实际开发过程中我们常常需要起多个项目,但又不想开多个 vscode 窗口,起项目可以使用 concurrently,或者通过 ntl 来查看并且运行
npm i -g ntl
跳到目录相面直接 ntl 就可以看到package.json中的scripts有哪些并且可以选择运行这些脚本,这样是不是方便了很多呢
8. 关于 package.json 中的 version
我们在研发过程中肯定是需要版本迭代的,下面的两个命令可以帮助我们
npm version patch 在最后一位+1
npm version major 在第一位+1
9. 命令行直接编辑 package.json
npm i -g json
json -I -f package.json -e 'this.scripts.a=\"node a1\"'
参数解释
-I就地编辑
-f强制修改
这样可以直接在命令行编辑 package.json 里面的所有信息
10 自动设置和打开 github 库
如果package.json文件中有repository,则可以通过输入 npm repo在默认浏览器中打开它。
如果你的项目已经连接到远程存储库,并且已经在命令行上安装了 git,那你可以使用这个命令找到你的连接存储库
git config --get remote.origin.url
更好的解决方案是可以使用如下脚本
json -I -f package.json -e "this.repository=\"$(git config --get remote.origin.url)\""
11. 自定义npm init脚本
- 找到 npm 所在的目录建立一个
.npm-init.js文件
确保.npm-init.js被指向正确
-
npm config set init -module ~\.npm-init.js -
编写
.npm-init.js
module.exports = {
name: prompt("package name", basename || package.name),
version: prompt("version", "1.0.0"),
decription: prompt("description", "这是npm自定义的文件"),
main: prompt("entry point", "index.js"),
repository: prompt("git repository", "https://github.com/0227vera"),
keywords: prompt(function (s) {
return s.split(/\s+/);
}),
author: prompt("author", "xuanliao <1066788870@qq.com>"),
license: prompt("license", "ISC"),
};
之后的这个文件可以修改和删除
12. 使用自定义 npm init 脚本将第一个 commit 提交到 github
为了将 git 命名合并到.npm-init.js文件中,需要一种方法来控制命令行,可以使用child_process模块,在文件中引入它,但是我们只需要execSync函数
const {execSync} = require('child_process')
修改刚才的.npm-init.js
const { execSync } = require("child_process");
let run = (func) => {
console.log("-------->", execSync(func).toString());
};
module.exports = {
name: prompt("package name", basename || package.name),
version: prompt("version", "1.0.0"),
decription: prompt("description", "这是npm自定义的文件"),
main: prompt("entry point", "index.js"),
keywords: prompt(function (s) {
return s.split(/\s+/);
}),
author: prompt("author", "xuanliao <1066788870@qq.com>"),
license: prompt("license", "ISC"),
repository: prompt("git repository url", "", (url) => {
if (url) {
run("git init");
run("git add .");
run('git commit -m "first commit"');
run(`git remote add origin ${url}`);
run("git push -u origin master");
}
return url;
}),
};
这个还是比较秀的,可以反杀一波
13. mac上面npm权限的问题
sudo chown -R $USER /usr/local
node
这一部分的学习,只要是想先学习一些基础的东西,能够简单的完成一个网站
http
使用 http 起一个服务
const http = require("http");
const server = http.createServer((req, res) => {});
server.listen(8080);
fs
全称:File System
const fs = require('fs');
fs.readFile('地址', (err, data) => {
if (err) {new Error err}
console.log(data)
})
fs.writeFile('地址', '内容', (err, data) => {
if (err) new Error(err)
})
get 请求的数据处理
const urlLib = require("url");
const http = require("http");
const server = http.createServer((req, res) => {
const obj = urlLib.parse(req.url, true);
const url = obj.pathname;
const GET = obj.query;
});
server.listen(8080);
post 请求的数据处理
const querystring = require("querystring");
const http = require("http");
const server = http.createServer((req, res) => {
let str = "";
req.on("data", (data) => {
str += data;
});
req.on("end", () => {
const POST = querystring.parse(str);
});
});
server.listen(8080);
文件上传的数据处理
multer:
const express = require("express");
let server = express();
server.listen(8080);
const multer = require("multer");
const objMulter = multer({
dest: "./www/upload/",
limit: 2 * 1024 * 1024, // 文件大小
});
server.use(objMulter.any()); // 可以接收任何类型,任何数量的
server.use("/upload", (req, res) => {
console.log(req.files);
// 然后用fs.rename()重命名把文件类型加上
});
模块化
- 系统模块: http、 querystring、 url、 Crypo(加密)、 Events(事件)、 OS(操作系统的相关信息)、 Path(路径相关)、 Net(网络操作)、 Stream(流操作)、 Timers(定时器)、 ZLIB(压缩) 等
- 自己写模块:(CMD 规范)
// 抽取的模块 module.js
module.exports = () => {
var name = "salvatore";
this.changeName = (changeName) => {
name = changeName;
};
this.getName = () => {
return name;
};
this.setName = (newname) => {
name = newname;
};
return this;
};
// 使用模块
const module = require("./module.js");
express 框架
const express = require("express");
const server = express();
// post数据使用,中间件
const bodyParser = require("body-parser"); // 只能解决数据类的东西
server.use(
bodyParser.urlencoded({
extended: false, // 扩展,true--->启用扩展模式
limit: 2 * 1024, // 限制2M,默认是100K
})
);
server.use("路径", (req, res, next) => {
// use = post or get
// get数据
const get = req.query;
// post数据 body-parser
const post = req.body;
req.test = 3;
next();
});
server.use("和上面相同的路劲", (req, res, next) => {
console.log("和上面的形成链式操作", res.test); // 3
res.send("aaa");
res.end();
});
server.listen(8080);
中间键
express-static
const static = require("express-static");
const express = require("express");
const server = express();
server.listen(8080);
server.use(static("./www"));
cookie、session 以及加签名的问题的问题
const secret = "aghahgaljdsfhajgha";
const cookieParser = require("cookie-parser");
const cookieSession = require("cookie-session");
const express = require("express");
const server = express();
const keys = ["qqq", "www", "eee"]; // session的密钥
server.use(cookieParser(secret));
server.use(
cookieSession({
keys,
name: "sess", // session的名字
maxAge: 20 * 60 * 1000, // 过期时间
})
); // 放在cookie后面
server.use("路径", (req, res, next) => {
// cookie的发送
// req.secret = secret // cookie的一个密钥
res.cookie("key", "value", {
path: "/aaa",
maxAge: 30 * 24 * 60 * 60 * 1000, // ms为单位
signed: true, // 添加签名
});
// cookie的读取
// 签名的cookies
console.log("签名cookies--->", res.signedCookies);
// 没有签名的cookies
console.log("没有签名cookies--->", req.cookies); // 可以访问底下的,不能向上访问
// 删除cookie,某一条cookie
res.clear("key");
// session 的读取
console.log(req.session);
// 删除session
delete req.session; // delete删除的是服务器上面的东西
res.send("ok");
res.end();
});
server.listen(8080);
route 路由的问题
// server.js
const express = require("express");
const userRouter = require("./userRouter");
let server = express();
server.listen(8080);
server.use("/user", userRouter);
// userRouter.js
const express = require("express");
module.exports = () => {
const router = express.Router();
router.get("/login", (req, res) => {
// 做登陆的操作
});
router.get("/register", (req, res) => {
// 做注册的操作
});
return router;
};
SQL 的问题
const mysql = require("mysql");
let db = mysql.createConnection({
// 连接
host: "localhost",
port: "3306",
user: "root",
password: "root",
database: "newtest",
});
// mysql.createPool() 连接池
// 2,查询 (curd) 非常典型的异步操作,肯定会有回调函数
db.query("SELECT * FROM `user_table`;", (err, data) => {
if (err) {
throw err;
} else {
console.log("--------->", JSON.stringify(data));
}
});