ES6 模块化
1 模块化概念
1.1 什么是模块化
-
模块化: 将一个大的js文件拆分成一个个小的js文件,最终通过某种语法组合在一起
-
模块:一个js文件就是一个模块,只针对js文件处理
-
特点:模块的内部数据/实现是私有的, 只是向外部暴露一些接口(方法/数据)与外部其它模块通信
1.2 模块化发展历史
-
使用命名函数来区分作用域
//add功能模块 function add() { } //sum功能模块 function sum() { }
-
简单封装 Namespace模式
var MYApp = { add: function () { }, sum: function () { } }
-
匿名闭包(IIFE)模式
var module1 = (function(){ var a = 1; var b = 2; var sum = function (){ console.log(a+b); } return { sum:sum } })() module1.sum();
-
匿名闭包(IIFE)模式 引入依赖关系
var module1 = (function($){ var a = 1; var b = 2; var sum = function (){ $.ajax() } return { sum:sum } })(jQuery) module1.sum();
1.3 模块化的优点
- 避免命名冲突(减少命名空间污染)
- 更好的分离, 按需加载
- 更高复用性
- 高可维护性
1.4 旧版本的模块化引入
- 请求过多
- 依赖模糊
- 难以维护
2. 其他模块化规范
2.1 commonJS
2.1.1 说明
- 每个文件都可当作一个模块
- 在服务器端: 模块的加载是运行时同步加载的
- 在浏览器端: 模块需要提前编译打包处理
- 同步加载,有缓存
2.1.2 基本语法
- 暴露模块
- exports.xxx = value
- module.exports = value
- 引入模块
- require(xxx)
2.1.3 实现
-
服务器端实现(Node.js)
-
浏览器端实现(Browserify,也称为CommonJS的浏览器端的打包工具)
-
下载
npm i browserify -g
-
编译
browserify main.js(使用Commonjs规范的代码) -o built.js(可以浏览器解析的js代码)
-
-
区别Node与Browserify
- Node.js运行时动态加载模块(同步)
- Browserify是在转译(编译)时就会加载打包(合并)require的模块
2.2 AMD
2.2.1 说明
- Asynchronous Module Definition(异步模块定义)
- 专门用于浏览器端, 模块的加载是异步的
- 异步加载
2.2.2 基本语法
- 定义暴露模块
- 定义没有依赖的模块
define(function(){return 模块})
- 定义有依赖的模块
define(['module1', 'module2'], function(m1, m2){return 模块})
- 引入使用模块
require(['module1', 'module2'], function(m1, m2){使用m1/m2})
- 定义没有依赖的模块
2.2.3 实现
实现(浏览器端):Require.js
2.3 CMD
2.3.1 说明
- Common Module Definition(通用模块定义)
- 专门用于浏览器端, 模块的加载是异步的
- 依赖模块先全部下载,再执行所有
2.3.2 基本语法
- 定义暴露模块
- 定义没有依赖的模块
define(function(require, exports, module){exports.xxx = value;module.exports = value})
- 定义有依赖的模块
define(function(require, exports, module){var module2 = require('./module2');require.async('./module3', function (m3) {exports.xxx = value})
- 引入使用模块 `define(function (require) {
var m1 = require('./module1') var m4 = require('./module4') m1.show()`
- 定义没有依赖的模块
2.3.3 实现
实现(浏览器端):Sea.js
3. ES6模块化规范
3.1 默认暴露及引入
-
暴露:
- 当前模块只需要暴露一个功能,则可以选用默认暴露
- 默认暴露在当前模块中只能暴露一个功能
- 使用 export default XXX;
function add(a, b) { return a + b; } export default add;
-
引入
import add from './add';
-
as
可以起别名,比如import add as save from './add'
;
3.2 分别暴露和引入
-
暴露
- 当一个模块中有多个功能需要暴露的时候,可以在声明语句前进行书写export进行暴露
- 分别暴露可以暴露多个功能出去
- 如果是分别暴露 则需要把export写在完整的声明语句前
export let count = 0; export const msg = { code: 10000, info: "hello world" } export function mins(a, b) { return a - b; }
-
引入:
- 引入分别暴露模块(一般使用解构赋值的形式来引入),因为分别暴露最终暴露的是一个对象
- 假如真的不想用解构赋值,我们可以直接用一个对象接收住统一暴露的内容
import * as say from './say'
3.3 统一暴露
-
暴露
- 直接在export后放对象,把需要暴露的功能放在对象中暴露出去
- 一般是暴露多个功能使用
function say1(con) { return "hello " + con; } function say2(con) { return "bye " + con } //统一暴露 /* export { say1, say2 } */ //统一暴露的时候 起一个别名 export { say1 as s1, //起别名 say2 }
-
引入
- 引入统一暴露模块(一般也是使用解构赋值的形式接受)
import { s1,say2} from './say'
- 假如真的不想用解构赋值,我们可以直接用一个对象接收住统一暴露的内容
import * as say from './say'
- 引入统一暴露模块(一般也是使用解构赋值的形式接受)
3.4 ES6 模块化的编译
使用babel把ES6模块化语法编译为CommonJS模块化
使用browserify把CommonJS模块化编译为浏览器识别的语法
-
babel的使用
npm install --save-dev @babel/core @babel/cli @babel/preset-env
-
@babel/core:babel的核心包
-
@babel/cli:babel的命令包
-
@babel/preset-env:babel的预设包
-
-
在package.json中配置预设
"babel": {"presets": ["@babel/env"]}
-
使用babel的命令把js文件夹中所有ES6模块化的文件编译为CommonJS的模块化规范:
npx babel 目标文件夹 -d 新文件夹(npx是启动本地命令)
-
使用browserify把babel编译出来的CommonJS规范的入口文件代码编译为浏览器识别的代码
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!