webpack与模块化

模块化的核心

  • 独立的作用域
  • 如何导出模块内部数据
  • 如何导入外部模块数据

ESM(ECMAScript Module)

独立模块作用域

一个文件就是模块,拥有独立的作用域,且导出的模块都自动处于严格模式下,即use strict

导出模块内部数据

// 分别导出,可导出多次,import时变量名需与导出的变量名一致
export const key1 = {}
export const key2 = ()=>{
	return something...
}

// 默认导出,import时可自定义变量名;.js文件有且仅有一个默认导出
export default key3 
或
export default function key4(){}

// 模块重定向导出
export key5 from '...'

导入外部模块数据

  • 静态导入
  • 动态导入

静态导入

静态导入方式不支持延迟加载,import 必须在模块的最开始

import {key1} from 'module-name' // 导入单个导出的变量
import {key1 as customName} from 'module-name' // 自定义别名
import keys from 'module-name' // 导入默认模块

动态导入

关键字import可以像调用函数一样来动态导入模块,返回一个 promise。vue的路由懒加载就是用到此方法动态加载路由

import ('./a.js').then(()=>{})
// 也支持 await
cosnt b = await import('./b.js')
// 通过 `import()` 方法导入返回的数据会被包装在一个对象中,即使是 `default` 也是如此

模块的向下兼容

  • Common JS
  • AMD
  • UMD

Common JS

CommonJS 规范就是一套偏向服务端的模块化规范,NodeJS 就采用了这个规范。

  • 导出模块
// a.js
const key1 = 1
const key2 = 2
module.exports = {
 x:key1,
 y:key2
}
// or
exports.x = key1
exports.y = key2
  • 导入模块
// b.js
let a = require('./a');
a.x;
a.y;

AMD

因为 CommonJS 规范一些特性(基于文件系统,同步加载),它并不适用于浏览器端,所以另外定义了适用于浏览器端的规范 AMD(Asynchronous Module Definition)
浏览器并没有具体实现该规范的代码,一般是通过第三方库来解决:requireJShttps://requirejs.org/

// 1.html
<script data-main="scripts/main" src="https://cdn.bootcss.com/require.js/2.3.6/require.min.js"></script>
  • 独立模块作用域
    通过一个define方法来定义一个模块,并通过该方法的第二个回调函数参数来产生独立作用域
define(function() {
  // 模块内部代码
})
  • 导出模块内部数据
    通过return导出模块内部数据
// Person.js
define(function() {
  return class Person{
    say(item) {
      console.log(`我的名字是:${item.name}`)
    }
  }
})
// requireJS 也支持 CommonJS 风格的语法
define(['require', 'exports', 'module'], function(require, exports, module) {
  class Person{
    say(item) {
      console.log(`我的名字是:${item.name}`)
    }
  }
  exports.Person = Person;
})
// 忽略不需要的依赖导入
define(['exports'], function(exports) {
  class Person {
    say(item) {
      console.log(`我的名字是:${item.name}`)
    }
  }
  exports.Person = Person;
})
// 如果是依赖的导入为:require, exports, module,也可以省略依赖导入声明
define(function(require, exports, module) {
  class Person {
    say(item) {
      console.log(`我的名字是:${item.name}`)
    }
  }
  exports.Person = Person;
})
  • 导入外部模块数据
    通过前置依赖列表导入外部模块数据
// 定义一个模块,并导入 ./Person 模块
define(['./Person'], function(person) {
  let person = new Person()
  person.say({name: 'zhangsan'})
})

UMD

严格来说,UMD 并不属于一套模块规范,它主要用来处理 CommonJSAMDCMD 的差异兼容,是模块代码能在前面不同的模块环境下都能正常运行

(function (root, factory) {
  	if (typeof module === "object" && typeof module.exports === "object") {
        // Node, CommonJS-like
        module.exports = factory(require('jquery'));
    }
    else if (typeof define === "function" && define.amd) {
      	// AMD 模块环境下
        define(['jquery'], factory);
    }
}(this, function ($) { // $ 要导入的外部依赖模块
    $('div')
    // ...
    function b(){}
    function c(){}

    // 模块导出数据
    return {
        b: b,
        c: c
    }
}));
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值