Node.js的学习(二)node.js 模块化
一、Node.js模块化
1、模块化概要
早期的javascript版本没有块级作用域、没有类、没有包、也没有模块,这样会带来一些问题,如复用、依赖、冲突、代码组织混乱等,随着前端的膨胀,模块化显得非常迫切。
通俗点来说:模块化就是把手机变成一个一个零件,可以拼装,哪个零件坏了可以换,就不用整个手机都需要换,就像搭积木一样

前端模块化规范如下:

常见的的JavaScript模块规范有:CommonJS、AMD、CMD、UMD、原生模块化(ES6的时候有学)
模块化是指解决一个复杂问题时,自顶向下逐层把系统划分成若干模块的过程。对于整个系统来说,模块是可组合、分解和更换 的单元
JavaScript在早期的设计中就没有模块、包、类的概念,开发者需要模拟出类似的功能,来隔离、组织复杂的JavaScript代码,我们称为模块化。
模块就是一个实现特定功能的文件,有了模块我们就可以更方便的使用别人的代码,要用什么功能就加载什么模块。
2、模块化开发的四点好处:
(1)、避免变量污染,命名冲突
(2)、提高代码复用率
(3)、提高了可维护性
(4)、方便依赖关系管理
nodejs 中根据模块的来源不同,将模块分为了3大类,分别是:
- 内置模块(内置模块是由Node.js官方提供的,例如fs、path、http等)
- 自定义模块 (用户创建的每个 .js文件,都是自定义模块)
- 第三方模块 (由第三方开发出来的模块,并非官方提供的内置模块,也不是用户创建的自定义模块,使用前需要先下载)
3、模块作用域
和函数作用域类似,在自定义模块中定义的变量、方法等成员,只能在当前模块内被访问,这种模块级别的访问限制,叫做模块作用域。
模块作用域的好处:防止了全局变量污染的问题
4、变量作用域
(1)、在浏览器端使用var或不使用关键字定义的变量属于全局作用域,也就是可以使用window对象访问。
<script>
var a = 100; (function () {
b = 200;
})(); console.log(window.a, a);
console.log(window.b, b);
</script>
结果:

(2)、在 Node.js 中没有 window 对象

(3)、在Node.js的交互环境下,定义的变量属于global,global是类似浏览器端的window对象

(4)、在模块中(文件中)有global对象,使用关键字var,let,const定义的成员不属于global对象,仅在当前模块中有效,而不使用关键字定义的对象属于global对象。
var a=100;
b=200;
let c=300;
const d=400;
console.log(global);
console.log(global.a);
console.log(global.b);
console.log(global.c);
console.log(global.d);
终端输出:

5、CommonJS
CommonJS就是一个JavaScript模块化的规范,该规范最初是用在服务器端 NodeJS 中,前端的 webpack 也是对CommonJS原生支持的。
根据这个规范
(1)、每一个文件就是一个模块,其内部定义的变量是属于这个模块的,不会对外暴露,也就是说不会污染全局变量。
(2)、导入自定义的模块时路径需要以 ./ 或 ../ 开始,同一路径下也不能省略。
(3)、如果反复多次require模块,只加载一次。
(4)、require引入模块时,后缀名.js可以省略
(5)、每个模块文件都是一个独立的函数级作用域,在其它模块中不能直接访问
举个栗子:
m1.js 文件代码:
console.log("这是模块m1");
let a=100;
b=200;
m2.js 文件代码:
var m11=require("./m1");
console.log(a);
console.log(b);
结果:

从上面的示例可以看出a在模块2中是访问不到的,模块其实就是一个封闭的函数:
m1.js 文件的代码:
console.log("这是模块m1");
let a=100;
b=200;
//输出当前函数
console.log(arguments.callee+"");
输出结果:

(6)、每个模块中都包含如下5个对象:
exports:导出对象,默认为{}

require:导入函数,使用该函数可以实现模块的依赖

module:模块信息,用于记录当前模块的所有信息

__filename:当前模块的文件全路径,含文件名

__dirname:当前模块的文件路径,不含文件名

(7)、使用exports或module.exports对象可以将当前模块中需要导出的内容暴露出去。
m4.js 文件代码:
let a=100;
let b=()=>{
return 200;
};
exports.a=a;
exports.b=b;
m5.js 文件代码:
const m1=require("./m1");
console.log(m1);
console.log(m1.a);
console.log(m1.b());
运行结果:

(8)、导入模块内容可以结合结构语法
m6.js 文件代码:
exports.a=100;
exports.b=function(){
return 200;
};
m7.js 文件代码:
const {a,b:fun}=require("./m6");// 模块结合解构
console.log(a);
console.log(fun());
运行结果:

二、Node.js 文件系统
2.1、概要
Node.js 提供一组类似 UNIX(POSIX)标准的文件操作API。 Node 导入文件系统模块(fs)语法如下所示:
var fs = require("fs")
2.3、异步与同步
Node.js 文件系统(fs 模块)模块中的方法均有 异步和同步 版本,例如读取文件内容的函数有异步的 fs.readFile() 和同步的 fs.readFileSync()。
异步的方法函数最后一个参数为回调函数,回调函数的第一个参数包含了错误信息(error)。
建议大家是用异步方法,比起同步,异步方法性能更高,速度更快,而且没有阻塞。
实例
创建 input.txt 文件,内容如下:
foo
创建 filereaddemo.js 文件, 代码如下:
const fs=require("fs"); //依赖内置模块fs,用于文件管理
//异步读取文件index.txt,设置读取成功时的回调函数,err表示错误信息,data表示数据
fs.readFile("index.txt",function(err,data){
if(err) throw err; // 抛出异常
console.log("异步:"+data+"");
});
console.log("---------------");
//同步读取
let data=fs.readFileSync("index.txt");
console.log("同步:"+data+"");
运行结果:

注意:异步完成时间是不确定的,一般异步完成时间最慢!!!
2.2、写入文件
创建 file.js 文件,代码如下所示:
const fs=require("fs");
// 异步写入文件
fs.writeFile("output1.txt","异步hello","utf-8",function(err){
if(!err){
console.log("异步文件写入成功!");
}
else{
throw err;
}
});
console.log("---------------");
// 同步写入文件
fs.writeFileSync("output2.txt","同步hello","utf-8");
console.log("同步文件写入成功");
运行结果:



2.3、获取文件信息
以下为通过异步模式获取文件信息的语法格式:
fs.stat(path, callback)
参数使用说明如下:
path - 文件路径。
callback - 回调函数,带有两个参数如:(err, stats), stats 是 fs.Stats 对象。
fs.stat(path)执行后,会将stats类的实例返回给其回调函数。可以通过stats类中的提供方法判断文件的相关属性。例如判断是否为文件:
创建一个 isfile 文件,代码如下:
// 判断是否为文件:
const fs=require("fs"); // 获取文件信息
fs.stat("student.txt",(err,stats)=>{
console.log("是文件吗?"+stats.isFile());
console.log("是目录吗?"+stats.isDirectory());
console.log(stats);
});
运行结果:

stats类中的方法有:

2.4、删除文件
以下为删除文件的语法格式:
fs.unlink(path, callback)
参数使用说明如下:
path - 文件路径。
callback - 回调函数,没有参数。
创建 deleteFile.js 文件,代码如下:
const fs=require("fs");
fs.unlink("output1.txt",function(err){
if(err){
throw err;
}
else{
console.log("异步删除文件成功!");
}
});
console.log("--------------------");
fs.unlinkSync("output2.txt");
console.log("同步删除文件成功!");
运行结果:

2.5、创建目录
以下为创建目录的语法格式:
fs.mkdir(path[, mode], callback)
参数使用说明如下:
path - 文件路径。
mode - 设置目录权限,默认为 0777。
callback - 回调函数,没有参数。
创建mkdirfile.js 文件,代码如下所示:
const fs=require("fs");
fs.mkdir("dir1",function(err){
if(err){
throw err;
}
else{
console.log("异步创建目录成功!");
}
});
console.log("---------------------");
fs.mkdirSync("dir2");
console.log("同步创建目录成功!");
运行结果:


2.6、读取目录
以下为读取目录的语法格式:
fs.readdir(path, callback)
参数使用说明如下:
path - 文件路径。
callback - 回调函数,回调函数带有两个参数err, files,err 为错误信息,files 为 目录下的文件数组列表。
创建 readDirectory.js 文件,代码如下:
// 读取目录
const fs=require("fs"); // 异步
fs.readdir("dir1",(err,files)=>{
if(err)
{throw err;}
else{
console.log("异步获取目录下的文件成功!");
files.forEach(file=>console.log(file));
}
});
console.log("-----------------------"); // 同步
let files=fs.readdirSync("dir2");
console.log("同步获取目录下的文件成功!");
files.forEach(file=>console.log(file));
运行结果:


2.7、删除空目录
以下为删除空目录的语法格式:
fs.rmdir(path, callback)
参数使用说明如下:
path - 文件路径。
callback - 回调函数,没有参数。
接下来我们创建 delDirectory.js 文件,代码如下所示:
var fs = require("fs");
// 异步删除
fs.rmdir("dir1",function(err){
if(err){
throw err;
}
else{
console.log("异步删除目录成功");
}
});
console.log("=================================");
// 同步删除
// recursive:递归删除
fs.rmdirSync("dir2");
console.log("同步删除目录成功");
运行结果:

2.8、删除非空目录
以下为删除非空目录的语法格式:
fs.rm(path,callback);
创建一个delDirectory2.js 文件,代码如下:
var fs = require("fs");
// 异步删除非空目录
fs.rm("dir1",{recursive: true},err=>{
if (err) {
throw err;
}
console.log("异步删除非空目录成功!");
});
运行结果:

三、参数与环境变量
3.1、读取package.json文件配置参数
创立一个 config 目录并向其中增加一个 config/default.json 文件。这将是默认配置文件,并将蕴含所有默认环境变量。
获取配置的内容:
process.env['npm_package_config_xxxxxx']
在咱们的示例应用程序中它应该是这样的:
在 package.json 文件中,新添加一个 “ config ” ,然后设置一些自定义的参数:

然后新建一个config.js 文件,代码如下:
console.log(process.env.npm_package_config_foo);
请注意:要是直接运行,它的值为:undefined,如何解决?解决方法如下:
(1)在package.json文件中的 scripts中添加一行 “ start ”:node 要运行的文件名

(2)在终端哪里,输入命令:npm run start 回车,即可解决

3.2、读取自定义配置文件数据
首先创建一个 default.json 文件,代码如下:
{
"student":{
"name":"tom",
"age":"18"
}
}
先依赖模块config,命令如下:
npm i config

咱们将在咱们的应用程序中通过导入 config 和应用 get 办法拜访变量来访问它,代码如下:
const config = require("config");
console.log(config);
console.log(config.get("student.name"));
console.log(config.get("student.age"));
运行结果:

3.3、使用evn、dotenv依赖读取参数
(1)首先导入依赖:
npm i dotenv //依赖模块

(2)自定义创建 .env 文件代码如下:
USER_ID="239482"
USER_KEY="foobar"
NODE_ENV="development"
(3)自定义创建 env.js 文件代码如下:
require("dotenv").config();
console.log(process.env.USER_ID);
运行结果:

3.4、环境变量的设置与读取
3.4.1、查看当前所有可用的环境变量
命令如下:
set

3.4.2、查看某个环境变量
命令如下:
set 变量名
具体操作步骤如下:
首先在电脑上的属性 -> 高级系统设置中,新添加一个环境变量

请注意:在环境变量中添加或修改了变量,需要重启电脑!!!
运行结果如下:


3.4.3、修改环境变量
请注意:所有的在cmd命令行下对环境变量的修改只对当前窗口有效,不是永久性的修改。也就是说当关闭此cmd命令行窗口后,将不再起作用。
修改环境变量命令如下:
set 变量名=变量内容
运行结果:

请注意,此修改环境变量是指用现在的内容去覆盖以前的内容
3.4.4、修改环境变量为空
命令如下:
"set 变量名="
3.4.5、给变量追加内容
命令如下:
“set 变量名=%变量名%;变量内容”
3.4.6、修改环境变量的值并访问
命令如下:
set a=900 && node envcfg.js
运行结果如下:

Node.js的学习(二)node.js 模块化的更多相关文章
- vue.js 源代码学习笔记 ----- codegen.js
/* @flow */ import { genHandlers } from './events' import { baseWarn, pluckModuleFunction } from '.. ...
- Node.js基础学习二之POST请求
本篇介绍下 Node.js post 请求 需求: 用户登录,前端界面输入用户名和密码,点击登录请求后台验证,根据后台反馈的信息做出响应 前端: (1)使用form表单 (2)使用ajax异步请求 服 ...
- D3.js 入门学习(二) V4的改动
//d3.scan /* 新的d3.scan方法对数组进行线性扫描,并根据指定的比较函数返回至少一个元素的索引. 这个方法有点类似于d3.min和d3.max. 而d3.scan可以得到极值的索引而不 ...
- vue.js 源代码学习笔记 ----- html-parse.js
/** * Not type-checking this file because it's mostly vendor code. */ /*! * HTML Parser By John Resi ...
- vue.js 源代码学习笔记 ----- helpers.js
/* @flow */ import { parseFilters } from './parser/filter-parser' export function baseWarn (msg: str ...
- vue.js 源代码学习笔记 ----- codegenEvents.js
/* @flow */ const fnExpRE = /^\s*([\w$_]+|\([^)]*?\))\s*=>|^function\s*\(/ const simplePathRE = / ...
- vue.js 源代码学习笔记 ----- fillter-parse.js
/* @flow */ export function parseFilters (exp: string): string { let inSingle = false let inDouble = ...
- vue.js 源代码学习笔记 ----- text-parse.js
/* @flow */ import { cached } from 'shared/util' import { parseFilters } from './filter-parser' //找到 ...
- 测试驱动开发(TDD)及测试框架Mocha.js入门学习
组里马上要转变开发模式,由传统的开发模式(Developer开发,QA测试),转变为尝试TDD(Test-driven development,测试驱动开发)的开发模型.由此将不存在QA的角色,或者仅 ...
- node.js入门学习(五)--Demo模块化改造
1.node.js中模块的分类 1)node.js内置模块(核心,原生) 所有内置模块在安装node.js时就已经编译成二进制文件,可以直接加载运行(速度较快),部分内置模块,在node.exe这个进 ...
随机推荐
- 如何自动清理 KingbaseES SYS_LOG
KingbaseES 初始化完成后,默认不会对 sys_log进行清理.如果需要对sys_log进行自动清理,需要设置相关参数. 与日志自动清理有关的参数(默认值)如下: log_filename | ...
- docker容器资源限制:限制容器对内存/CPU的访问
目录 一.系统环境 二.前言 三.docker对于CPU和内存的限制 3.1 限制容器对内存的访问 3.2 限制容器对CPU的访问 一.系统环境 服务器版本 docker软件版本 CPU架构 Cent ...
- MariaDB数据库 主-从 部署
〇.前言 好久没碰数据库了 准备环境: centos7自带的MariaDB,没有的话下面是安装命令 yum install -y mariadb mariadb-server systemctl re ...
- 华南理工大学 Python第1章课后小测
1.(单选)计算机有两个基本特性:功能性和()性.(本题分数:5)A) 可存储B) 可计算C) 可通信D) 可编程您的答案:D 正确率:100%2.(单选)计算机硬件可以直接识别和执行的程序设计语言 ...
- [Python]-sklearn.model_selection模块-处理数据集
拆分数据集train&test from sklearn.model_selection import train_test_split 可以按比例拆分数据集,分为train和test x_t ...
- Memlab,一款分析 JavaScript 堆并查找浏览器和 Node.js 中内存泄漏的开源框架
Memlab 是一款 E2E 测试和分析框架,用于发现 JavaScript 内存泄漏和优化机会. Memlab 是 JavaScript 的内存测试框架.它支持定义一个测试场景(使用 Puppete ...
- Java中的SPI原理浅谈
在面向对象的程序设计中,模块之间交互采用接口编程,通常情况下调用方不需要知道被调用方的内部实现细节,因为一旦涉及到了具体实现,如果需要换一种实现就需要修改代码,这违反了程序设计的"开闭原则& ...
- .NET 部署Https(SSL)通过代码方式
在上一个文章中,传送门,给大家介绍了怎么在配置文件中使用 Kestrel 部署 Https,正好今天有小伙伴稳问到:可以通过代码的方式实现 Kestrel 的 Https 的部署吗?答案是肯定的,我们 ...
- Dockerfile文件:设置变量启动的时候传递进去
from openjdk:8-jdk-alpine RUN ln -sf /usr/share/zoneinfo/Asia/shanghai /etc/localtime RUN echo 'Asia ...
- PPR管的熔接
1. 热熔器的介绍 2. 用热熔器熔接PPR管