随着应用的复杂度越来越高,其代码量和文件数量都会急剧增加,会逐渐引发以下问题:
随着时间的推移,针对 JavaScript 的不同运行环境,相继出现了多种模块化规范,按时间排序,分别为:
模块化的核心思想是:模块之间是隔离的,通过导入和导出进行数据和功能的共享。
在 CommonJS 标准中,导出数据有两种方式:
// a.js const name = '张三'
function getTel() { return '123456789' }
module.exports = { name, getTel }
// b.js const name = '李四'
function getTel() { return '666666666' }
// 通过给exports对象添加属性的方式,来导出数据 exports.name = name exports.getTel = getTel
// index.js // 引入a模块暴露的所有内容 const a = require('./a')
// 引入b模块暴露的所有内容 const b = require('./b')
console.log(a, a.getTel()) console.log(b, b.getTel())
注意点:
在CJS模块化标准中,使用内置的require函数进行导入数据。 // index.js // 1 直接引入模块 const a = require('./a') console.log(a, a.getTel())
// 2 引入同时解构出要用的数据 const { name, getTel } = require('./a') console.log(name, getTel())
// 3 引入同时解构 + 重命名 const { name: stuName, getTel: stuTel } = require('./a') console.log(stuName, stuTel())
一个 JS 模块在执行时,是被包裹在一个内置函数中执行的,所以每个模块都有自己的作用域,可通过如下方式来验证这一说法: // index.js console.log(arguments.callee.toString())内置函数大致形式如下:
function (exports, require, module, __filename, __dirname) { // index.js console.log(arguments.callee.toString()) }
Node.js 默认支持 CommonJS 规范,但浏览器端不支持,所以需要经过编译,步骤如下:
pnpm i browserify -gbrowserify index.js -o build.js,index.js 是源文件,build.js 是输出目标文件<script type="text/javascript" src="./build.js"></script>ES6 模块化规范是一个官方标准的规范,它是在语言标准的层面上实现了模块化功能,是目前最流行的模块化规范,且浏览器与服务端均支持该规范。
浏览器端可以直接运行,如在index.html页面中引入使用:<script type="module" src="./index.js"></script>
在 Node.js 中运行 ES6 模块代码有两种方式:
ES6 模块化提供 3 种导出方式:分别导出、统一导出、默认导出。这3种导出方式,可以同时使用。
使用原则:导出的常量,务必用const定义。
分别导出:
// a.js 分别导出 export const name = '张三' export function getTel() { return '123456789' }
统一导出:
// b.js 统一导出 const name = '李四' function getTel() { return '666666666' } export { name, getTel }
默认导出:
// c.js 默认导出 const name = '王五' export const age = 25 function getTel() { return '999999999' } export default { name, getTel }
对于 ES6 模块化来说,使用何种导入方式,要根据导出方式决定。
「导入全部」(通用),可将模块中的所有导出内容整合到一个对象中。
// index.js import * as a from './a.js' console.log(a, a.getTel())
「命名导入」(对应导出方式:分别导出、统一导出)
// index.js 命名导入 import { name, getTel } from './a.js' import { name as stuName, getTel as stuTel } from './a.js' console.log(name, getTel()) console.log(stuName, stuTel())
「默认导入」(对应导出方式:默认导出)
// index.js 默认导入 import c from './c.js' // 默认导出的名字可以修改,如把c改为abc也行 console.log(c.name, c.getTel())
「命名导入 与 默认导入 可以混用」,且默认导入的内容必须放在前方。
// index.js 默认导入 import c, { age } from './c.js' console.log(c.name, c.getTel(), age)
「动态导入」(通用),允许在运行时按需加载模块,返回值是一个Promise。
// index.js const a = await import('./a.js') console.log(a)
import可以不接收任何数据,如只让a.js参与运行:import './a.js'。
本文作者:a
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!