大家好,又见面了,我是你们的朋友全栈君。
3. 浏览器中运行的 JavaScript 和 Node.js 中运行的 JavaScript 有区别吗
在内置了 JavaScript V8 Engine 以后实际上只能执行 ECMAScript,就是语言中的语法部分。
浏览器为了能够让 JavaScript 操作浏览器窗口以及 HTML 文档,所以在 JavaScript V8 Engine 中添加了控制它们的 API, 就是 DOM 和 BOM. 所以 JavaScript 在浏览器中运行时是可以控制浏览器窗口对象和DOM文档对象的。
和浏览器不同,在 Node.js 中是没有 DOM 和 BOM 的,所以在 Node.js 中不能执行和它们相关的代码,比如 window.alert()
或者 document.getElementById()
. DOM 和 DOM 是浏览器环境中特有的。在 Node.js 中,作者向其中添加了很多系统级别的 API,比如对操作系统中的文件和文件夹进行操作。获取操作系统信息,比如系统内存总量是多少,系统临时目录在哪,对系统的进程进行操作等等。
JavaScript 运行在浏览器中控制的是浏览器窗口和 DOM 文档。
JavaScript 运行在 Node.js 中控制的操作系统级别的内容。
系统环境变量是指在操作系统级别上定义的变量,变量中存储了程序运行时所需要的参数。
比如在使用 webpack 构建前端应用时就使用到了系统环境变量,因为 webpack 需要根据系统环境变量判断当前为开发环境还是生产环境,根据环境决定如何构建应用。
在开发环境的操作系统中定义 NODE_ENV 变量,值为 development,在生产环境的操作系统中定义 NODE_ENV 变量,值为 production。webpack 在运行时通过 process.env.NODE_ENV 获取变量的值,从而得出当前代码的运行环境是什么。
环境变量 PATH:系统环境变量 PATH 中存储的都是应用程序路径。当要求系统运行某一个应用程序又没有告诉它程序的完整路径时,此时操作系统会先在当前文件夹中查找应用程序,如果查找不到就会去系统环境变量 PATH 中指定的路径中查找。
LTS:长期支持版 (稳定版) 可以运行在生产环境中。
Current:最新版 (预览版) 不建议运行在生产环境中,因为可能有 BUG。
查看 Node 版本:node -v
查看 Npm 版本:npm -v
将 Node 应用程序目录添加到系统环境变量中, 然后重新启动命令行工具再次执行 node 命令.
msiexec /package node-v10.15.0-x64.msi
运行 Node 应用程序安装包function sayHello (name) {
console.log('Hello' + name)
}
sayHello('Node')
在命令行工具中通过 node JavaScript 文件
的方式执行代码。
console.log(window) // window is not defined
在 Node.js 环境中是没有 window 的,所以 window 对象自然是未定义的。
在 Node.js 环境中全局对象为 global,在 global 对象中会存在一些和 window 对象中名字相同且作用相同的方。
global.console.log
global.setInterval
global.clearInterval
global.setTimeout
global.clearTimeout
global.setImmediate
在 Node.js 环境中声明的变量不会被添加到全局对象中,变量声明后只能在当前文件中使用。
var message = "hello"
console.log(global.message) // undefined
在 Node.js 环境中,默认就支持模块系统,该模块系统遵循 CommonJS 规范。
一个 JavaScript 文件就是一个模块,在模块文件中定义的变量和函数默认只能在模块文件内部使用,如果需要在其他文件中使用,必须显式声明将其进行导出。
在每一个模块文件中,都会存在一个 module 对象,即模块对象。在模块对象中保存了和当前模块相关信息。
在模块对象中有一个属性 exports,它的值是一个对象,模块内部需要被导出的成员都应该存储在到这个对象中。
Module {
exports: {
}
}
// logger.js
const url = "http://mylogger.io/log";
function log (message) {
console.log(message)
}
module.exports.endPoint = url
module.exports.log = log
在其他文件中通过 require 方法引入模块,require 方法的返回值就是对应模块的 module.exports 对象。
在导入模块时,模块文件后缀 .js 可以省略,文件路径不可省略。
require 方法属于同步导入模块,模块导入后可以立即使用。
// app.js
const logger = require("./logger")
console.log(logger) // { endPoint: 'http://mylogger.io/log', log: [Function: log] }
console.log(logger.endPoint) // http://mylogger.io/log
logger.log('Hello Module') // Hello Node
通过 require 方法引入模块时会执行该模块中的代码。
// logger.js
console.log("running...")
// app.js
require("./logger") // running...
在导入其他模块时,建议使用 const 关键字声明常量,防止模块被重置。
var logger = require("./logger")
logger = 1;
logger.log("Hello") // logger.log is not a function
const logger = require("./logger")
logger = 1; // Assignment to constant variable.
logger.log("Hello")
有时在一个模块中只会导出一个成员,为方便其他模块使用,可以采用以下导入方式。
// logger.js
module.exports = function (message) {
console.log(message)
}
// app.js
const logger = require("./logger")
logger("Hello")
Node.js 是如何实现模块的,为什么在模块文件内部定义的变量在模块文件外部访问不到?
每一个模块文件中都会有 module 对象和 require 方法,它们是从哪来的?
在模块文件执行之前,模块文件中的代码会被包裹在模块包装函数当中,这样每个模块文件中的代码就都拥有了自己的作用域,所以在模块外部就不能访问模块内部的成员了。
(function(exports, require, module, __filename, __dirname) {
// entire module code lives here
});
从这个模块包装函数中可以看到,module 和 require 实际上模块内部成员, 不是全局对象 global 下面的属性。
__filename:当前模块文件名称。
__dirname:当前文件所在路径。
exports:引用地址指向了 module.exports 对象,可以理解为是 module.exports 对象的简写形式。
exports.endPoint = url;
exports.log = log
在导入模块时最终导入的是 module.exports 对象,所以在使用 exports 对象添加导出成员时不能修改引用地址。
exports = log //这是错误的写法.
在 Node.js 安装完成后,会内置一些非常有用的模块。
Path:模块内提供了一些和路径操作相关的方法。
File system:文件操作系统,提供了和操作文件相关的方法。
在引入内置模块时, 使用的是模块的名字,前面不需要加任何路径。
const path = require("path")
console.log(path.parse(__filename))
{
root: '/',
dir: '/Users/administrators/Desktop/node_test',
base: 'app.js',
ext: '.js',
name: 'app'
}
const fs = require("fs")
const files = fs.readdirSync("./")
console.log(files) [ 'app.js', 'logger.js' ]
fs.readdir("./", function (error, files) {
console.log(error) // null | Error {}
console.log(files) // [ 'app.js', 'logger.js' ] | undefined
})
每一个基于 Node.js 平台开发的应用程序都是 Node.js 软件包。
所有 Node.js 软件包都被托管在 www.npmjs.com 中。
Node Package Manager,Node.js 环境中的软件包管理器。随 Node.js 一起被安装。
它可以将 Node 软件包添加到我们的应用程序中并对其进行管理,比如下载,删除,更新,查看版本等等。
它没有用户界面,需要在命令行工具中通过命令的方式使用,对应的命令就是 npm。
NPM 和 Node 是两个独立的应用程序,只是被捆绑安装了,可以通过版本号证明。
Node.js 规定在每一个软件包中都必须包含一个叫做 package.json 的文件。
它是应用程序的描述文件,包含和应用程序相关的信息,比如应用名称,应用版本,应用作者等等。
通过 package.json 文件可以方便管理应用和发布应用。
创建 package.json 文件: npm init
快速创建 package.json 文件: npm init --yes
{
"name": "project-name",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
在应用程序的根目录执行命令:npm install <pkg>
或者 npm i <pkg>
npm install lodash
软件包下载完成后会发生三件事:
package.json
文件中. 包含软件包的名字以及版本号。
package-lock.json
文件, 用于记录软件包及软件包的依赖包的下载地址及版本。
在引入第三方软件包时,在 require 方法中不需要加入路径信息,只需要使用软件包的名字即可,require 方法会自动去 node_modules 文件夹中进行查找。
const _ = require("lodash")
const array = ["a", "b", "c", "d"]
// chunk 对数组中的元素进行分组
// 参数一表示要进行操作的数组
// 参数二表示每一组中包含的元素个数
console.log(_.chunk(array, 2)) // [ [ 'a', 'b' ], [ 'c', 'd' ] ]
Major Version 主要版本
:添加新功能 (破坏现有 API) -> 6.0.0
Minor version 次要版本
:添加新功能 (不会破坏现有 API, 在现有 API 的基础上进行添加) -> 5.13.0
Patch version 补丁版本
:用于修复 bug -> 5.12.6
当过了一段时间以后,其他人从版本库中下载了你的应用程序,并通过 npm install
命令恢复了应用程序的依赖软件包,但是此时应用程序的依赖软件包版本可能会发生变化,而应用程序的 package.json 文件中记录的只是大致版本,如何查看依赖软件包的具体版本呢?
方式一:在 node_modules 文件夹中找到对应的依赖软件包,找到它的 package.json 文件,可以在这个文件中的 version 字段中找到它的具体版本。
方式二:通过 npm list
命令查看所有依赖软件包的具体版本, –depth 选项指定查看依赖包的层级。
npm view mongoose
npm view mongoose versions
npm view mongoose dist-tags dependencies
npm i <pkg>@<version>
npm i mongoose@2.4.2 lodash@4.7.0
cat package.json
npm list --depth 0
npm uninstall <pkg>
npm uninstall mongoose
npm un mongoose
通过 npm outdated
命令可以查看哪些软件包已经过期,对应的新版本是什么。
通过 npm update
更新过期的软件包,更新操作遵循语义版本控制规则。
项目依赖:无论在开发环境还是线上环境只要程序在运行的过程中需要使用的软件包就是项目依赖。比如 lodash,mongoose。
开发依赖:在应用开发阶段使用,在生产环境中不需要使用的软件包,比如 TypeScript 中的类型声明文件。
在 package.json
文件中, 项目依赖和开发依赖要分别记录,项目依赖被记录在 dependencies
对象中,开发依赖被记录在 devDependencies
中,使开发者可以在不同的环境中下载不同的依赖软件包。
在下载开发依赖时,要在命令的后面加上 --save-dev
选项或者 -D
选项。npm i eslint -D
在开发坏境中下载所有依赖软件包: npm install
在生产环境中只下载项目依赖软件包: npm install --prod
-g
选项将软件包安装到全局:npm install <pkg> -g
查看全局软件包安装位置:npm root -g
删除全局中的软件包: npm un npm-check-updates -g
查看全局中安装了哪些软件包: npm list -g --depth 0
查看全局中有哪些过期软件包: npm outdated -g
npm install nodemon@2.0.7 -g
nodemon app.js
package.json
文件中软件包版本
npm-check-updates
安装到全局: npm install npm-check-updates -g
npm-check-updates
ncu -u
npm i
npm outdated
或 npm-check-updates
在软件包的源代码发生更改后, 是不能直接发布的, 应该新更新软件包的版本号然后再进行发布.
更新主要版本号:npm version major
更新次要版本号:npm version minor
更新补丁版本号:npm version patch
npm unpublish <pkg> --force
由于 npmjs.com 是国外的网站,大多数时候下载软件包的速度会比较慢,如何解决呢?
可以通过配置的方式更改 npm 工具的下载地址。
npx 是 npm 软件包提供的命令,它是 Node.js 平台下软件包执行器。主要用途有两个,第一个是临时安装软件包执行后删除它,第二个是执行本地安装的提供命令的软件包。
将所有软件包安装到应用本地是现在最推荐的做法,一是可以防止软件包的版本冲突问题,二是其他开发者在恢复应用依赖时可以恢复全部依赖,因为软件包安装到本地后会被 package.json 文件记录,其他开发者在运行项目时不会因为缺少依赖而报错。
应用程序入口文件就是应用程序执行的起点,就是启动应用程序时执行的文件。
场景一:其他开发者拿到你的软件包以后,通过该文件可以知道应用的入口文件是谁,通过入口文件启动应用。
场景二:通过 node 应用文件夹
命令启动应用。node 命令会执行 package.json 文件中 main 选项指定的入口文件,如果没有指定入口文件,则执行 index.js。
获取免费软件资源、交流前端技术—WX:NY378599
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/160206.html原文链接:https://javaforall.cn