1.Node.js是什么
0.写在前面
-
解释:Node.js® is a runtime built on Chrome’s V8 JavaScript engine.
-
需要在自己电脑安装node.js(官网:https://nodejs.org/zh-cn/),建议下载长期维护版本
1.特性
Node.js 可以解析JS代码(没有浏览器安全级别的限制)提供很多系统级别的API,如:
- 文件的读写 (File System)
- 进程的管理 (Process)
- 网络通信 (HTTP/HTTPS)
- ……
1.安全沙箱(跨域访问)
- 代码(基于html的ajax请求)–明显会被跨域拦截
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>browser-safe-sandbox</title>
</head>
<body>
<div>browser-safe-sandbox</div>
<script>
const xhr = new XMLHttpRequest()
xhr.open('get', 'https://m.maoyan.com/ajax/moreClassicList?sortId=1&showType=3&limit=10&offset=30&optimus_uuid=A5518FF0AFEC11EAAB158D7AB0D05BBBD74C9789D9F649898982E6542C7DD479&optimus_risk_level=71&optimus_code=10', false)
xhr.send()
</script>
</body>
</html>
- 在终端中输入以下代码
npx http-server
- 使用node.js进行ajax请求
- server.js
// 引入http,版本高的可以使用import
const https = require('https')
https.get('https://m.maoyan.com/ajax/moreClassicList?sortId=1&showType=3&limit=10&offset=30&optimus_uuid=A5518FF0AFEC11EAAB158D7AB0D05BBBD74C9789D9F649898982E6542C7DD479&optimus_risk_level=71&optimus_code=10'
, (res) => {
// console.log(res)
//对返回的数据进行封装
let str = ''
res.on('data', (chunk) => {
str += chunk
})
res.on('end', () => {
console.log(str)
})
})
- 在该文件的目录下打开终端,输入
node server.js
- 这个案例完成后只需要明白一点:node.js是没有跨域访问的限制的
2.文件读写
- 之后会详细介绍node文件读写(这里只是了解一下nodejs的特性)
const fs = require('fs')
fs.writeFile('./log.txt', 'hello', (err) => {
if (err) {
//错误处理
} else {
console.log('文件创建成功')
}
})
3.进程管理
console.log(process.argv.slice(2))
4.通信管理(创建一个服务端)
const http = require('http')
const server = http.createServer((request, response) => {
let url = request.url
response.write(url)
response.end()
})
server.listen(8090, 'localhost', () => {
console.log('localhost:8090')
})
2.Node相关工具
1.NVM
-
Node的版本管理工具(全称Node Version Manager)
-
github网址:https://github.com/coreybutler/nvm-windows,自行百度相关安装教程
-
终端工具:cmd.powershell,cmd,bash(是linux操作环境,使用linux语法,在VSCode中可以切换)
1.查看node.js发行了哪些版本:
①.查看官网(https://nodejs.org/zh-cn/ )changelog(更新日志)
②.在终端中输入:npm view node versions
2.nvm常用命令
- 注意:以下命令都是在bash终端中使用
- 查看帮助:
nvm --help
- 查看自己node版本:`node -v
- 查看自己电脑中安装有哪些node版本:
nvm list
- 切换版本(不会改变默认版本,只是当前窗口使用):
nvm use 14.15.0
- 安装新的node版本:
nvm install v14.15.0
- 设置默认版本:
nvm alias default v14.15.0
2.NPM
- Node包管理工具(全称Node Package Manager)
1.全局安装package
-
全局安装
npm install understore --global
-
全局安装
npm install jquery -g
-
全局安装
npm i gulp -g
-
全局安装-缩写
npm i gulp
2.全局卸载
npm uninstall gulp -g
3.初始化
npm init
npm init -y
表示全部确定
4.配置环境安装
npm i gulp --dev-save
npm i underscore -S
npm i underscore --save
5.写脚本
"dev": ".\\node_modules\\.bin\\gulp -v"
"dev": "gulp -v"
#会自动到node_modules包里面去寻找
- 在package.json文件中的scripts里面写脚本,需要先初始化,后面会有详细说明,这里只做简介
6.全局安装包的目录
- Mac
/User/felix/.nvm/versions/node/nvm各个版本/bin
- windows
C:\User\你的用户名\AppData\Roaming\npm\node_modules
7.移动包到生产环境
npm i gulp -D
- 生产环境的包会出现在package.json的decDependencies里面,需要事先初始化,测试人员在安装依赖时会默认忽略
8.安装依赖
npm i
9.查看依赖关系
npm list
参数筛选:
npm list | grep gulp
10.只安装生产环境下的包
npm i --production
11.安装指定版本的包
- 查看版本:
npm view jquery versions
-
安装指定版本
npm i jquery@2.2.4
-
安装某个大版本的最高版本,后面不写代表最大版本
npm i jquery@1 -S
- 14.15.1–第一个是major,第二个是minor,第三个是patch(补丁),一般patch单数不稳定,双数稳定
12.查看版本是否过期
npm outdated
升级:
npm update
^表示只锁定主版本号
~表示锁定主版本号和次版本号
只写版本号表示锁定patch
0.0在次版本号和版本中在锁定主版本号情况下不会报错
*表示最新版本
13.清除缓存
npm cache clean --force
3.NRM
- 全称:npm registry manager
- 安装:
npm i nrm -g
1.手动切换源
- 查看当前源
npm config get registry
- 切换源
- 淘宝:
npm config set registry https://registry.npm.taobao.org
- 官网:
npm config set registry https://registry.npmjs.org
2.nrm切换源
nrm use npm
nrm use taobao
- …
3.查看自己的所有源
nrm ls
4.测试网速
- 测速时间一般较长
nrm test
4.NPX
-
全称:npm package extention,我也不知道为什么不叫他npe
-
从 npm 5.2版本之后才有!
-
不需要额外安装
-
问题:如果你在开发环境安装了一个gulp第三方库(
npm i gulp -D
),根据之前的知识,你在命令行是不能直接使用gulp -v
的命令的,除了使用./node_modules/.bin/gulp -v
自己寻找之外,还可以使用npx -
npx会创建一个临时的文件夹,并且调用临时文件夹里面的第三方库,不会污染全局环境
-
在只需要调用一次或者在非本地环境却要依赖第三方库的时候,可以使用npx
-
有关参数:
- 1.强制使用本地模块,不下载远程模块
npx --no-install http-server
- 2.忽略本地模块,强制安装使用远程模块
npx --ignore-existing http-server
3.上传自己的包
1.内置模块
-
node.js分为内置模块以及第三方模块
-
内置模块可以通过查找官方文档查看用法(官网:http://nodejs.cn/api/fs.html)
-
eg:app.js
const path = require('path')
//resolve解析一个路径
//__dirname表示当前代码所在文件的物理路径
console.log(__dirname)
console.log(path.resolve(__dirname, '../'))
2.第三方模块
2.axios例子:
- 下载axios
npm i axios -S
- app.js
const axios = require('axios')
axios.get('http://www.baidu.com').then(result => {
console.log(result)
}).catch((err) => {
})
- 在终端中输入
node app.js
运行
3.自定义模块
1.lodash案例:
npm i lodash -S
2.app.js
const _ = require('lodash')
let arr = [4, 5, 6, 7]
//转换为二维数组
let arr2 = _.chunk(arr, 2)
console.log(arr2)
3.运行
node index.js
4.认识暴露文件,别人引用你的模块的时候,别人需要寻找的文件(json格式不允许添加注释),在package.json中书写
"main": "index.js",
5.修改成模块形式的index.js
const _ = require('lodash')
// let arr = [4, 5, 6, 7]
function myChunk(arr) {
//转换为二维数组
let arr2 = _.chunk(arr, 2)
// console.log(arr2)
return arr2
}
module.exports = myChunk
6.test.js
const myChunk = require('./index.js')
console.log(myChunk([4, 5, 6, 7]))
4.线上发布
- 在https://www.npmjs.com官网中注册一个自己的账号
1.登录
- 在终端输入自己账号和密码以及邮箱:
npm adduser
- 这里涉及到一个问题,npm源要设置成官网,不能是镜像,设置查看前面nrm切换源
2.上传包
npm publish
- 注意包名不能和网站上已有的包名重复,否则会上传失败
- 修改包名:在package.json里面修改name属性,之后再重新尝试
"name":03-custom-lth-test
- 成功提示:
-
修改版本号:
"version":"9.9.99"
-
添加你的描述信息(自己写一个markdown笔记,起名为readme.md):
"description":"readme.md"
-
添加关键字
"keywords":["test","helloword"]
-
协议:
"license":"MIT"
-
其他:
"bugs":{http://www.baidu.com},"homepage":"https://baiwu.com"
3.在官网上查找自己的包
- 到这一步上传自定义包就算成功了
4.下架包
npm unpublish 03-custom-test-lth --force
5.使用自定义包
1.下载
npm i 03-custom-lth-test -S
2.test.js
- 引入包
require('axios')
const myChunk = require('03-custom-lth-test')
console.log(myChunk([4, 5, 6, 7]))
3.运行
node test.js
4.NPM脚本
package.json
{
"dependencies": {
"03-custom-lth-test": "^1.0.0",
"axios": "^0.27.2",
"jquery": "^3.6.0"
},
"scripts": {
"start": "node server.js"
},
"name": "02-npm",
"version": "1.0.0",
"main": "server.js",
"author": "",
"license": "ISC",
"description": ""
}
-
在scripts里面写的就是脚本,里面使用的是linux语法
-
在脚本里面写第三方命令首先会从全局环境中去找有没有第三方库,如果没有的话会自动到node_modules里面去找,而在终端里写的话只会在全局里面找
-
运行:
npm run + 命令
,可以简写的命令:npm start,npm test,
-
同时写多条命令:
- 1.用&并行执行
- 2.用&&表示串行
-
自定义属性
"config": {
"env": "production"
}
- 获取自定义属性:
- 通过
npm_package
前缀+_变量名
- 通过
console.log(process.env.npm_package_config_env)
- 在脚本内部也可以访问配置文件的信息
"build":echo $npm_package_config_env
5.NPM安装git上发布的包
- 适合安装公司内部的git服务器上的项目(不要以不会这种方式安装就被开除了,哈哈)
1.ssh方式:
npm i git+ssh://git@github.com:lurongtao/gp-project.git
2.https方式:
npm i git+https://git@github.com:lurongtao/gp-project.git
6.cross-env
- 运行跨平台和使用环境变量的脚本,比如说因为linux和windows的命令提示行窗口写的命令不一样
- cross-env提供一个设置环境变量的scripts,让你能够以Unix方式设置环境变量,然后在windows上面也能兼容运行。(牛逼之处)
- 安装
npm i cross-env
或者
npm i cross-env -D -S
- Usage:
"scripts": {
"dev": "cross-env NODE_ENV=development gulp -f gulp.config.js",
"proc":"cross-env NODE_ENV=production gulp -f gulp.config.js"
},
- 获取值:
const node_env = process.env.NODE_ENV
console.log(node_env)
- exports就是module.exports的一个引用
7.模块/包与CommonJS
1.模块/包分类
Node.js有三类模块,即内置模块、第三方模块、自定义模块
1.1内置模块
Node.js内置模块又叫做核心模块,Node.js安装完成即可以使用:
const path=require('path')
var extname=path.extname('index.html')
console.log(extname)
1.2第三方模块
第三方模块的Node.js模块指的是为了实现某些功能,发布的npmjs.org上的模块,按照一定的源协议供社群使用,如:
npm install chalk
const chalk = require('chalk')
console.log(chalk.blue('Hello world!'))
1.3自定义模块
自定义的Node.js模块,也叫做文件模块,是我们自己写的供自己使用的模块。同时,这类模块发布到npmjs.org就成了开源的第三方模块。
自定义模块是在运行时动态加载,需要完整的路径分析,文件定位、编译执行的过程、速度比核心模块稍微慢一些,但是用的非常多
1.3.1模块定义、接口暴露和引用接口
我们可以把公共的功能,抽离成为一个单独的js文件,作为一个模块,默认情况下面这个模块里面的方法或者属性,外面是没办法访问的。如果要让外部可以访问模块里面的方法或者属性,就必须在模块里面通过exports或者module.exports暴露属性或者方法。
ES是JavaScript的语法糖,可以说是一种更高级的规范,但不是所有的浏览器都支持ES。
语法糖是指通过一种简单的语法更容易让人理解,通过解释让浏览器识别。
原本Node.js也是不支持模块化的概念,但是引入了一种第三方规范:CommonJS规范,Node.js已经将CommonJS纳入自己,已经成为Node.js的一个规范。
浏览器不支持CommonJS规范,CommonJS可以定义模块,引入模块,暴露接口,调用模块
name.js
const name = {
surname: 'zhang',
sayname() {
console.log(this.surname)
}
}
const age = {
age: 100
}
// module.exports = {
// //相当于name:name,age:age,这种情况下可以简写
// name,
// age
// }
//exports是module。exports的一个引用,本质上还是返回一个对象,用法和module.exports不一样:
exports.name = name
exports.age = age
//事实上这句话const exports = module = exports默认就已经使用了
//但是exports不能和上面module.exports一样使用!!!
// exports.default = {
// }
// //等价于
// module.exports = {
// default
// }
app.js
console.log(require)
//可以省略.js,默认会寻找name.js,但是加上.js可以加快速度,提高性能
const { name, age } = require('./name.js')
name.sayname()
console.log(age.age)
1.3.2模块的循环引用
类似于A引用B,B引用C,C引用A,这种循环就会导致程序运行出错
- 写在后面:你知道CommonJS与ES6模块化的区别吗?