起步

JavaScript 存在两种运行环境:

1. 浏览器工作环境

你可以有两种方法编辑 JS 代码。

  1. 其一,打开浏览器开发者工具,此处以 chrome 为例,启动浏览器窗口(键盘F5或者Ctrl + Shift + i),打开控制台(console)输入
var str = 'Hello World'; // 回车
str; // 回车, 输出"Hello World"
  1. 其二就是使用.html 文件,然后再浏览器开发者工具查看,因为不是我们今天要介绍的主要内容,这里就不再介绍啦。
<script>var obj = {name: '王勃',post: '落霞与孤鹜齐飞 秋水共长天一色',};console.log(obj);
</script>

2. nodejs 运行环境

你同样可以有两种方法编辑 JS 代码。以 VS Code 编辑器为例说明之

  1. 打开编辑器终端
node

在 node 运行环境输入

var str = {name: 'Andy',age: 12,gender: 'male',
};

  1. 利用 node 直接在编辑其运行, 在此我们建立如下项目结构以示说明

在 inde.js 文件输入

console.log(1);

然后再 Terminal 终端运行,

node index.js

终端输出如下:

如果我们修改文件,就需要重新执行上述 CLI 命令,开发十分不便,因此,我们有必要安装nodemon以便开发过程能够热更新运行结果;

  • nodemon全局安装
npm install -g nodemon
  • Linux 操作系统安装需要输入管理员权限
sudo npm install -g nodemon

现在再执行 index.js

Commonjs 项目介绍

现在让我们添加一段代码,看看 nodemon 的工作情况

Commonjs 模块化开发思路

随着项目的发展,代码越来越长,不同的功能放在一个 JS 文件,既不便于开发,也不便于将来修改和删除维护,有没有方法将不同的功能放到不同的函数中,然后在不同的地方调用即可,答案是肯定的;

  1. 首先,让我们将 index.js 代码修改一下,用两个函数将两段功能代码进行封装,结果会是这样;

function demo() {console.log(1);
}
function person() {var str = {name: 'Andy',age: 12,gender: 'male',};console.log(str);
}demo();
person();
  1. 现在开来还是存在问题,两段功能的代码始终是在 index.js 文件中,代码一多让人看看九就心烦,能否将这两段功能代码分别放到两个不同的 JS 文件中,仅仅在 index.js 中调用他们?答案是肯定的,你只要这样做
  • 创建两个 JS 文件,本案例分别创建 post.js 和 article.js

article.js

function demo() {console.log(1);
}

person.js

function person() {var str = {name: 'Andy',age: 12,gender: 'male',};console.log(str);
}
  • 现在怎样在 index.js 文件引入 article.js 和 post.js 呢?

index.js

const perosn = require('./js/person');const article = require('./js/article');
  • 运行 nodemon,查看运行结果,nodemon 执行 index.js 或者 app.js 文件可以不需要输入文件名
nodemon   // === nodemon index.js

如何在引入的文件使用被引入的文件呢?

  1. 此时,需要改造被引入文件 person.js 和 article.js,将需要被引用的模块暴露出去

article.js

function demo() {console.log(1);
}module.exports = { demo };

person.js

function person() {var str = {name: 'Andy',age: 12,gender: 'male',};console.log(str);
}
module.exports = { person };
  1. 在引入文件 inde.js 调用文件
const person = require('./js/person');const article = require('./js/article');person.person();
article.demo();

运行结果如下

  • 看看 index.js 这样调用是不是很麻烦,能否简便一些,你可以这样处理,将 person.js 的命名函数改为不匿名函数,就像这样。
module.exports = function () {var str = {name: 'Andy',age: 12,gender: 'male',};console.log(str);
};
  • index.js 调用
const person = require('./js/person');const article = require('./js/article');person();
article.demo();

怎样扩展被引入模块的功能

现在问题来啦,怎样扩展被引入模块的功能, 以 article.js 文件为例,我们需要扩展一个 post 功能模块,可以这样做

  1. 改造 article.js
function demo() {console.log(1);
}
function post(param) {console.log(param);
}
module.exports = { demo, post };
  1. index.js 调用, 在此案例我们传入的实参是一个配置对象,就像下边
article.post({name: '王勃',psot: '落霞与孤鹜齐飞 秋水共长天一色',
});
  • 参看运行结果

对引用文件的解构赋值

现在我们感觉对 article.js 的调用比较繁琐,能否对其进行简化,你可以采用 ES6 技术-对 demo 和 post 解构赋值

  • index.js
const person = require('./js/person');const { demo, post } = require('./js/article');person();
demo();
post({name: '王勃',psot: '落霞与孤鹜齐飞 秋水共长天一色',
});
  • 参看运行结果

exports 与 module.exports 的区别

为了说明这个问题,我们新创建一个文件 post.js,并将 article.js 文件复制过来

  • post.js
function demo() {console.log(1);
}
function post(param) {console.log(param);
}
module.exports = { demo, post };

现在我改造一下 post.js

exports.demo = function () {console.log(1);
};
exports.post = function (param) {console.log(param);
};
  • index.js 引入 post.js

为了便于调试,我们将 article.js 的引入给为 post.js 的引入

const person = require('./js/person');const { demo, post } = require('./js/post');person();
demo();
post({name: '王勃',psot: '落霞与孤鹜齐飞 秋水共长天一色',
});
  • 参看运行结果

模块的类型

模块可以是任意 JS 规定的数据类型

  1. String 类型
  • string.js
exports.string = '渔舟唱晚 响穷彭蠡之滨 雁阵惊寒 声断衡阳之浦';
  • index.js 引入和调用
const { string } = require('./js/string.js');
console.log(string);
  • 参看运行结果

  1. Object 类型
  • object.js
exports.object = {sayHi: function (x) {return console.log(x);},
};
  • index.js 引入和调用
const { object } = require('./js/object.js');
object.sayHi({name: '屈原',post: '路漫漫其修远兮 吾将上下来求索',
});
  • 参看运行结果

模块的扩展

为了说明这问题,我们用一个案例来理解模块开发的扩展问题

项目分析

  1. 在开发过程中我们需要开发用户登录与注册功能

我们可以这样做,从 index.js => user.js => login.js 传入用户登录表单,然后在 login 功能模块与数据库传入的 email 进行查询,如果用户存在,允许登录,否者要求用户注册

我们也可以从 index.js => user.js => login.js 传入用户注册表单,然后在 login 功能模块与数据库传入的 email 进行查询,如果用户不存在,允许注册,否者要求用户更换注册名

  1. 登录、注册流程图

  1. 首先创建/assets/js/login.js
exports.login = function (user) {console.log('login');
};
exports.registry = function (user) {console.log('registry');
};
  1. 创建/src/user.js
const { login, registry } = require('../assets/js/login');module.exports = function (user) {login(user);registry(user);
};
  1. index.js 引入 user.js
const user = require('./js/user.js');user();
  1. user.js 引入 login.js

  2. 测试

  1. 现在 index.js 传入 user 数据
const user = require('./js/user.js');user({name: 'Andy',email: 'andy@gmail.com',
});
  1. login.js 登录功能

我们假设从数据库已经获得了 email 数据 => Email,是一个数组,模拟项目进程,使用 indexOf 方法,查找用户是否存在,indexOf 原本是用来查询字符串初次出现的位置,但是,也可以用来查询数组中是否存在某个数组元素,当数组元素存在时会显示其在数组中的下标;

以 login 函数为例

const Email = ['andy@gmail.com','jhon@gmail.com','jack@gmail.com','andy@gmail.com','alax@gmail.com',
];
exports.login = function (user) {const result = Email.indexOf(user.email);console.log(result);
};
exports.registry = function (user) {console.log(user.email);
};

参看结果

'andy@gmail.com’的下标为 0,现在我们调换’andy@gmail.com’在数组中的位置,

参看结果

'andy@gmail.com’的下标为 2,

  1. 判断 result>=0 时,返回 true,否则返回 flase

参看结果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yStKfkGX-1618356062991)(https://z3.ax1x.com/2021/04/13/cyMvUe.png)]

  1. 修改 index.js 的 email,让数据在 Email 中不存在

参看结果

  1. registry 功能,可以类比 Login

login.js

const Email = ['jhon@gmail.com','jack@gmail.com','andy@gmail.com','andy@gmail.com','alax@gmail.com',
];
exports.login = function (user) {const result = Email.indexOf(user.email);if (result >= 0) return true;return '用户名不存在,请注册';
};
exports.registry = function (user) {const result = Email.indexOf(user.email);if (result < 0) return true;return '用户名已注册,请更换注册名!';
};

user.js

const { login, registry } = require('../assets/js/login');module.exports = function (user) {let resultLogin = login(user);console.log(resultLogin);let resultRegistry = registry(user);console.log(resultRegistry);
};

参看结果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pT5ibhj3-1618356062994)(https://z3.ax1x.com/2021/04/13/cy1SXt.png)]

  1. 测试

当 index.js 中 emial 存在时,返回的结果,可与上述结果相比较

index.js

const user = require('./js/user.js');user({name: 'Andy',email: 'andy@gmail.com',
});

参看结果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xUX7XAv0-1618356062996)(https://z3.ax1x.com/2021/04/13/cy1BND.png)]

总结

通过案例详细说明了使用模块化开发项目的全部过程。

源代码

源码下载地址commonjs 模块化开发相关源码

Commonjs 模块化开发解析相关推荐

  1. 前端面试题 ~ 有关模块化开发

    1.说说你对前端模块化开发的认识. (1)异步模块定义(AMD)规范是 require. js推广的.对模块定义的规范. (2)通用模块定义(CMD)规范是 SeaJS推广的.对模块定义的规范. (3 ...

  2. js 多个定时器_Node.js系列深入浅出Node模块化开发——CommonJS规范

    前言 本文将为大家透彻的介绍关于Node的模块化--CommonJS的一切. 看完本文可以掌握,以下几个方面: 什么是模块化,以及没有模块化会带来哪些问题,是如何解决的: JavaScript的设计缺 ...

  3. 模块化开发:AMD、CMD、CommonJs和Es6的区别

    什么是AMD.CMD.CommonJs? 他们之间有什么区别? 项目当中都是如何运用的? AMD即Asynchronous Module Definition,是RequireJS在推广过程中对模块定 ...

  4. 五、Vue模块化开发学习笔记——JavaScript原始功能、匿名函数的解决方案、使用模块作为出口、CommonJS、ES6 export和import的使用

    一.JavaScript原始功能 -在网页开发的早期,js制作作为一种脚本语言,做一些简单的表单验证或动画实现等,那个时候代码还是很少的. 那个时候的代码是怎么写的呢? 直接将代码写在<scri ...

  5. SOFABoot源码解析之模块化开发

    1.SOFABoot源码解析 1.1模块化开发 1.1.1 简述 关于SOFABoot模块化开发的文档来自于Alipay开源社区Wiki,链接地址为: https://github.com/alipa ...

  6. commonjs 和 es6模块化开发入门

    commonjs模块化 首先写一个api,提供给外部调用 //commonjslet sum =(a,b)=> a+b;// 暴露接口 module.exports = {sum // sum: ...

  7. JavaScript模块化开发技术概述

    2019独角兽企业重金招聘Python工程师标准>>> 什么是模块化开发? 前端开发中,起初只要在script标签中嵌入几十上百行代码就能实现一些基本的交互效果,后来js得到重视,应 ...

  8. 前端模块化开发学习之gulpbrowserify篇

     随着web应用的发展,前端的比重占得越来越多,编写代码从而也越来越复杂.而通常我们需要将不同功能或者不同模块的代码分开写,最后在html中一起加载,这样做是可以的,但是当你需要进行维护或者是二次开发 ...

  9. Js模块化开发的理解

    Js模块化开发的理解 模块化是一个语言发展的必经之路,其能够帮助开发者拆分和组织代码,随着前端技术的发展,前端编写的代码量也越来越大,就需要对代码有很好的管理,而模块化能够帮助开发者解决命名冲突.管理 ...

最新文章

  1. STL vector
  2. 一个基于POI的通用excel导入导出工具类的简单实现及使用方法
  3. matlab作图如何改变坐标刻度
  4. python删除第一行_Python删除文件第一行
  5. Spring声明式事务示例
  6. Python Dataframe转List
  7. Java查询图书信息
  8. python 爬虫应用
  9. EF架构~DefaultValue让我的UnitOfWork更可读
  10. 机械设计参考CAD零件图纸常用素材资料(300张)
  11. ssm+vue基于微信小程序的数学辅导教学学习系统#毕业设计
  12. android app 设置以太网静态Ip
  13. 腾讯云快速增长背后 三大短板仍需补足
  14. Cadence OrCad Capture新建工程的方法
  15. win10下的linux占用大小,详解Win10系统上使用Linux之前要知道的几件事
  16. 编译原理_P1004
  17. 使用myeclispe或者sts工具,创建的myBatis的 xml文件不提示的问题解决方法
  18. oracle 英文简写的日期转成数值型日期的字符串
  19. 2022年嵌入式开发就业前景怎么样?
  20. iphone12android在线啥意思,iPhone12的新功能 你的安卓手机早就已经有了

热门文章

  1. TeXstudio-粗体斜体无法显示
  2. 把opencv Mat 按位存成bmp二值图像 (1bit 1pixel)
  3. Python精灵和精灵组
  4. 实验九 使用异步方式实现文件读\写
  5. iPhone15将开放15W无线快充!
  6. Docker系列之五:Docker 三剑客之 Docker Swarm
  7. 对智能电视的几个看法和观点
  8. Mac电脑怎样关闭sip,苹果电脑关闭系统完整性保护SIP的方法
  9. 前端模拟自动解析手机号姓名地址
  10. 微信小程序一星期入门-完结篇--电影详情页的制作