npm、node基础

179 阅读7分钟

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. 让脚本跨平台兼容

任何命令行上的代码,都有兼容性的风险,特别是在windowsunix系统(包括MacLinux)之间,如果是当人开发,单台机器那肯定是没有问题,当是大多数时候都是多个人一个项目组联合开发,就必须要做一个项目兼容的问题了,不过好在 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. 并行运行脚本

可以使用&&来依次运行两个和多个脚本,但运行起来还是用一定的时间差的,如果说我们想要去并行这其中的几个脚本呢,有点同步异步的意思哈,目前有两种比较流行的解决方案,concurrentnpm-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脚本

  1. 找到 npm 所在的目录建立一个.npm-init.js文件

确保.npm-init.js被指向正确

  1. npm config set init -module ~\.npm-init.js

  2. 编写.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()重命名把文件类型加上
});

模块化

  1. 系统模块: http、 querystring、 url、 Crypo(加密)、 Events(事件)、 OS(操作系统的相关信息)、 Path(路径相关)、 Net(网络操作)、 Stream(流操作)、 Timers(定时器)、 ZLIB(压缩) 等
  2. 自己写模块:(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));
  }
});

资料跳转