JavaScript代码模块化,commonjs如何编写并引用?
发布于 作者:苏南大叔 来源:程序如此灵动~在JavaScript代码模块化过程中,commonjs
是其中一个产物。根据最初的设计,commonjs
是适用于服务器(node
)端使用的,类似的概念还有AMD
/CMD
/es6 module
。但是,由于webpack
提供的兼容方式的存在,commonjs
的写法,实际上也可以用于前端页面里面。
本文测试环境:chrome@89.0.4389.114
,webpack@5.36.2
,node@14.16.0
。主要讲述commonjs
的基本写法,主要结论是:commonjs
写法简单,但是并不是太好用,而且存在着一些大的问题。
模块化的基本概念
JavaScript
模块化基本概念就是:一个文件就是一个模块,有自己的作用域。这个文件里面定义的变量、类、函数等,对于别的文件来说,都是不可见的。除非本文件主动使用导出操作,使得这些方法类变量之类的在外部可见。
苏南大叔理解着就是:对每个文件施加了一个隐藏的闭包环境,起到了一个隔绝的作用。写法上非常像class类
,似乎就是class
里面的public
的字样(概念)换成了exports
字样(概念),你细品。
commonjs
所有代码都运行在模块作用域,不会污染全局作用域。模块可以多次加载,但是只会在第一次加载时运行一次,然后运行结果就被缓存了,以后再加载,就直接读取缓存结果。
commonjs
的基本写法
和普通的传统函数式编程js
相比较的话,其实就是在代码的最末端加上了module.exports
字样,其它的地方基本上没有变化。代码类似如下:
var name = 'sunan'
var age = 18
module.exports.name = name
module.exports.getAge = function(){
return age
}
或者:
var name = 'sunan'
var age = 18
module.exports={
name:name,
getAge:function(){
return age;
}
}
这里需要特殊说明的是:
- 理论上来说,上面的
module.exports
可以缩写成exports
,但是并不建议这么使用,因为个别情况下会有问题。 - 另外,在
commonjs
模块化方案里面,module
就是关键字了,不能被改写。你懂的。
一种简写方式
下面是一个更加简单的写法:
var name = "苏南";
var age = 18;
var getAge = function () {
return age;
}
function setAge(a) {
age = a;
}
module.exports = {
name, age, getAge, setAge
}
这里导出的对象的key
和内部的变量名是一致的,就可以这样简写:
module.exports = {
name, age, getAge, setAge
}
而不是:
module.exports = {
name:name,
age:age,
getAge:getAge,
setAge:setAge
}
基本使用方法(前后端)
这里需要额外说明的是:commonjs
在设计的最开始,就是要提供给node
类似的后端环境使用的,并不是提供给传统的网页换的。但是,这些commonjs
如果通过webpack
处理过的话,这些写法在前端也是一样可以使用的。所以,webpack
有识别commonjs
的能力。
被模块化的代码写法,如上所示。在其他的地方,进行引用的时候,使用require
进行操作,如下所示:
var example = require('./example.js');
var example2 = require('./example2');
webpack
额外加工(纯浏览器环境)
在node
下面直接使用的话,是可以直接识别commonjs
的写法的。但是,在纯浏览器环境下使用的话,就恰恰需要编译处理一下才能识别这种commonjs
的写法。而webpack
恰恰就提供了这种能力,当然,相信其他的打包软件,也会提供类似的能力,这个并非webpack
的专利。
这里就简单说说webpack
如何处理commonjs
。此处测试环境,使用的是:webpack@5.36.2
。
其实特别简单,直接npx webpack
试试(话说npx
是个好命令):
npm install -D webpack webpack-cli
npx webpack
配置webpack.config.js
(其实没有任何的特殊配置,就是传统的设置entry
和output
):
var path = require("path");
module.exports = {
entry: path.join(__dirname, 'main.js'),
output: {
path: __dirname,
filename: 'main_4_web.js'
},
};
在这个例子里面,main.js
里面,使用require
加载了module.js
。而module.js
就是使用了commonjs
标准,利用module.exports
导出的一个模块文件。
存在问题
commonjs
写法真的是非常简单,但是,这种写法也存在着天然的缺陷。这里先进行简要的说明:
- 缺陷一:
module.exports
和exports
,理论上,两者可以相互替代。但是,建议统一使用module.exports
。 - 缺陷二:
commonjs
模块会缓存结果,多次调研的话,是会读取缓存文件。这个问题非常严重,严重违背认知。这个问题在后面的文章里面,苏南大叔会对其进行详细阐述。
相关文章
总结
这里总结一下,commonjs
写法和使用方法是非常简单的,默认是用于后端使用的。如果在纯浏览器环境下使用,需要进行编译。commonjs
存在着一些天生的缺陷,所以需要写代码的时候,特别注意。
更多commonjs
的经验文章,请点击苏南大叔的博客:
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。