【webpack学习笔记—1】3点弄懂CommonJS模块打包标

2020-11-04  本文已影响0人  sam的奋斗日记

前言

前端本没有模块化,但是随着前端工程的发展,各个文件间的关系越来越多,为了能彼此方便地引用,慢慢地便有了模块化,这里的一个文件可以理解为一个模块。
打包就是为了让前端工程化,分离代码间的作用域。导出就是将本模块对外暴露,导入就是引入其他模块来使用其方法等。
CommonJS把每个文件当做一个独立的模块(所以这里模块和文件的概念共通),个人认为说到底就是在维护模块中的module的属性,其中有2个关键属性:第一个是exports(默认值是空的),第二个是loaded(默认值是false)。

下面通过3点来介绍如何通过这两个属性实现导入导出的控制。

补充知识点:module长啥样?
执行如下命令

node ./test.js

获得如下输出:

Module {
  id: '.',
  exports: {},  // 未导出属性,所以为空
  parent: null,  // 如果是其他模块引用当前模块,那么引用当前模块的模块名会成为这里的parent,但是这里是直接打印当前模块module的,所以为null
  filename: 'D:\\project\\study-webpack\\src\\test.js',
  loaded: false, // 还没有被使用require调用,为false
  children: [], // 道理同parent,有引用其他模块时这里会显示
  paths:
   [ 'D:\\project\\study-webpack\\src\\node_modules',
     'D:\\project\\study-webpack\\node_modules',
     'D:\\project\\node_modules',
     'D:\\node_modules' ]
 }

1. CommonJS的导出

有2种写法均可以实现对模块属性的导出,以下两种均可,但是不能混用!

// 第一种写法
exports.name = 'sam';
// 第二种写法
module.exports = {
    name : 'sam'
}

补充知识点:为什么不能将2种方式混用 ?
同一文件下混用会将这两个exports分别指向两个不同的对象,我们来测试下:

// 创建一个test.js文件,使用nonde环境执行它,node ./test.js
console.log(module.exports) // {}
console.log(exports) // {}
// 将两种导出进行混用
exports.name = 'sam';
module.exports = {
    sex : 'man'
}
console.log(module.exports) // { sex : 'man' }
console.log(exports) // { name : 'sam' }
console.log(module.exports === exports) // false

很明显生成不同的2个对象,而且无论哪个导出在前,而最终都是以modlue.exports为准。

2. CommonJS的导入

导入很简单,使用require实现,而且可以通过构造表达式来导入(这将与下一篇文章中的ES6 Module导入区别,那个只能提前声明好)

// ./person.js
console.log('this is sam!')
exports.name = 'sam';

// ./info.js
let path = './person' + '.js';
let person = require(path);
console.log(person.name); 
console.log('====================='); 
let person2 = require('./person.js');

获得如下输出

this is sam!
sam
=====================
sam

补充知识点:为什么‘this is sam!’只输出一次?
因为第一次require时,loaded值为false,所以执行文件中的代码,第二次require时,loaded为true,表示已经加载过了,所以不再执行代码。
所以有时候我们第一次使用模块,且只需要模块中代码执行的结果,而不需要调用其他属性时,可以像这样操作:

require('./test.js')

3. 小结

  1. CommonJS有2种导入方式,module.exportsexports.xxx,且二者不能同时混用
  2. 第一次require导入模块时,会执行模块中的代码

内容均为我个人阅读《Webpack实战:入门、进阶与调优》后的回忆总结,这是一本很不错的书,想深入了解webpack的同学可以去看看这本书

上一篇下一篇

猜你喜欢

热点阅读