前端工程化之【模块化规范】
目录
- 模块化概述:
- 什么是模块化
- 为什么需要模块化
- 有哪些模块化规范
- 导入与导出的概念
- CommonJS 规范
- ES6 官方模块化规范
- 导出数据
- 导入数据
- Node 中运行 ES6 模块
模块化概述:
什么是模块化
● 将程序文件依据一定规则
拆分成多个文件
,这种编码方式就是模块化的编码方式。
● 本质上拆分出来的每个文件就是一个模块
,模块中的数据默认都是私有的
,模块之间互相隔离。
● 同时也能通过一些手段,可以把模块内的指定数据“抛出去”
,供其他外部模块使用。
为什么需要模块化
随着应用的复杂度越来越高,其代码量和文件数量都会急剧增加,会逐渐引发以下问题:
- 数据安全问题
- …
有哪些模块化规范
历史背景:2009 年,随着
Node.js
的出现,JavaScript 在服务器端的应用
逐渐增多,为了让 Node.js 的代码更好维护,就必须要制定一种Node.js 环境下的模块化规范
,来自 Mozilla 的工程师 Kevin Dangoor 提出了CommonJS 规范(CommonJS 初期的名字叫 ServerJS),随后 Node.js 社区采纳了这一规范
。
随着时间的推移,针对 JavaScript 的不同运行环境
,相继出现了多种模块化规范,按时间排序,分别为:
其中 AMD 以及 CMD
规范,目前已经渐渐淡出视野了,本文主要讲述 CommonJS
以及 ES6官方模块化
标准
导入与导出的概念
模块化的核心思想就是:模块之间默认是
私有隔离的
,通过导入和导出
进行数据和功能的共享。
- 导出(暴露):
模块向外公开其内部的一部分(
如变量、函数等
),使这些内容可以被其他模块使用。
- 导入(引入):
模块引入和使用
其他模块导出
的内容,以使用代码和功能。
CommonJS 规范
在
CommonJS
标准中,导出
数据有两种方式:
- 第一种方式:
module.exports = value
- 第二种方式:
exports.name = value
const name = 'javaScript'
const motto = '前端技术栈'
function getTel (){
return '66666666666666'
}
function getHobby(){
return ['数据一','数据二']
}
// 通过给exports对象添加属性的方式,来导出数据(注意:此处没有导出getHobby)
exports.name = name
exports.slogan = slogan
exports.getTel = getTel
在 CommonJS
模块化标准中,使用内置的 require
函数进行导入
数据
// 直接引入模块
const test = require('./test')
// 引入同时解构出要用的数据
const { name, slogan, getTel } = require('./test')
// 引入同时解构+重命名
const {name:stuName,motto,getTel:stuTel} = require('./test')
扩展导读
一个 JS 模块在执行时,是被包裹在一个
内置函数
中执行的,所以每个模块都有自己的作用域,我们可以通过如下方式验证这一说法:
console.log(arguments)
console.log(arguments.callee.toString())
内置函数的大致形式如下:
function (exports, require, module, __filename, __dirname){
/*********************/
}
ES6 官方模块化规范
ES6 模块化规范是一个
官方标准
的规范,它是在语言标准的层面
上实现了模块化功能,是目前最流行的模块化规范
,且浏览器与服务端均支持
该规范。查看 ESM 官方详情
导出数据
ES6 模块化提供 3 种导出方式:
1.分别导出、2.统一导出、3.默认导出
【分别导出】
// 导出name
export let name = {str:'测试数据'}
// 导出slogan
export const slogan = '一个字符串数据'
// 导出getTel函数
export function getTel (){
return '66666666'
}
【统一导出】
const name = {str:'测试数据'}
const slogan = '一个字符串数据'
function getTel (){
return '666666666'
}
function getCities(){
return ['北京','上海','深圳','成都','武汉','西安']
}
// 统一导出了:name,slogan,getTel
export {name,slogan,getTel}
【默认导出】
const name = '张三'
const motto = '走自己的路,让别人五路可走!'
function getTel (){
return '13877889900'
}
function getHobby(){
return ['前端','后端','测试']
}
//默认导出:name,motto,getTel
export default {name,motto,getTel}
备注 :「上述多种导出方式,可以同时混合使用
」
// 导出name ———— 分别导出
export const name = {str:'测试数据'}
const slogan = '一个字符串数据'
function getTel (){
return '010-56253825'
}
function getCities(){
return ['北京','上海','深圳','成都','武汉','西安']
}
// 导出slogan ———— 统一导出
export {slogan}
// 导出getTel ———— 默认导出
export default getTel
导入数据
对于 ES6 模块化来说,使用何种
导入方式
,要根据导出方式决定
。
1.「导入全部」(通用)
可以将模块中的所有导出内容整合到一个对象中。
import * as test from './test.js'
2.「命名导入」(对应导出方式:分别导出、统一导出
)
import { name,slogan,getTel } from './test.js'
通过 as
重命名
import { name as myName,slogan,getTel } from './test.js'
3.「默认导入」(对应导出方式:默认导出
)
import test from './test.js' //默认导出的名字可以修改,不是必须为test
4.「命名导入 与 默认导入可以混合使用
」
「命名导入」与「默认导入」混合使用,且
默认导入的内容必须放在前方
:
import getTel,{name,slogan} from './test.js'
5.「动态导入」(通用)
允许在运行时按需加载模块,返回值是一个
Promise
const test = await import('./test.js');
console.log(test) //Promise
6.import 可以不接收任何数据
例如只是让
mock.js
参与运行
import './mock.js'
Node 中运行 ES6 模块
Node.js中运行ES6模块代码有两种方式:
- 方式一:将 JavaScript 文件后缀从
.js
改为.mjs
,Node 则会自动识别 ES6 模块。 - 方式二:在
package.json
中设置type
属性值为module
。
🚵♂️ 博主座右铭:向阳而生,我还在路上!
——————————————————————————————
🚴博主想说:将持续性为社区输出自己的资源,同时也见证自己的进步!
——————————————————————————————
🤼♂️ 如果都看到这了,博主希望留下你的足迹!【📂收藏!👍点赞!✍️评论!】
——————————————————————————————