NODE基础概念
node并不是一门语言,它是一个开发工具或者环境
之所以称node为服务器端语言,是因为node给予了JS操作服务器的能力:我们在服务器端安装node,只用js完成服务器需要处理的事情,最后把写好的js代码交给了node环境运行即可。
node安装完成后
- 当前电脑上自动安装了npm(node Package Manager):一个JS模块(所有封装好可以供其他人调取使用的都可以称之为模块或者包)管理的工具,基于npm可以下载JS模块
- 它会生成一个node执行的命令(可以在DOS窗口或者终端命令中执行):node xxx.js
node解析JS代码
- REPL(在DOS命令窗口直接输入node回车)
- 直接基于node来执行JS文件
- 在DOS窗口 & 终端窗口
- VS中的terminal中执行node命令
- VS中右键run code
特点
- 基于V8渲染和解析JS的(快)
- 单线程(劣势)
- 异步无阻塞I/O操作(对文件的读写)
- 事件驱动:类似于发布订阅或者回调函数
- 。。。
在node环境中把JS代码执行(3种方式)
-
REPL命令(Read-Evaluate-Print-Loop:输入-求值-请求-循环)
-
基于node xxx.js命令执行:
在命令行窗口输入命令,则相当于在node环境下执行代码执行代码
-
基于WB、VS这类编辑工具直接执行
JS运行在客户端浏览器中=>"前端"
浏览器给JS提供可很多全局的属性和方法:例如:window.xxx(setInterval、setTimeout、eval、alert、JSON…)
前端(浏览器运行JS)是限制IO操作的
JS运行在服务器端的node中=>“后台”
node也给JS提供了很多内置属性和方法,例如:http、fs、url、path…等对象中都提供很多API供JS操作
node中运行JS是不需要限制I/O操作的
NODE
NODE本身是基于CommonJS模块规范设计的,所以模块是NODE的组成
- 内置模块:NODE天生提供给JS调取使用的
- 三方模块:别人写好的,我们可以基于NPM安装使用
- 自定义模块:自己创建一些模块
CommonJS模块化设计的思想(AMD、CMD、ES6 MODULE都是模块设计思想)
1. CommonJS规定:每一个JS都是一个单独的模块(模块是私有的:里面涉及的值和变量以及函数都是私有的,和其他JS文件中的内容是不冲突的)
2. CommonJS中可以允许模块中的方法互相调用
B模块想要调取A模块中的方法
- A导出
- B导入
【导出】
CommonJS给每个模块(每个JS)都设置了内置的变量、属性和方法
module:代表这个模块对象
module.exports:模块的export属性是用来导出属性和方法
exports:是内置的一个"变量",也是用来导出属性和方法的
虽然exports是变量,module.exports是属性,不是一个东西,但是对应的值都是对象,指向同一个地址(module.exports === exports)
【导入】
require:CommonJS提供的内置变量,用来导入模块的(其实导入的就是module.exports暴露出来的东西);导入的值也是[object]类型的。
require导入规则:
require('./xxx') 到当前目录下查找模块
require('../xxx') 到上级目录下查找模块
require('/xxx') 到下级目录下查找文件
require('xxx') 首先到当前项目的node_modules中查找模块,找不到再到node提供的内置模块中查找。
【特点】
1.所有代码都运行在模块作用域,不会污染全局作用域(每一个模块都是私有的,包括里面的东西都是私有的,不会和其他模块产生干扰)
2. 模块可以多次加载,但是只会在第一次加载运行一次,然后运行结果就被缓存了,以后再加载,就直接读取及诶过。想让模块再次运行,必须清除缓存。
3. 模块加载的顺序,按照在代码出现的顺序。CommonJS规范加载模块是同步的,也就是说,只有加载完成,才能执行后面的操作。
__filename:模块中这个内置变量是当前模块所在的绝对路径(具体到盘符:物理路径)(加当前模块)d:\js学习\案例\test\A.js
__dirname:绝对路径,不加当前模块d:\js学习\案例\test
//test.js
let a = 12,
fn = b => {
return a + b;
};
console.log(1);
exports.fn = fn; //将当前模块的函数放到exports导出对象中(这样可以基于equire在其他模块中导入)
console.log(2);
//test2.js
//reuqire导入的时候,首先把test模块中的代码自上而下执行,把exports对应的堆内存导入进来,所以接收到的结果是一个对象(require是一个同步操作)
console.log(3);
let test1 = require('./test'); //=>./是当前文件的某个模块;.js可以省略;
console.log(4);
console.log(test1.fn(10));
//结果:1 2 3 4 22
//reuqire导入的是module.exports导出的对象(exports只是提供的快捷方式,exports=module.exports)
moudle.exports = { //重定向自己的堆内存,实现导出
fn1:fn1
};
exports.fn2 = 100;//无法导出,此时exports和module.exports已经不是同一个堆内存了
NPM模块管理
安装node后,自带npm模块管理器
我们需要一个第三方模块、插件、类库或者框架等,需要提前下载安装才可以使用
百度搜索,找到下载地址,基于浏览器下载(资源混乱,不方便搜索)
基于npm等第三方包管理器下载(yarn / bower …都是第三方模块)
(npm是基于https://www.npmjs.com/下载资源的)
常用命令:
npm view xxx > xxx.version.txt
查看模块的历史版本
npm install xxx@xxx
:把资源下载到当前目录下(@xxx指定版本号)
npm install xxx -g(--global)
:把资源或者第三方模块安装到的全局环境下(目的:以后可以基于一些命令来操作一些事情)
npm uninstall xxx / npm uninstall xxx -g
:从本地或者全局卸载
npm addUser
登录npm (登录时要先切源到npm)
npm publish
上传包文件
基于npm安装的特点:
- 连网(国外服务器,下载慢)
- 下载成功后,在node_modules文件夹,在这个文件夹中找到我们需要的模块
- 一般来说,下载下来的内容包含源码和最后提供开发者使用的压缩版本
解决下载慢的问题:
-
基于nrm切换到国内下载资源(一般是淘宝镜像)(切源)
首先在全局安装nrm模块:npm install nrm -g
安装完成后,可以使用nrm命令
nrm ls 查看当前可用源
nrm use xxx 使用某个源
切完源还是得基于npm安装操作
-
可以基于yarn来安装管理
首先在全局安装yarn模块:npm install yarn -g
安装完成后,可以使用yarn命令安装我们需要的模块,基于yarn安装的东西只能安装在本地
yarn add xxx
yarn remove xxx
-
可以基于cnpm淘宝镜像处理
解决安装版本的问题
首先查看当前模块的历史版本:
npm view jquery > jquery.version.json
:把当前模块的历史信息输出到具体的某个文件中(文件名自己随便起的)安装指定的版本模块:
yarn add jquery@1.11.3
:npm和yarn都是这样来安装指定版本的
注意点
- 在本地项目中基于npm/yarn安装第三方模块
第一步:在本地项目中创建一个"package.json"的文件
作用:把当前项目所有依赖的第三方模块信息(包含:模块名称以及版本号信息)都记录下来;可以在这里配置一些可执行的命令脚本等
基于yarn会默认 生成一个"配置清单",知识信息没有手动创建的全面
手动创建:npm init -y 或者 yarn init -y
{
"name": "httptest", //=>模块名称
"version": "1.0.0", //=>版本号
"description": "", //=>模块的描述”“
"main": "server.js", //=>当前模块的主入口文件
"scripts": { //=>可执行脚本
"server": "node server.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": { //=>生产依赖
"mime": "^2.5.2",
"qs": "^6.9.6"
},
"devDependencies":{} //=>开发依赖
}
第二步:安装
开发依赖:只有在项目开发阶段依赖的第三方模块
生产依赖:项目部署实施的时候,也需要依赖的第三方模块
[npm]
npm install xxx --save 保存到配置清单的生产依赖中
npm install xxx --save-dev 保存到开发依赖中
[yarn]
yarn add xxx 默认就是保存到生产依赖中
yarn add xxx --dev /-D 保存到开发依赖中
第三部:部署的时候“跑环境”
不要自己一个个的安装,只需要执行npm install 或者yarni install即可,npm会自己先检测目录中是否有package.json文件,如果有的或话,会按照文件中的配置清单依次安装
=>开发一个项目,我们生成一个配置清单"package.json",当我们安装第三方模块使用的时候,把安装的模块信息记录到配置清单中,这样以后不管是团队协作开发还是项目部署上线,我们都没有必要把node_modules发文件发文件给别人,只需要把配置清单传递给其他人即可,其他人拿到配置清单后,按照清单中依赖项及版本号,重新安装即可(重新安装:即“跑环境”)
- 安装在本地和全局的区别
【安装在全局的特点】
1. 所有的项目都可以使用这个模块
- 容易导致版本冲突
- 安装在全局的模块,不能基于CommonJS规范调取使用(不能在JS中通过require调取使用)
【安装在本地的特点】
1. 只能当前项目使用这个模块
- 不能直接的使用命令行
为什么安装在全局下可以使用命令?
npm root / -g 查看本地项目或者全局环境下,npm的安装目录
安装在全局目录下的模块,但部分都会生成一个xxx.cmd的文件
@ECHO off
SETLOCAL
CALL :find_dp0
IF EXIST "%dp0%\node.exe" (
SET "_prog=%dp0%\node.exe"
) ELSE (
SET "_prog=node"
SET PATHEXT=%PATHEXT:;.JS;=;%
)
"%_prog%" "%dp0%\node_modules\yarn\bin\yarn.js" %*
ENDLOCAL
EXIT /b %errorlevel%
:find_dp0
SET dp0=%~dp0
EXIT /b
能否既安装在本地,也可以使用命令操作?
(1) 把模块安装在本地如果支持命令操作的(会在node_modules的bin中生成xxx.cmd的命令文件,只不过这个文件无法在全局下执行 => 不能直接用命令)
(2) 在package.json的scripts中配置需要执行的命令脚本
"scripts":{
"gmh":"lessc -v" 属性名自己设置即可,属性值是需要执行的命令脚本,根据需要自己编写(可以配置很多命令的)
}
(3) npm run gmh / yarn gmh 这样的操作就可以把配置的脚本执行
-> 首先到配置清单的scripts中查找
-> 找到后把后面对应的属性值(执行脚本)执行
-> 执行脚本的时候,回到本地node_modules中bin文件下查找,没有的话,再向npm安装的全局目录下查找