一、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 模块化的更多相关文章

  1. vue.js 源代码学习笔记 ----- codegen.js

    /* @flow */ import { genHandlers } from './events' import { baseWarn, pluckModuleFunction } from '.. ...

  2. Node.js基础学习二之POST请求

    本篇介绍下 Node.js post 请求 需求: 用户登录,前端界面输入用户名和密码,点击登录请求后台验证,根据后台反馈的信息做出响应 前端: (1)使用form表单 (2)使用ajax异步请求 服 ...

  3. D3.js 入门学习(二) V4的改动

    //d3.scan /* 新的d3.scan方法对数组进行线性扫描,并根据指定的比较函数返回至少一个元素的索引. 这个方法有点类似于d3.min和d3.max. 而d3.scan可以得到极值的索引而不 ...

  4. vue.js 源代码学习笔记 ----- html-parse.js

    /** * Not type-checking this file because it's mostly vendor code. */ /*! * HTML Parser By John Resi ...

  5. vue.js 源代码学习笔记 ----- helpers.js

    /* @flow */ import { parseFilters } from './parser/filter-parser' export function baseWarn (msg: str ...

  6. vue.js 源代码学习笔记 ----- codegenEvents.js

    /* @flow */ const fnExpRE = /^\s*([\w$_]+|\([^)]*?\))\s*=>|^function\s*\(/ const simplePathRE = / ...

  7. vue.js 源代码学习笔记 ----- fillter-parse.js

    /* @flow */ export function parseFilters (exp: string): string { let inSingle = false let inDouble = ...

  8. vue.js 源代码学习笔记 ----- text-parse.js

    /* @flow */ import { cached } from 'shared/util' import { parseFilters } from './filter-parser' //找到 ...

  9. 测试驱动开发(TDD)及测试框架Mocha.js入门学习

    组里马上要转变开发模式,由传统的开发模式(Developer开发,QA测试),转变为尝试TDD(Test-driven development,测试驱动开发)的开发模型.由此将不存在QA的角色,或者仅 ...

  10. node.js入门学习(五)--Demo模块化改造

    1.node.js中模块的分类 1)node.js内置模块(核心,原生) 所有内置模块在安装node.js时就已经编译成二进制文件,可以直接加载运行(速度较快),部分内置模块,在node.exe这个进 ...

随机推荐

  1. 不想当Window的Dialog不是一个好Modal,弹窗翻身记

    弹窗是我们熟视无睹的一种交互方式,经常用到,但从没好好想过这种交互行为背后的意义... 弹窗是Windows的灵魂 Windows的灵魂是什么?当然是Window,当方便快捷的多窗口进入人们视野的时候 ...

  2. Windows 系统 PostgreSQL 手工安装配置方法

    自从2020年底开始接触 PostgreSQL 以来就喜欢上了这个数据库,个人感觉比 MySQL 好用,多表联合查询性能好很多,同时也不存在 SQLServer 的版权授权费用问题.搭配 .NET 开 ...

  3. 关于python文件写入问题

    第一种.用for循环不断打开文件写入关闭 测试代码数据如下: import time begin = time.perf_counter() def a(f, lis): f.write(lis + ...

  4. 手把手教你用Java获取IP归属地

    前几个月微信公众号上线了IP归属地的功能,后续知乎.抖音等平台纷纷添加了该功能.如果是国内的用户精确到省份,国外用户精确到国家.本文就使用Java实现获取IP归属地. ! 主要讲解几个步骤: Java ...

  5. 采云端&采云链:从订单协同到采购供应链,让采购供应链互联互通

    采购供应链安全从来没有像现在这样显得如此重要和紧迫,也从来没有像现在这样复杂和敏感,对企业的经营产生决定性的影响.尤其在疫情期间,采购供应链更加牵一发而动全身,成为"运筹帷幄,决胜于千里之外 ...

  6. 2、String类

    String类 String 对象用于保存字符串,也就是一组字符序列 字符串常量对象是用双引号括起来的字符序列,例如:"你好"."12.07"."bo ...

  7. 完整的WindowsServer服务器系统初始化配置、安全策略加固和基线检查脚本等保2.0适用

    转载自:https://www.bilibili.com/read/cv14326780?spm_id_from=333.999.0.0 0x00 前言简述 最近单位在做等保测评,由于本人从事安全运维 ...

  8. Jetbrains家的软件都可用的激活码-pycharm

    网址:http://vrg123.com/ 步骤: 1,关注下方的公众号 2,点击菜单中的"激活密钥" 3,点击进入,获得网站密钥 4,在网站上输入网站密钥,点击获取,即可获取激活 ...

  9. 在 CentOS 8/RHEL 8 上安装和使用 Cockpit

    Cockpit 是一个基于 Web 的服务器管理工具,可用于 CentOS 和 RHEL 系统.最近发布的 CentOS 8 和 RHEL 8,其中 cockpit 是默认的服务器管理工具.它的软件包 ...

  10. C++面向对象编程之转换函数、explicit、one-argument

    1.转换函数 转换函数不需要返回值和参数,直接 "operator 类型名称() {}" ,类型名称就决定了返回值: 在一开始在执行 d = 4 + f; 时,先看有木有重载 + ...