6、初始前端工程化
6.1、工程化概述
虽然前几篇我的目录标题写的前端工程化,但是那些东西并不属于前端工程化的内容,更倾向于是js、jq
当中的东西,下面我们将接触真正的前端工程化。
前端工程化开发其实现在是离不开一个东西的,这个东西就是Node.js
,早期角度来说这个东西一般是来做服务器开发的,目前的话已经不在局限于服务器开发了,现在整个前端开发过程中,已经完全离不开node.js
了,特别是我们node.js
帮我们管理了一些包工具npm/yarn/cnpm/npx/pnpm
pnpm
在最近一年刚刚流行起来,这个包的历史是比较久远的,但是在最近一两年的时候才变的特别流行,22年几个月的时候势
头很猛,包括像Vue
的源码里面,他现在也切换到了pnpm``pnpm
真的非常好用
nodejs
包管理工具、node当中的基础知识、node当中模块化的使用、webpack
打包器–>Vue Cli
/React Cli
,git源代码管理工具(版本控制工具)
6.2、Node.js
是什么
-
官方对于
Node.js
的定义Node.js
是一个基于V8 JavaScript
引擎的JavaScript运行时环境。
-
也就是说
Node.j
s基于V8
引擎来执行JavaScript的代码,但是不仅仅只有V8
引擎:-
前面我们知道
V8
可以嵌入到任何C ++应用程序中,无论是Chrome还是Node.js
,事实上都是嵌入了V8
引擎来执行 JavaScript代码; -
但是在Chrome浏览器中,还需要解析、渲染
HTML
、CSS
等相关渲染引擎,另外还需要提供支持浏览器操作的API
、浏览器 自己的事件循环等; -
另外,在
Node.js
中我们也需要进行一些额外的操作,比如文件系统读/写、网络IO、加密、压缩解压文件等操作
-
6.3、浏览器和Node.js
架构的区别
-
我们可以简单理解规划出
Node.js
和浏览器的差异: -
Nodejs
是用什么语言来编写的?- 有
js
但不是js
,更多的是C++/C语言
- 有
6.4、更详细的架构图
-
我们来看一个单独的
Node.js
的架构图-
我们编写的JavaScript代码会经过V8引擎,再通过Node.js的Bindings,将任务放到Libuv的事件循环中;
-
libuv
(Unicorn Velociraptor
—独角伶盗龙)是使用C语言编写的库; -
libuv
提供了事件循环、文件系统读写、网络IO、线程池等等内容;
-
我们可以可以基于node去编写我们自己的应用程序,对于我们前端来说,我们编写我们自己的应用程序,肯定是采用js
语言来编写,也就是我们可以通过 JavaScript这个语言去编写自己的应用程序,编写完应用程序他会交给V8
引擎来处理我们的代码。进而V8
引擎会帮助我们做一些翻译,比如说你写了一段代码如下fs.read("abc.txt")
,这段代码在我们的操作系统中是不认识的,这个时候的话他回经由我们的v8
引擎来对我们的代码进行翻译,翻译完成后,他会由我们Node.js
中的LIBUV
去调用系统系统操作的API
,执行对应操作,FilE SYSTEM
—>事件循环,进来的时候,我们把对应的回调函数放到了,事件队列里,出来的时候、掉出对应的回调函数,交给V8
引擎去执行
WORKER THREADS:工作线程,PROCESS:进程
6.5、Node.js
的应用场景
1、Node.js
的快速发展也让企业对Node.js
技术越来越重视,在前端招聘中通常会对Node.js
有一定的要求,特别是高级前端开发工程师Node.js
更是必不可的技能
2、在目前前端开发的库都是以node包的形式进行管理的。
3、npm
,yarn
、pnpm
工具成为前端开发使用最多的工具
4、越来越多的公司使用Node.js
作为web服务器开发、中间件、代理服务器;
5、大量项目需要借助Node.js
完成前后端渲染的同构应用;SSR Nuxt.js
6、资深前端工程师需要为项目编写脚本工具(前端工程师编写脚本通常会使用JavaScript,而不是Python或者shell);
7、很多企业在使用Electron来开发桌面应用程序;VsCode
就是用Electron来编写的一个软件
6.6、Node.js
的安装
node的官网:nodejs.org
、nodejs.cn
Node.js
是在2009年诞生的,目前最新的版本是分别是LTS
20.12.2以及Current
22.1.0:
LTS
版本:(Long-term support, 长期支持)相对稳定一些,推荐线上环境使用该版本;
Current版本:最新的Node版本,包含很多新特性;
这些我们选择什么版本呢?
如果你是学习使用,可以选择current版本;
如果你是公司开发,建议选择LTS
版本(面向工作,选择LTS
版本);
Node的安装方式有很多:
可以借助于一些操作系统上的软件管理工具,比如Mac上的homebrew
,Linux上的yum
、dnf
等;
也可以直接下载对应的安装包下载安装;
我们选择下载安装,下载自己操作系统的安装包直接安装就可以了:
window选择.msi
安装包,Mac选择.pkg
安装包,Linux会在后续部署中讲解;.msi
(microsoft
install
) 微软安装
安装过程中会配置环境变量(让我们可以在命令行使用);
并且会安装npm
(Node Package Manager)工具;
.msi
安装步骤
点击.msi
安装程序,next下一步、选择安装位置、(包管理工具、node环境),C++编译程序(推荐安装),next—>install—>finish
按任意键继续,会继续安装一些额外的工具(会有一个黑窗口)让他自己跑就可以了
检查是否安装成功
#查看node的版本
node -v
node --version
#查看npm版本
npm --version
黑窗口那一步可能会安装失败、这是因为有些包需要翻墙下载。暂时用不到,用到了再处理这个问题,或者你像我一样打开你的科学上网工具,
以前运行Js
代码我们怎么运行?
写js
文件,在html
页面中引入这个文件、然后浏览器中打开这个文件
现在怎么运行Js
代码怎么运行?
windows切换盘符,>F:
切换到对应的js
父级目录(输入a,按下tab键)
node abc.js
为什么能运行js
,因为node环境中有,v8
引擎
6.7、Node.js
的版本管理工具
公司现在使用的node版本,14、16等
但是现实的前端开发中、我们可能需要同时开发多个项目,且多个项目使用的node版本还不一样。那我们能不能同时安装多个node。默认情况下,安装第二个版
本时。会自动提示是否卸载上次安装的node,所以采用手动安装的方式是不可以达到我们想要的目的,做不到灵活的切换node版本
市面上有很多的版本管理工具、比如n/nvm
,n就是Node的一个模块,他的作者是tj
,tj
全称为TJ Holowaychuk
(Express框架的作者)
nvm
的作者就是Jordan Harband
是qs
模块的主要维护者,以前这个qs
模块也是由TJ Holowaychuk
来维护的。
据说n
比NVM
好用,这句话出自王老师之口,具体我也没有测试过没发言权
但是不管是n
还是nvm
都有一个很大的缺陷,就是并不支持windows系统,这两个工具就是在mac系统下使用的
社区上边有天才,有人发布了nvm-windows
nvm
对应的windows版本呢
https://github.com/nvm-sh/nvm
https://github.com/coreybutler/nvm-windows
1、采用NVM
来切换Node版本
#安装nvm最新版本
nvm install latesst
#查看已经下载的nvm列表
nvm list
#切换node
nvm use切换版本
2、采用n
版本管理工具
安装n:直接使用npm
安装
#安装工具n
npm install -g n
#查看安装的版本
n --version
安装最新的lts
版本
前面添加的sudo
是权限问题;
可以两个版本都安装,之后我们可以通过n快速在两个版本间切换;
# 安装最新的lts版本
n lts
# 安装最新版本
n latest
# 查看所有的版本
n
windows
的黑窗口操作是非常不好用的,可以采用git的黑窗口git bash
3、采用volta-node
版本管理器
https://www.jb51.net/javascript/3152840cs.htm
6.8、node.js
基础知识
1、JavaScript代码执行
如果我们编写一个js
文件,里面存放JavaScript代码,如何来执行它呢?
目前我们知道有两种方式可以执行:
- 将代码交给浏览器执行;
- 将代码载入到node环境中执行;
如果我们希望把代码交给浏览器执行:
- 需要通过让浏览器加载、解析
html
代码,所以我们需要创建一个html
文件; - 在
html
中通过script标签,引入js
文件; - 当浏览器遇到script标签时,就会根据
src
加载、执行JavaScript
代码;
如果我们希望把js
文件交给node执行:
-
首先电脑上需要安装
Node.js
环境,安装过程中会自动配置环境变量; -
可以通过终端命令
node js
文件的方式来载入和执行对应的js
文件;
选择对应文件夹、右键再集成终端中打开,使用命令node index.js
文件
开始可能会显示无法识别的命令,因为开始默认使用的是powershell
,这个东西默认调用一些环境是有些问题的
还是会出现问题如下
git bash
–>cmd
–>powershell
2、Node.js
的输入和输出
1、node输出
console.log
- 最常用的输入内容的方式:
console.log
- 最常用的输入内容的方式:
console.clear
- 清空控制台:
console.clear
- 清空控制台:
console.trace
- 打印函数的调用栈:
console.trace
- 打印函数的调用栈:
还有一些其他的方法,其他的一些console方法,可以自己在下面学习研究一下。
https://nodejs.org/dist/latest-v16.x/docs/api/console.html
2、node输入
正常情况下执行一个node程序,直接跟上我们对应的文件即可:
node index.js
但是,在某些情况下执行node程序的过程中,我们可能希望给node传递一些参数:
node index.js env=development coderwhy
如果我们这样来使用程序,就意味着我们需要在程序中获取到传递的参数:
- 获取参数其实是在process的内置对象中的;
- 如果我们直接打印这个内置对象,它里面包含特别的信息:
- ✓ 其他的一些信息,比如版本、操作系统等大家可以自行查看,后面用到一些其他的我们还会提到;
现在,我们先找到其中的argv
属性:
-
我们发现它是一个数组,里面包含了我们需要的参数;
3、为什么叫argv
呢?
你可能有个疑问,为什么叫argv
呢?
在C/C++程序中的main函数中,实际上可以获取到两个参数:
argc
:argument counter的缩写,传递参数的个数;argv
:argument vector(向量、矢量)的缩写,传入的具体参数。- vector翻译过来是矢量的意思,在程序中表示的是一种数据结构。
- 在C++、Java中都有这种数据结构,是一种数组结构;
- 在JavaScript中也是一个数组,里面存储一些参数信息;
我们可以在代码中,将这些参数信息遍历出来,使用
3、Node.js
中的REPL
-
什么是
REPL
呢?感觉挺高大上REPL
是Read-Eval-Print
Loop的简称,翻译为“读取-求值-输出”循环;REPL
是一个简单的、交互式的编程环境
;
-
事实上,我们浏览器的console就可以看成一个
REPL。
-
Node也给我们提供了一个
REPL
环境,我们可以在其中演练简单的代码。
4、Node.js
常见的全局对象一
node当中没有windows全局对象、但是有global
Node中给我们提供了一些全局对象,方便我们进行一些操作:
- 这些全局对象,我们并不需要从一开始全部一个个学习;
- 某些全局对象并不常用;
- 某些全局对象我们会在后续学习中讲到;
- ✓ 比如module、exports、require()会在模块化中讲到;
- ✓ 比如Buffer后续会专门讲到;
5、Node.js
特殊的全局对象
为什么我称之为特殊的全局对象呢?
- 这些全局对象实际上是模块中的变量,只是每个模块都有,看来像是全局变量;
- 在命令行交互中是不可以使用的;
- 包括:
__dirname
、__filename
、exports
、module
、require()
__dirname
:获取当前文件所在的路径?
- 注意:不包括后面的文件名
__filename:获取当前文件所在的路径和文件名称:
- 注意:包括后面的文件名称
6、Node.js
常见的全局对象二
process对象:process提供了Node进程中相关的信息:
- 比如Node的运行环境、参数信息等;
- 后面在项目中,我也会讲解,如何将一些环境变量读取到 process 的
env
中;
console对象:提供了简单的调试控制台,在前面讲解输入内容时已经学习过了。
- 更加详细的查看官网文档:https://nodejs.org/api/console.html
定时器函数:在Node中使用定时器有好几种方式
setTimeout(callback, delay[, ...args])
:callback在delay毫秒后执行一次;setInterval(callback, delay[, ...args])
:callback每delay毫秒重复执行一次;setImmediate(callback[, ...args])
:callbackI / O
事件后的回调的“立即”执行;- ✓ 这里先不展开讨论它和
setTimeout
(callback, 0)之间的区别; - ✓ 因为它涉及到事件循环的阶段问题,我会在后续详细讲解事件循环相关的知识;
- ✓ 这里先不展开讨论它和
process.nextTick(callback[, ...args])
:添加到下一次tick队列中;- √ 具体的讲解,也放到事件循环中说明;
7、global对象
global是一个全局对象,事实上前端我们提到的process
、console
、setTimeout
等都有被放到global中:
我们之前讲过:在新的标准中还有一个globalThis
,也是指向全局对象的;
类似于浏览器中的window;
8、global和window的区别
在浏览器中,全局变量都是在window上的,比如有document
、setInterval
、setTimeout
、alert
、console
等等
在Node中,我们也有一个global属性,并且看起来它里面有很多其他对象。
但是在浏览器中执行的JavaScript代码,如果我们在顶级范围内通过var定义的一个属性,默认会被添加到window对象上:
var name='有些人真的很让我反胃'
console.log(windows.name) //有些人真的很让我反胃
但是在node中,我们通过var定义一个变量,它只是在当前模块中有一个变量,不会放到全局中:
var name='coderwhy'
console.log(global.name);//undefined