初识Nodejs | 青训营笔记

35 阅读4分钟

这是我参与「第四届青训营 」笔记创作活动的第4天

初识Nodejs

一个基于 Chrome V8 引擎 的 JavaScript 运行时环境

node js is all built around callbacks in order to implement an asynchronous behavior

后台进程处理占用时间长的东西,处理完毕后用回调通知主线程执行继续剩下的任务

image-20220718180137564

因为node只是个js运行时环境,所以,输入控制台输入node可以正常写js

image-20220718190133587

在js里面所有的文件都被当作是一个模块

ps:win+D 选择下一个被选择的语句

node运行环境里的操作

在运行环境里敲tab可以看到node自带的变量和环境

__ 代表之前的一项运行结果

String.或者之类的用tab可

简单使用

const fs = require("fs");
​
const textIn = fs.readFileSync("./txt/input.txt", "utf-8"); //读取文件的同步版本
​
console.log(textIn);
​
const textOut = `This is:${textIn}\nCreated on ${Date.now()}`;
fs.writeFileSync("./txt/output.txt", textOut);

异步

image-20220719112436169

fs.readFile("./txt/start.txt", "utf-8", (err, data1) => {    //读取文件的异步版本
  fs.readFile(`./txt/${data1}.txt`, "utf-8", (err, data2) => {   //读取的文件,编码,回调函数(包含读取错误的err和读取到的数据data2)
    fs.readFile("./txt/append.txt", "utf-8", (err, data3) => {
      console.log(data3);
      fs.writeFile("./txt/final.txt", `${data2}\n${data3}`, "utf-8", (err) => {
        console.log("your file has been written");
      });
    });
  });
});
console.log("will read file!");

服务端

const data = fs.readFileSync(`${__dirname}/dev-data/data.json`, "utf-8");
//这里用同步的因为是一开始只执行一次的代码
const dataObj = JSON.parse(data);
​
const server = http.createServer((req, res) => {
  const pathName = req.url;
  if (pathName === "/" || pathName === "/overview") {
    res.end("This is the OVERVIEW");
  } else if (pathName === "/product") {
    res.end("This is the PRODUCT");
  } else if (pathName === "/api") {
    res.writeHead(200, { "Content-type": "application/json" });
    res.end(data); //这里不写productData因为它是一个js对象
  } else {
    res.writeHead(404, {
      "Content-type": "text/html", //指定类型
      "my-own-header": "hello-world", //可以传递自己定义的信息
    });
    res.end("<h1>Page not found!</h1>");
  }
  //接收一个回调(请求req,响应res)
  // res.end("Hello from the server!");
});
server.listen(1234, "127.0.0.1", () => {   //监听端口号,监听默认的地址
  console.log("Listening to requests on port 1234");
});

__dirname和./ 的区别

__dirname返回当前js文件所在文件夹的路径, ./返回当前的工作目录,类似process.cwd()方法

但是当用require的时候,./还是代表当前js文件所在的文件夹的路径

// Include path module
var path = require("path");
​
// Methods to display directory
console.log("__dirname:    ", __dirname);
console.log("process.cwd() : ", process.cwd());
console.log("./ : ", path.resolve("./"));
console.log("filename: ", __filename);

假如路径是桌面,移动到父目录

键入node Desktop/index.js命令运行代码

image-20220719172948071

例:Node Farm

///////////////////////////////////////
//SERVER
const tempOverview = fs.readFileSync(
  `${__dirname}/templates/template-overview.html`,
  "utf-8"
);
const tempCard = fs.readFileSync(
  `${__dirname}/templates/template-card.html`,
  "utf-8"
);
const tempProduct = fs.readFileSync(
  `${__dirname}/templates/template-product.html`,
  "utf-8"
);
​
const data = fs.readFileSync(`${__dirname}/dev-data/data.json`, "utf-8");
//这里用同步的因为是一开始只执行一次的代码
const dataObj = JSON.parse(data); //把data转换成js对象
​
const replaceTemplate = (temp, product) => {
  let output = temp.replace(/{%PRODUCTNAME%}/g, product.productName);
  output = output.replace(/{%IMAGE%}/g, product.image);
  output = output.replace(/{%PRICE%}/g, product.price);
  output = output.replace(/{%FROM%}/g, product.from);
  output = output.replace(/{%UNTRIENTS%}/g, product.nutrients);
  output = output.replace(/{%QUANTITY%}/g, product.quantity);
  output = output.replace(/{%DESCRIPTION%}/g, product.description);
  output = output.replace(/{%ID%}/g, product.id);
​
  if (!product.organic)
    output = output.replace(/{%NOT_ORGANIC%}/g, "not-organic");
​
  return output;
};
​
const server = http.createServer((req, res) => {
  const { query, pathname } = url.parse(req.url, true); //解构赋值
  //url.parse 将url字符串转成对象并返回 parse就是字符串转对象
​
  //Overview Page
  if (pathname === "/" || pathname === "/overview") {
    res.writeHead(200, { "Content-type": "text/html" });
​
    const cardsHtml = dataObj
      .map((el) => replaceTemplate(tempCard, el))
      .join("");
    console.log(cardsHtml);
    const output = tempOverview.replace("{%PRODUCT_CARDS%}", cardsHtml);
    res.end(output);
​
    //Product Page
  } else if (pathname === "/product") {
    // console.log(query);
    res.writeHead(200, { "Content-type": "text/html" });
    const product = dataObj[query.id];
    const output = replaceTemplate(tempProduct, product);
​
    res.end(output);
​
    //API
  } else if (pathname === "/api") {
    res.writeHead(200, { "Content-type": "application/json" });
    res.end(data); //这里不写productData因为它是一个js对象
​
    //Not Found
  } else {
    res.writeHead(404, {
      "Content-type": "text/html", //指定类型
      "my-own-header": "hello-world", //可以传递自己定义的信息
    });
    res.end("<h1>Page not found!</h1>");
  }
  //接收一个回调(请求req,响应res)
  // res.end("Hello from the server!");
});
server.listen(1234, "127.0.0.1", () => {
  console.log("Listening to requests on port 1234");
});

Parsing Variables from URLs

const { query, pathname } = url.parse(req.url, true); //解构赋值

url.parse 将url字符串转成对象并返回

其实只看parse就行,parse是字符串转对象

后面跟的布尔值参数:

默认的是false

默认为false,//foo/bar 形式的字符串将被解释成 { pathname: ‘//foo/bar' }

如果设置成true,//foo/bar 形式的字符串将被解释成 { host: ‘foo', pathname: ‘/bar' }

npm

node自带npm

npm有两种类型的包:

regular dependencies:写的代码需要用到这些包里面提前写好的东西

npm install slugify --save  //save可以不写

生成更易读的url代码

关于用法在npm上面找即可

slugify('some string', {
  replacement: '-',  // replace spaces with replacement character, defaults to `-`  //把空格替换成什么
  remove: undefined, // remove characters that match regex, defaults to `undefined`
  lower: false,      // convert to lower case, defaults to `false`
  strict: false,     // strip special characters except replacement, defaults to `false`
  locale: 'vi',       // language code of the locale to use
  trim: true         // trim leading and trailing replacement chars, defaults to `true`
})

development dependencies: 开发的时候用,项目完成的时候就不需要了

npm install nodemon --save-dev

写node的时候更改代码自动刷新

使用:

nodemon index.js

全局安装

npm i nodemon -g

没有全局安装的包如何使用:

没有全局安装的包不能直接在命令行使用,想要使用本地安装的包可以在package.json写命令

"scripts": {
    "start": "modemon index.js"  //自己写
  },

Package Versioning and Updating

1.3.4 主要版本 次要版本 补丁版本

主要版本破坏性更新,次要版本引入新的功能,和之前的次要版本兼容,补丁版本是修复bug的版本

查看过时版本

npm outdated

只查看过时的补丁版本

//在package.json的配置文件里面把版本号前面的^换成~
"dependencies": {
    "slugify": "~1.6.5"
  },
​
npm outdated  //就只会查带~的补丁版本了
* 是所有版本,包括主要版本,
^ 是所有次要版本
~ 是所有补丁版本

安装指定版本

npm install slugify@1.0.0

分享代码的时候是不用分享node_modules里面的东西的,在另外一个系统上面运行需要把node_modules里面的依赖重新装一边,使用:

npm install

\