第1章 NodeJS
如果你是一个前端程序员,你不懂得像PHP、Python或Ruby等动态编程语言,然后你想创建自己的服务,那么Node.js是一个非常好的选择。如果你熟悉Javascript,那么你将会很容易的学会Node.js。
1.1 NodeJS简介
Node.js 是一个基于 Chrome V8 JavaScript 引擎 构建的开源、跨平台运行时环境。V8 引擎是即 Google Chrome 的核心。这使 Node.js 的性能非常出色。V8引擎允许开发者使用 JavaScript 编写服务器端代码,而不是仅仅局限于浏览器中的前端开发。
Node.js 是运行在服务端的 JavaScript,是一个事件驱动I/O服务端JavaScript环境,基于Google的V8引擎,V8引擎执行Javascript的速度非常快,性能非常好。
- NodeJS官网:https://nodejs.org/zh-cn
复制代码 1.2 NodeJS下载
打开官网中的下载页面,选择一个合适的版本下载安装包,然后双击安装:
安装过程:点击下一步…下一步…默认安装即可。- NodeJS历史版本下载:https://nodejs.org/dist/
复制代码 安装完毕后,打开cmd窗口,输入node -v查看node的版本。
1.3 Node基础入门
1.3.1 控制台输出
我们现在做个最简单的小例子,演示如何在控制台输出,创建文本文件demo01.js,代码内容:- var a=1;
- var b=2;
- console.log(a+b);
复制代码 我们在命令提示符下输入命令1.3.2 使用函数
创建文本文件demo02.js- function add(a,b){
- return a+b;
- }
- var c=add(100,200);
- console.log(c);
复制代码 命令提示符输入命令运行后看到输出结果为300
1.4 NodeJS模块化编程
模块是Node.js 应用程序的基本组成部分,文件和模块是一一对应的。换言之,一个 Node.js 文件就是一个模块,这个文件可能是JavaScript 代码、JSON 或者编译过的C/C++扩展。
将一个复杂的程序文件依据一定规则(规范)拆分成多个文件的过程称之为模块化,其中拆分出的每个文件就是一个模块 ,模块的内部数据是私有的,不过模块可以暴露内部数据以便其他模块使用。
创建文本文件demo03_01.js- exports.add=function (a,b){
- return a+b;
- }
复制代码 创建文本文件demo03_2.js- // 导入demo03_1模块,类似于Java中的对象
- var demo= require('./demo03_01');
- // 通过"对象名"调用方法
- console.log(demo.add(400,600));
复制代码 我们在命令提示符下输入命令结果为1000
1.5 NodeJS内置模块
Node.js 作为一个 JavaScript 的运行环境,其官方提供了非常多的的内置模块,这些内置模块就和Java中的核心API一样,为NodeJS提供了很多基础功能,我们可以通过require()将这些模块导入到当前的JS文件中。
- fs:文件系统模块。
- fs.writeFile(file, data[, options], callback):文件写入
- fs.readFile(path[, options], callback):读取文件
- fs.unlink(path, callback):删除文件
- fs.mkdir(path[, options], callback):创建文件夹
使用示例:- // 导入fs模块
- const fs = require('fs');
- fs.writeFile('./test01.txt', '学而时习之,不亦说乎', err => {
- //如果写入失败,则回调函数调用时,会传入错误对象,如写入成功,会传入 null
- if (err) {
- console.log(err);
- return;
- }
- console.log('写入成功');
- });
复制代码 1.5.1 fs模块
fs模块是nodejs中关于文件操作的模块。
语法:
- fs.writeFile(file, data[, options], callback):文件写入
- file 文件名
- data 待写入的数据
- options 选项设置 (可选)
- callback 写入回调
使用示例:- // 导入fs模块
- const fs = require('fs');
- var str = "北冥有鱼,其名为鲲。鲲之大,不知其几千里也。"
- fs.writeFile('./test01.txt', str, err => {
- //如果写入失败,则回调函数调用时,会传入错误对象,如写入成功,会传入 null
- if (err) {
- console.log(err);
- return;
- }
- console.log('写入成功');
- });
复制代码
- fs.readFile(path[, options], callback):读取文件
- path 文件路径
- options 选项配置
- callback 回调函数
使用示例:- //导入 fs 模块
- const fs = require('fs');
- // 读取的是字节
- fs.readFile('./test01.txt', (err, data) => {
- if(err) throw err;
- console.log(data);
- });
- // 安装编码来读取
- fs.readFile('./test02.txt', 'utf-8',(err, data) => {
- if(err) throw err;
- console.log(data);
- });
复制代码
- fs.unlink(path, callback):删除文件
- path 文件路径
- callback 操作后的回调
- const fs = require('fs');
- fs.unlink('./test01.txt', err => {
- if(err) throw err;
- console.log('删除成功');
- });
复制代码
- fs.mkdir(path[, options], callback):创建文件夹
- path 文件夹路径
- options 选项配置( 可选 )
- callback 操作后的回调
使用示例:- const fs = require('fs');
- // 创建文件夹
- fs.mkdir('./a1', err => {
- if(err) throw err;
- console.log('创建成功');
- });
- //递归创建
- fs.mkdir('./aa/b1/c1', {recursive: true}, err => {
- if(err) throw err;
- console.log('递归创建成功');
- });
复制代码
- fs.rmdir(path[, options], callback):删除文件夹
- path:文件夹路径
- options:选项配置( 可选 )
- callback:操作后的回调
使用示例:- const fs = require('fs');
- //删除文件夹
- fs.rmdir('./a1', err => {
- if(err) throw err;
- console.log('删除成功');
- });
- //递归删除文件夹
- fs.rmdir('./aa', {recursive: true}, err => {
- if(err) {
- console.log(err);
- }
- console.log('递归删除')
- });
复制代码 1.5.2 http模块
http模块是nodejs中有关于http协议的模块。
(1)创建HTTP服务:- // 1. 导入http模块
- const http = require('http');
- /**
- * 2. 创建http服务
- * request:请求对象
- * response:响应对象
- */
- const server = http.createServer((request, response) => {
- response.end('Hello HTTP server');
- });
- // 3. 监听端口, 启动服务
- server.listen(8000, () => {
- console.log('服务已经启动, 端口 9000 监听中...');
- });
复制代码 打开浏览器,访问:http://localhost:8000
(2)request对象
常用方法及属性:
含义语法请求方式request.method协议和版本request.httpVersion请求路径request.urlURL 路径require(‘url’).parse(request.url).pathnameURL 查询字符串require(‘url’).parse(request.url).query请求头request.headers请求体request.on(‘data’, function(chunk){}) request.on(‘end’, function(){});使用示例:- // 1、引入http模块
- const http = require("http");
- const url = require('url')
- // 2、建立服务
- const server = http.createServer((request, response) => {
- // 设置响应类型
- response.setHeader("Content-Type", "text/html;charset=utf-8")
- // 获取完整的请求路径(带请求参数)
- var requestUrl =url.parse(request.url).pathname;
- // 获取查询字符串
- var params = url.parse(request.url).query;
- response.write(`<hr> 请求方式: ${request.method}`);
- response.write(`<hr> 协议和版本: ${request.httpVersion}`);
- response.write(`<hr> 请求路径: ${request.url}`);
- response.write(`<hr> URL 路径: ${requestUrl}`);
- response.write(`<hr> URL 查询字符串: ${params}`);
- response.write(`<hr> 请求头: ${JSON.stringify(request.headers)}`);
- response.write("name:" + params.name);
- if (request.url == "/register" && request.method == "GET") {
- response.end("<hr> welcome to register...");
- } else if (request.url == "/login" && request.method == "GET") {
- response.end("<hr> welcome to login...");
- } else {
- response.end("<h1>404 Not Found</h1>")
- }
- })
- // 3、监听端口
- server.listen(8000, () => {
- console.log('服务启动中....');
- })
复制代码 打开浏览器,访问:http://localhost:8000/register?username=xiaohui
(3)response对象
常用方法及属性:
作用语法设置响应状态码response.statusCode设置响应状态描述response.statusMessage设置响应头信息response.setHeader(‘头名’, ‘头值’)设置响应体response.write(‘xx’) response.end(‘xxx’)使用示例:- require('http').createServer((request, response) => {
- //获取请求的方法已经路径
- let {url, method} = request;
- // 设置响应类型
- response.setHeader("content-Type", "text/html")
- if (method == "GET" && url == "/index.html") {
- // 通过fs模块读取文件(同步读取)
- let data = require('fs').readFileSync('./index.html');
- response.statusCode = 200;
- response.end(data);
- } else {
- let data = require('fs').readFileSync('./404.html');
- response.statusCode = 404;
- response.end(data);
- }
- }).listen(8000, () => {
- console.log('8000端口正在启动中....');
- })
复制代码 访问:http://localhost:8000/index.html
1.6 NPM包管理工具
npm全称Node Package Manager,他是node包管理和分发工具。我们可以把NPM理解为java中的Maven。我们通过npm可以很方便地下载js库,管理前端工程。最近版本的node.js已经集成了npm工具,在命令提示符输npm -v 可查看当前npm版本。
NPM官网:https://www.npmjs.com/
1.6.1 修改npm镜像
NPM官方的管理的包都是从 http://npmjs.com下载的,但是这个网站在国内速度比较慢。这里推荐使用淘宝 NPM 镜像 ,淘宝 NPM 镜像是一个完整 npmjs.com 镜像。
设置镜像地址:- #经过下面的配置,以后所有的 npm install 都会经过淘宝的镜像地址下载
- npm config set registry https://registry.npmmirror.com
- #查看npm配置信息
- npm config list
- # 查看镜像源
- npm config get registry
复制代码 1.6.2 相关命令
命令介绍npm init初始化工程npm init -y可以跳过向导,快速初始化工程npm install简写npm i,自动下载package.json中dependencies中全部的依赖。npm install 包名简写npm i 包名,下载指定包npm install --save 包名简写npm i -S 包名,下载并保存依赖项(package.json中dependencies) 5.0.0版本之后的npm会自动保存到dependenciesnpm uninstall 包名简写npm un 包名,只删除,如果有依赖项会依然保存npm uninstall --save 包名简写npm un -S 包名,删除的同时也会将依赖信息删除npm help查看使用帮助npm 命令 --help查看对应命令的使用帮助,例如我忘记uninstall的简写,那么我可以输入npm uninstall --help
1.6.3 初始化工程
使用npm init命令可以把当前文件夹初始化成一个“包”,即一个标准的nodejs工程
建立一个空文件夹,在命令提示符进入该文件夹 执行命令初始化- npm init
- npm init -y # 全面使用默认值来初始化项目
复制代码 按照提示输入相关信息,如果是用默认值则直接回车即可。- C:\Users\Admin\Desktop\dfxt\dfxt_day02\web\NodeJSDemo\demo04_npm>npm init
- This utility will walk you through creating a package.json file.
- It only covers the most common items, and tries to guess sensible defaults.
- See `npm help init` for definitive documentation on these fields
- and exactly what they do.
- Use `npm install <pkg>` afterwards to install a package and
- save it as a dependency in the package.json file.
- Press ^C at any time to quit.
- package name: (demo04_npm)
- version: (1.0.0)
- description:
- entry point: (index.js)
- test command:
- git repository:
- keywords:
- author:
- license: (ISC)
- About to write to C:\Users\Admin\Desktop\dfxt\dfxt_day02\web\NodeJSDemo\demo04_npm\package.json:
- {
- "name": "demo04_npm", # 项目名称
- "version": "1.0.0", # 项目版本号
- "description": "", # 项目描述
- "main": "index.js", # 入口文件
- "scripts": { # 脚本
- "test": "echo "Error: no test specified" && exit 1"
- },
- "author": "", # 作者
- "license": "ISC" # 认证信息
- }
- Is this OK? (yes) yes
复制代码 npm init 命令的作用是将文件夹初始化为一个“包”,创建 package.json 文件,执行完npm init后会生成package.json文件,这个是包的配置文件,相当于maven的pom.xml,我们之后也可以根据需要进行修改。
1)安装镜像
install命令用于安装某个模块,如果我们想安装jquery模块,输出命令如下:- # 下载最新版本的jquery
- npm install jquery
复制代码 在该目录下已经出现了一个文件夹和文件。
- node_modules文件夹:用于存放下载的js库(相当于maven的本地仓库)。
- package-lock.json文件:确定当前安装的包的依赖,以便后续重新安装的时候生成相同的依赖,而忽略项目开发过程中有些依赖已经发生的更新。
我们再打开package.json文件,发现刚才下载的jquery已经添加到依赖列表中了,依赖包会被添加到dependencies节点下,类似maven中的标签。
安装时想指定特定的版本:查看package.json的依赖:- "dependencies": {
- "jquery": "^3.2.1"
- }
复制代码 2)版本号说明
- 指定版本:比如3.2.1,遵循“大版本.次要版本.小版本”的格式规定,安装时只安装指定版本。
- 波浪号指定版本:比如~3.2.1,表示安装3.2.x的最新版本(不低于3.2.1),但是不安装3.3.x,也就是说安装时不改变大版本号和次要版本号。
- 插入号指定版本:比如ˆ3.2.1,表示安装3.x.x的最新版本(不低于3.2.1),但是不安装2.x.x,也就是说安装时不改变大版本号。需要注意的是,如果大版本号为0,比如^0.2.1,则插入号的行为与波浪号相同,这是因为此时处于开发阶段,即使是次要版本号变动,也可能带来程序的不兼容。
- latest:安装最新版本。比如:
- npm install jquery@latest
复制代码 。需要注意,“最新版本”指的是latest标签指向的版本,而latest通常是主版本的最新稳定版,但不一定是最高的版本号,因为可能有预发布版本存在。例如,如果一个包的版本是1.2.3,然后发布了2.0.0-beta,这时候latest可能仍然指向1.2.3,直到2.0.0正式发布。
npm安装依赖说明:
场景实际安装版本安装标签对应的版本(如 Vue 3.4.21)安装标签对应的版本(如 Vue 3.4.21-beta)安装精确指定版本(3.2.0)严格按 package-lock.json 安装,确保环境一致性3)全局安装
在 npm 中,是的缩写,表示全局安装。它的作用是将一个包(package)安装到系统的全局环境中,而不是当前项目的本地目录。全局安装后的包可以在系统的任何目录下通过命令行直接使用。
全局安装适用于需要跨项目使用的命令行工具或全局工具。例如:(Vue 脚手架)、(React 脚手架)、(自动重启 Node 服务)等。
全局安装的路径:
- C:\Users\<用户名>\AppData\Roaming\npm\node_modules
复制代码- /usr/local/lib/node_modules
复制代码 安装与卸载全局包:- npm install -g @vue/cli # 全局安装 Vue CLI(跨项目使用)
- npm uninstall -g @vue/cli # 卸载全局的 Vue CLI
复制代码 4)运行依赖和开发依赖
我们使用- npm install <packageName>
复制代码 就能在线下载依赖到本地的node_modules目录,但我们项目打包时通常不会打包项目的node_modules以减轻项目大小。当项目发送给了团队的其他成员时只有源代码而没有项目所需的依赖,此时项目是无法运行的。
因此我们安装某个依赖时,除了下载依赖项到本地的node_modules目录外,还应该记录当前项目的依赖项配置,这样就算其他人获得到了项目源代码也可以按照依赖项配置来下载当前项目所需依赖。
在安装(npm install xxx)某个依赖项时,可以通过配置或来将该依赖项记录下来:
- –save 等同于 -S (常用,可保存在package.json文件中):依赖项信息将加入到dependencies中,表示是生产阶段的依赖,也就是项目运行时的依赖,就是程序上线后仍然需要依赖。
- –save-dev 等同于 -D:依赖项信息将加入到devDependencies,表示是开发阶段的依赖,就是我们在开发过程中需要的依赖,只在开发阶段起作用。
- Tips:从npm 5.0.0版本开始,默认行为改变了。现在当运行npm install xxx时,npm会自动将包添加到dependencies中,相当于之前需要–save的效果。
复制代码 如下:- {
- // jquery是开发依赖
- "devDependencies": {
- "jquery": "^3.7.1"
- },
- // bootstrap是生产依赖
- "dependencies": {
- "bootstrap": "^5.3.5"
- }
- }
复制代码 项目运行时必须依赖的包(无论是本地开发、生产环境还是其他环境),例如一些框架或常用库,如:JQuery、Bootstrap、Vue、axios等依赖,如果缺少这些依赖,代码将无法运行,这些依赖就应该是dependencies;
一些仅在开发阶段需要的依赖,生产环境不需要。例如一些构建、转码、测试工具等,如webpack、babel、eslint、jest等,这些依赖投入到生产环境中就再也不需要了,这些依赖就应该是devDependencies;
1.6.5 package和package-lock文件 1)package文件:
package.json定义了这个项目所需要的各种模块,以及项目的配置信息,包括名称、版本、许可证、依赖模块等元数据。
当执行 npm install 的时候,node 会先从 package.json 文件中读取所有 dependencies 信息,然后根据 dependencies 中的信息与 node_modules 中的模块进行对比,没有的直接下载,已有的检查更新。另外,package.json 文件只记录你通过 npm install 方式安装的模块信息,而这些模块所依赖的其他子模块的信息不会记录。
2)package-lock文件:
package.json文件中保存着项目的依赖以及这些依赖的版本信息,但是这些依赖的版本并非是一个固定的,而是可以随着时间的流逝(例如该依赖发布了新版本)自动更新的。因此,同一个package.json在不同时间点执行可能会导致项目实际使用的依赖版本不同。
如项目中JQuery依赖为,当前该依赖最新发布版本为,执行命令后将3.5.1版本的JQuery下载到了项目中。四个月后JQuery官方对其进行更新,当前最新版本为3.7.1,此时从新执行该项目的``npm install`将会安装3.7.1版本的JQuery。
可以看到,同一个项目,不同时间点来执行安装命令会导致项目的依赖版本不一样。package-lock.json文件正是来解决这个问题的。
package-lock.json 文件会保存 node_modules 中所有包的信息,包括精确版本 version 和下载地址 resolved 以及依赖关系 dependencies 等,用以记录当前状态下实际安装的各个模块的具体来源和版本号。这样 npm install 时速度就会提升。
当项目中已有package-lock.json 文件,在安装项目依赖时,将以该文件为主进行解析安装指定版本依赖包,而不是使用 package.json 来解析和安装模块。因为 package.json 指定的版本不够具体,而package-lock 为每个模块及其每个依赖项指定了版本,位置和完整性哈希,所以它每次的安装都是相同的。
package-lock.json 文件主要作用有以下两点:
1)当删除 node_module 目录时,想通过 npm install 恢复所有包时,提升下载速度。
2)锁定版本号,防止自动升级新版本。
项目中存在了package-lock.json当下载依赖时会以该文件中锁定的版本来下载,但有时我们也希望更新一下项目依赖,此时可以执行来更新项目的依赖版本,并且更新package-lock.json锁定的版本。
一般来说前端工程完毕后是不会将node_modules文件夹打包到项目中的(精简项目),当项目发布到互联网时,用户需要自行执行npm install来根据package.json或package-lock.json文件来下载依赖。如果项目中没有package-lock.json可以使用如下命令来构建一个package-lock.json:- npm install --package-lock-only
复制代码 到此这篇关于NodeJS的使用与NPM包管理器详解的文章就介绍到这了,更多相关nodejs与npm包管理器内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
来源:https://www.jb51.net/javascript/340102gzz.htm
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |