node
1、介绍和知识梳理
-
为电脑提供一个可以脱离浏览器运行 JS 的环境
-
node安装完成后,会提供一个 REPL 环境 可交互式命令行工具
- 提供对于模块的加载功能(一组功能封装后的文件)
- 内置模块:node环境安装时的自带功能
- 三方模块:开发者针对于Node环境开发的可运行的 ,独立文件
- 开发者开发且开源的模块 (npm网站上锁看到的都是)
- 自行开发的且只为当前项目准备模块
- 提供对于模块的加载功能(一组功能封装后的文件)
-
gulp,webpack,less,sass,grunt,fix……
-
基于JS的开发模式
- AMD : 依赖前置:require.js – 将项目中的功能拆分成多个 JS 文件,以工具模块的形式定义在项目中,如果一个页面需要使用某个JS文件中方法,需要在页面加载时就对该方法进行引入
- CMD:依赖就近:sea.js – 将项目中的功能拆分成多个 JS 文件,以工具模块的形式定义在项目中,如果一个页面需要使用某个JS文件中方法,只需要在使用之前进行方法的引入
-
node的模块化是一个典型的 AMD 模块系统,借鉴了 require.js 的设计方式
-
ES6 中提出的 模块化开发,本身也是借鉴了 require.js 的设计方式
gulp grunt …… 自动化工作流 ==> 开发效率的提示 (css js 压缩混淆,图片的压缩,动态语言的自动编译)
webpack 模块化的开发核心
bable ES语法的兼容转换
ESLINT 语法规范校验
2、回忆node的基本应用
/*
1、加载 node环境下服务的基础模块 http
2、创建 根据http模块对象 构建服务器的基础功能
3、定义 根据创建的server 定义服务器启动默认端口和提示信息
*/
const http = require("http");
// 请求达到,请求响应
const server = http.createServer(function(request,response){
/*
页面显示乱码
+ 从前端角度
- 展示乱码 :在浏览器的调试窗口下文字显示正常
将页面的展示字符集 和 后端响应的字符保持一致
> 1、页面解决(页面和后端是独立的)
> 2、后端代码解决 (页面和后端的代码混合的)
- 响应乱码 : 在浏览器的调试窗口下文字显示依然乱码
> 后端响应的字符为乱码,由后端解决
* 服务运行时的乱码:后端代码对数据进行处理时出现乱码错误
* 数据由数据库获取,但数据库的响应字符集和 后端代码的字符集 不匹配导致
*/
// 设置响应的返回状态
response.writeHead(200,{
'Content-Type': 'text/html; charset="UTF-8"'
})
// 每个请求必须要有一个响应
response.write("<h1>hello 新年</h1>"); // 响应写出
// 每个请求必须完成响应结束符的定义
response.end();
});
server.listen(3000,function(error){
if(error){
console.log("服务器启动失败:",error);
}else{
console.log("服务器启动成功,端口号 3000");
}
});
3、node环境下的模块机制
3.1、node模块定义
-
直接定义 一个普通的JSON或JS文件 ,就可以作为 node的模块使用
-
模块定义是允许 模块嵌套的
-
方式1:通过关键字
exports
进行模块的功能导出
console.log("02模块");
function show(){
console.log("02模块的show方法");
}
// console.log(typeof exports);
// 意义:在exports 对象中定义一个属性 show ,对应的值是 当前文件中的show方法
exports.show = show;
系统命令
查看当前目录下的文件和文件夹 mac|liunx 使用 ls ; widnows 使用 dir
- 方式2:关键对象
module
- 当前模块的描述信息和运行功能
Module {
// 当前模块的ID 唯一
id: 'D:\\Users\\User\\Desktop\\node\\code\\node_modules\\03module.js',
// 当前模块所导出的 功能
exports:{
print: [Function],
name: 'module03',
msg: '模块的字符串',
user: { name: 'tom', age: 23 }
},
// 当前模块的父级模块 =>
parent:
Module {
id: '.',
exports: {},
parent: null,
filename: 'D:\\Users\\User\\Desktop\\node\\code\\test\\03-test.js',
loaded: false,
children: [ [Circular] ],
paths:
[ 'D:\\Users\\User\\Desktop\\node\\code\\test\\node_modules',
'D:\\Users\\User\\Desktop\\node\\code\\node_modules',
'D:\\Users\\User\\Desktop\\node\\node_modules',
'D:\\Users\\User\\Desktop\\node_modules',
'D:\\Users\\User\\node_modules',
'D:\\Users\\node_modules',
'D:\\node_modules' ] },
filename:
'D:\\Users\\User\\Desktop\\node\\code\\node_modules\\03module.js',
loaded: false,
// 子模块
children: [],
// 当前模块所允许的搜索路径
paths:
[
'D:\\Users\\User\\Desktop\\node\\code\\node_modules',
'D:\\Users\\User\\Desktop\\node\\node_modules',
'D:\\Users\\User\\Desktop\\node_modules',
'D:\\Users\\User\\node_modules',
'D:\\Users\\node_modules',
'D:\\node_modules'
]
}
- 模块包装器的解释
let require = (function(
// 形参作用域操作赋值
module={
exports:{}
},
exports=module.exports
){
// 定义模块的代码
var num = 200;
var fun = function(){};
// exports.num = num;
// exports.fun = fun;
// module.exports.num = num;
// module.exports.fun = fun;
// exports = {
// num,fun
// }
// module.exports = {
// num,fun
// }
exports.fun = fun;
module.exports = {
num
}
// 定义模块的代码
return module.exports;
});
var obj = require();
console.log(obj);
- 当模块定义时使用了 modules.exports = {} 的方式时,整个模块中的 exports.属性=值 的方式将全部失效
- 基本上都会使用 方式2进行 功能的导出
// (function(exports, require, module, __filename, __dirname) {
var num = 100;
let obj = {
a:"aaa",
b:"ccc"
}
let fun = function(){
}
let str = "aaaa";
// exports.num = num;
// exports.obj = obj;
// exports.fun = fun;
// exports = {
// num,obj,fun
// }
// module.exports.num = num;
// module.exports.obj = obj;
// module.exports.fun = fun;
module.exports = {
num,obj,fun,str
}
// 模块的代码实际上在这里
// })
3.1.1、文件夹式模块
3.2、node模块加载
- 通过 require(path) 完成模块的加载
- 实际加载是 一组具有特点功能的文件
- 调用时需要的参数 path ,指的是 被加载的模块的 文件路径
- 问题1:为什么 require(“http”) 没有后缀名称
- 原因1:node环境下进行模块加载时 ,如果模块为node环境的核心模块,必须省略扩展名
- 原因2:node环境会根据内部的加载机制 ,自动为所装载非核心模块 补充扩展名
- 如果按确切的文件名没有找到模块,则 Node.js 会尝试带上
.js
、.json
或.node
拓展名再加载。- **【
.js
、.json
.node
】 数组的顺序就是加载顺序 **
- **【
- 如果按确切的文件名没有找到模块,则 Node.js 会尝试带上
- 问题2:为什么 require(“http”) 没有路径定义
- 原因:node对路径的加载机制进行了重新的设计
- 没有前缀
- 核心模块加载 ==> 从node安装环境中加载 核心模块功能
- 不是核心模块 ==> 以搜索方式 从 node_modules 中进行加载
- 搜索方式会随着系统的变换而发生变化
- 循环当前模块中
paths
属性进行 寻找和加载 ,paths属性会随系统变换而变换
- 循环当前模块中
- 文件夹内搜索
- 先 寻找 package.json 中的 main 属性的指向文件作为 入口文件
- 如果不存在上述情况,才会寻找 当前目录中入口文件 【index.js index.json】
- 搜索方式会随着系统的变换而发生变化
- ./ 相对于当前文件的 同级目录
- …/ 相对于当前文件的上级目录
- 没有前缀
- 原因:node对路径的加载机制进行了重新的设计
4、node path模块的使用
-
node环境下的核心模块
-
对项目的字符路径进行处理
- 将相对路径转换为绝对路径
-
path.join(path1,path2,……)
作用路径拼接 -
path.resolve([from...,] to)
将to参数解析为 绝对路径 -
path.relative([from...,] to)
将to参数解析为 相对路径 -
path.isAsolute(path)
判断给定的字符串是不是 绝对路径 返回的值为 true false
const path = require("path");
// console.log(path);
console.log(__dirname);
let newPath1 = path.join(__dirname,"./abc.js");
console.log(newPath1)
let newPath2 = path.join(__dirname,"../../abc.js");
console.log(newPath2)
console.log("-------");
let newPath3 = path.resolve('./abc.css');
console.log(newPath3);
let newPath4 = path.resolve('../abc','./abc.css');
console.log(newPath4);
let newPath5 = path.resolve('../abc','./aaa','./abc.css');
console.log(newPath5);
console.log(path.isAbsolute("./aaa.js"));
console.log(path.isAbsolute("C:/aaa.js"));
// 将文件路径 按照当前文件所在目录进行 路径的转换
let newPath6 = path.relative("","D:/aaa/ccc/dddd/aa.js");
console.log(newPath6);
let newPath7 = path.relative("D:/aaa/ccc","D:/aaa/ccc/dddd/aa.js");
console.log(newPath7);
预热
1、需要当前计算机具有 node 环境基础
node -v
2、需要npm的支持
npm -v node损坏了 node没装
2.1、安装npm的中国代理 nrm 全局组件的安装
npm install nrm -g
3、安装vue模块化环境构建工具 (CLI == commond line interface 脚手架)
npm install vue-cli -g
提供控制台命令 vue
初始化项目 vue init webpack 项目名称
进入项目目录 执行 npm start 启动项目