随着互联网的发展,JS已经不是当初那个单纯运用在网景浏览器中的小语言了。在前端框架飞速发展以及NodeJS在服务器上的运用,当初的那个小语言也在飞速迭代,让其内部架构能能符合所有开发项目的需求。因此语言的模块机制及其重要。模块化是计算机科学中的一个核心概念。它代表对所有代码逻辑的封装,以便提高代码的整洁度以及可重用性。同时,因为在开发大项目的过程中,开发者很容易遇到的情况就是变量命名的重叠,如果模块机制的隔离度不够高,程序必然会很脆弱。CommonJS便是建立于解决JS起初对模块化的不友好性。虽然针对模块化的解决方案在过去几年出现了很多标志性的创新,特别是 ES6中的export/import。但本篇文章会针对CommonJS在Node环境下做一些探讨。
模块化是对代码的封装,然而实现模块化的其中一个机制是能让一个文件的代码去调用其他文件的代码。需要知道的是面向对象的编程理念也是针对代码的整理。而CommonJS是在编程理念之下的底层实现,好比HTTP和TCP之间的关系。
// add.js
function add (a, b) {
return a + b
}
module.exports = add
借用在https://blog.risingstack.com/node-js-at-scale-module-system-commonjs-require/看到的例子,上图的module.export就是将代码从文件内导出的关键词。在底层,Node将add.js的代码做了封装:
(function (exports, require, module, __filename, __dirname) {
function add (a, b) {
return a + b
}
module.exports = add
})
为了避免对全局作用域造成污染,所导出的代码都存在于module内。当需要调用此模块时,只需使用require去做调用:
// index.js
const add = require('./add')
console.log(add(4, 5))
require的内部逻辑的核心就是去找到指向引入文件的确切位置,所以它的核心逻辑是围绕着查找文件地点的优先级而执行的。Node会根据名字或者提供的路径去获取模块。若没有找到,Node会去node_module文件下查看。当模块找到后,它将被存入缓存。