[03] Node.js
1. Node.js 概述
脚本语言需要一个解析器才能运行,JavaScript 是脚本语言,在不同的位置有不一样的解析器。如写入 html 的 JS,浏览器是它的解析器角色;而对于需要独立运行的 JS,Node.js 就是一个解析器。
每一种解析器都是一个运行环境,不但允许 JS 定义各种数据结构,进行各种计算,还允许 JS 使用允许环境提供的内置对象和方法做一些事情。如运行在浏览器中的 JS 的用途是操作 DOM,浏览器就提供了 document 之类的内置对象。而运行在 Node.js 中的 JS 的用途是操作磁盘文件或搭建 http 服务器,Node.js 就相应提供了 fs,http 等内置对象。
浏览器的内核包括两部分核心:DOM 渲染引擎、JS 解析器(JS 引擎)。JS 运行在浏览器中的内核中的 JS 引擎内部,而 Node.js 是脱离浏览器环境运行的 JavaScript 程序,基于 Google V8 引擎(Chrome 的 JavaScript 的引擎)。
【官网】http://nodejs.cn/download/
安装完毕后,cmd 窗口输入 node -v
查看版本(是否安装成功)。
1. 创建文件 test.js
console.log('Hello! Node.js');
2. 打开 cmd 窗口,进入到该 js 文件所在目录,使用命令 node test.js
3. 在 VSCode 中打开 cmd 窗口,进行 JS 代码的执行。
3. 服务器端应用开发
1. 创建 server.js
const http = require('http');
http.createServer(function (request, response) {
// 发送 HTTP 头部
// HTTP 状态值: 200 : OK
// 内容类型: text/plain
response.writeHead(200, {'Content-Type': 'text/plain'});
// 发送响应数据 "Hello World"
response.end('Hello Server');
}).listen(8888);
// 终端打印如下信息
console.log('Server running at http://127.0.0.1:8888/');
2. 运行服务器程序
3. 服务器启动成功后,在浏览器中输入:http://localhost:8888/ 查看页面
4. npm 包管理器
4.1 npm 简述
NPM 全称 Node Package Manager,是 Node.js 包管理工具,是全球最大的模块生态系统,里面所有的模块都是开源免费的。
在后端开发中,使用 Maven 构建项目,管理 jar 依赖,联网下载依赖。NPM 也是 Node.js 的包管理工具,相当于前端的 Maven,管理前端的 JS 依赖,联网下载 JS 依赖,如 jQuery。
我们通过 npm
可以很方便地下载 js 库,管理前端工程。
Node.js 默认安装的 NPM 包和工具的位置:%Node.js_HOME%\node_modules
在这个目录下你可以看见 npm 目录,npm 本身就是被 NPM 包管理器管理的一个工具,说明 Node.js 已经集成了 npm 工具。
4.2 使用 npm 管理项目
4.2.1 项目初始化
新建文件夹 npm_demo,右键终端中打开,输入命令:npm -init
(如果用的都是默认值,加选项 -y
)
文件夹下会多出来一个叫 package.json 的文件。
4.2.2 修改 npm 镜像
NPM 官方的管理的包都是从 http://npmjs.com 下载的,但是这个网站在国内速度很慢。推荐使用淘宝 NPM 镜像 http://npm.taobao.org/ ,淘宝 NPM 镜像是一个完整 npmjs.com 镜像,同步频率目前为 10 分钟一次,以保证尽量与官方服务同步。
设置镜像地址:
# 经过下面的配置,以后所有的 npm install 都会经过淘宝的镜像地址下载
npm config set registry https://registry.npm.taobao.org
# 查看 npm 配置信息
npm config list
4.2.3 npm 下载 js 依赖
# 使用 npm install 安装依赖包的最新版,模块安装的位置:项目目录\node_modules
# 安装会自动在项目目录下添加 package-lock.json文件,这个文件帮助锁定安装包的版本。同时
# package.json 中,依赖包会被添加到 dependencies 节点下,类似 Maven 中的 <dependencies>
npm install jquery
# npm 管理的项目在备份和传输的时候一般不携带 node_modules 文件夹
# 直接根据 package.json 中的配置下载依赖,初始化项目
npm install
# 如果安装时想指定特定的版本
npm install jquery@2.1.x
# 1) 局部安装
# devDependencies节点:开发时的依赖包,项目打包到生产环境的时候不包含的依赖
# 使用 -D 参数将依赖添加到 devDependencies 节点
npm install --save-dev eslint
# 或
npm install -D eslint
# 2) 全局安装 [一些命令行工具常使用全局安装的方式]
# Node.js 全局安装的 npm 包和工具的位置:用户目录\AppData\Roaming\npm\node_modules
npm install -g webpack
4.2.4 其它命令
npm update 包名 # 更新包(更新到最新版本)
npm update -g 包名 # 全局更新
npm uninstall 包名 # 卸载包
npm uninstall -g 包名 # 全局卸载
5. babel 转码器
Babel 是一个广泛使用的转码器,可以将 ES6 代码转为 ES5 代码,从而在现有环境执行执行。这意味着,你可以现在就用 ES6 编写程序,而不用担心现有环境是否支持。
5.1 安装命令行转码工具
Babel 提供 babel-cli 工具,用于命令行转码。它的安装命令如下:
npm install --global babel-cli # 全局安装
babel --version # 查看是否安装成功
5.2 babel 的使用
1. 新建文件夹 babel_demo,初始化项目
npm init -y
2. 创建文件,babel_demo/es6/1.js
// 转码前
// 定义数据
let input = [1, 2, 3]
// 将数组的每个元素 +1
input = input.map(item => item + 1)
console.log(input)
3. 配置“.babelrc”。Babel 的配置文件是 .babelrc,存放在项目的根目录下,该文件用来设置转码规则和插件,基本格式如下。
{
"presets": [],
"plugins": []
}
presets 字段设定转码规则,将 es2015 规则加入 .babelrc:
4. 安装转码器
npm install --save-dev babel-preset-es2015
5. 转码
# 转码结果写入一个文件
mkdir dist1
# --out-file 或 -o 参数指定输出文件
babel es6/1.js --out-file es5/1.js
babel es6/1.js -o es5/1.js
# 整个目录转码
mkdir dist2
# --out-dir 或 -d 参数指定输出目录
babel src --out-dir dist2
babel src -d dist2
6. 前端模块化
6.1 模块化概念
- 开发后端接口时,编写 Controller/Service/Mapper,其中 Controller 注入 Service,Service 注入 Mapper。在后端中,类与类之间的调用称为“后端模块化操作”。
- 前端模块化:js 与 js 之间调用,就称为“前端模块化操作”→ 随着网站逐渐变成"互联网应用程序",嵌入网页的 Javascript 代码越来越庞大,越来越复杂。Javascript 模块化编程,已经成为一个迫切的需求。理想情况下,开发者只需要实现核心的业务逻辑,其他都可以加载别人已经写好的模块。但是,Javascript不是一种模块化编程语言,它不支持"类"(class),包(package)等概念,更遑论"模块"(module)了。
6.2 什么是模块化开发
传统非模块化开发有如下的缺点:
- 命名冲突
- 文件依赖
模块化规范:
- CommonJS(ES5) 模块化规范
- ES6 模块化规范
每个文件就是一个模块,有自己的作用域。在一个文件里面定义的变量、函数、类,都是私有的,对其他文件不可见。
6.3 CommonJS 模块化规范
CommonJS 使用
exports
和require
来导出、导入模块。
1. 新建文件夹 module_demo,进行项目初始化 npm init -y
2. 导出模块:新建文件 module_demo/es5/math.js
// 定义成员(创建方法):
const sum = function(a, b){
return parseInt(a) + parseInt(b)
}
const subtract = function(a, b) {
return parseInt(a) - parseInt(b)
}
const multiply = function(a, b) {
return parseInt(a) * parseInt(b)
}
const divide = function(a, b) {
return parseInt(a) / parseInt(b)
}
// 导出成员(设置哪些方法可以被其他js调用)
module.exports = {
// 供调用时的名称: Function名称
sum: sum,
subtract: subtract,
multiply: multiply,
divide: divide
}
// 简写
module.exports = {
sum,
subtract,
multiply,
divide
}
3. 导入模块:新建文件 module_demo/es5/invoke_math.js
// 引入模块,注意:当前路径必须写 ./
const math = require('./math.js')
console.log(math)
const result1 = math.sum1(1, 2)
const result2 = math.subtract1(1, 2)
console.log(result1, result2)
4. 运行程序
6.4 ES6 模块化规范
ES6 使用
export
和import
来导出、导入模块。
6.4.1 方式1
1. 导出模块,创建文件 module_es6/es6/api.js
export function getList() {
console.log('获取数据列表')
}
export function save() {
console.log('保存数据')
}
2. 导入模块,创建文件 module_es6/es6/invoke_api.js
// 只取需要的方法即可,多个方法用逗号分隔
import { getList, save } from "./api.js"
getList()
save()
3. 这时的程序无法运行的,因为 ES6 的模块化无法在 Node.js 中执行,需要用 Babel 编辑成 ES5 后再执行。
6.4.2 方式2
1. 导出模块,创建文件 module_es6/simple/es6/api.js
export default {
getList() {
console.log('获取数据列表')
},
save() {
console.log('保存数据')
}
}
2. 导入模块,创建文件 module_es6/simple/es6/invoke_api.js
import api from "./api.js"
api.getList()
api.save()
3. 同理,先转成 ES5:babel module_es6\simple\es6 -d module_es6\simple\es5
,再运行。
7. webpack
7.1 webpack 简述
Webpack 是一个前端资源加载/打包工具。它将根据模块的依赖关系进行静态分析,然后将这些模块按照指定的规则生成对应的静态资源。
从图中我们可以看出,Webpack 可以将多种静态资源 js、css、less 转换成一个静态文件,减少了页面的请求。
7.2 安装 webpack
npm install -g webpack webpack-cli # 全局安装 webpack、webpack-cli
webpack -v # 安装后查看版本号
7.3 JS 打包示例
1. 新建文件夹 webpack_demo
进入webpack目录,执行命令:npm init -y
2. 创建 src 文件夹
① src 下创建 common.js
exports.info = function (str) {
document.write(str); // 浏览器中输出
}
② src 下创建 utils.js
exports.add = function (a, b) {
return a + b;
}
③ src 下创建 main.js
const common = require('./common');
const utils = require('./utils');
common.info('Hello world!' + utils.add(6, 7));
3. webpack_demo 目录下创建配置文件 webpack.config.js(名字固定),读取当前项目目录下 src 文件夹中的 main.js(入口文件)内容,分析资源依赖,把相关的 js 文件打包,打包后的文件放入当前目录的 dist 文件夹下,打包后的 js 文件名为 bundle.js。
const path = require("path"); // Node.js内置模块
module.exports = {
entry: './src/main.js', // 配置入口文件
output: {
path: path.resolve(__dirname, './dist'), // 输出路径,__dirname:当前文件所在路径
filename: 'bundle.js' // 输出文件
}
}
4. 命令行执行编译命令;执行后查看 bundle.js 里面包含了上面两个 js 文件的内容。
webpack # 有黄色警告(并进行代码压缩)
webpack --mode=development # 没有警告 (development没压缩/production压缩)
也可以配置项目的 npm 运行命令,修改 package.json 文件;然后运行 npm 命令执行打包:npm run dev
。
"scripts": {
// ...,
"dev": "webpack --mode=development"
}
5. main.js 的效果必须在 html 页面上才能看到,故在 webpack_demo 目录下创建 index.html,引用 bundle.js。
<body>
<script src="dist/bundle.js"></script>
</body>
7.4 CSS 打包示例
1. 安装 style-loader 和 css-loader。Webpack 本身只能处理 JavaScript 模块,如果要处理其他类型的文件,就需要使用 Loader 进行转换。Loader 可以理解为是模块和资源的转换器。需要安装相关 Loader 插件,css-loader 是将 css 装载到 JavaScript,而 style-loader 是让 JavaScript 认识 css。
npm install --save-dev style-loader css-loader
2. 向 webpack.config.js 中追加内容
output: {...},
module: {
rules: [
{
test: /\.css$/, // 打包规则应用到以css结尾的文件上
use: ['style-loader', 'css-loader']
}
]
}
3. 在 src 文件夹创建 style.css,顺便修改 index.html 的 <body id="#bg">
#bg {
color: #fff;
height: 1500px;
background-color: #159957;
background-image: linear-gradient(120deg, #155799, #159957);
}
4. 修改 main.js,引入 style.css
require('./style.css');
5. 访问 index.html 查看效果