js 模块化
模块化
将一个复杂的程序 依据一定的规则(规范) 拆分成几个块(文件),并进行组合在一起
块内部的数据是私有的,只是向外暴露一些接口(方法)与外部其他模块进行通信
模块的暴露、模块的引入
模块的进化史
1. 页面加载 script 的缺点:
请求过多,依赖模糊,难以维护
module1.js
module2.js
index.html
2. 简单地封装进一个对象(本质是对象,可修改,不安全)
3. 使用 IIFE 匿名闭包
4. 引入依赖(现代模块化的基石)
前端面试题: 没有模块化,怎么写代码?
利用 IIFE 引入依赖,构建匿名闭包。
设计原则: 高内聚、低耦合(模块内部配合越紧密越好、模块之间联系越低越好)
解耦: 降低耦合度
模块化的好处:
避免了命名冲突(减少了命名空间的污染)
更好的分离
更高的复用性
可维护性好
模块化规范 (vue 的出现,组件规范更深得人心):
- ES6 ----> Babel + Browserify
由于目前,浏览器还不能直接完全识别 ES6
Babel 将 ES6 转成 ES5,还将 import 语法 转成了 require 语法语法,最后 Browserify 使浏览器认识 require 语法
依赖模块,需要编译打包处理
- 暴露模块 (ES6 模块中的暴露命名,处于同一作用域 export,意味着不能暴露同名定义)
1. 分别暴露
export 暴露内容;
2. 统一暴露
export {xxx, yyy};
3. 默认暴露 (使用的频率很高,只能暴露一次)
export default 暴露内容;
- 引入模块
1. import {} from './module1';
2. import modules from './module2';
(浏览器端的) 实现:
① 使用 jQuery 的话
npm install jquery@1 --save
import $ from 'jquery';
② 使用 Babel 将 ES6 编译为 ES5 代码 (还能 { "presets": ["jsx"] } )
npm install -g babel-cli browserify // comment line interface ----> 命令行接口
npm install babel-preser-es2015 --save-dev // 安装进开发依赖
vim .babelrc // run control 运行时控制规则
{ "presets": ["es2015"] }
③ 使用 Babel 将 ES6 编译为 ES5 代码 (ES6 模块化 转换成了 CommandJS)
babel js/src -d js/lib
④ 使用 Browserify
browserify js/lib/app.js -o js/lib/appOutput.js
<script scr="js/lib/appOutput.js"></script>
看起来这一系列很麻烦,但是 自动化构建工具 诞生了,哈哈。
使用 Browserify 编译打包 js
- js/module1.js
- js/module2.js
- js/module3.js
- js/app.js
1
- index.html
1
- CommonJS ----> Node、Browserify
每一个 js 文件都可以当成一个模块
模块加载 是运行时同步加载的
npm install uniq --save
暴露模块 (本质是 exports 对象)
module.exports = {xxx, ccc};
exports.xxx = xxx;
exports.ccc = ccc;
module.js:
module.exports = {
name:'SunWuKong',
age:550,
hello(){ console.log('Hello Module.'); }
};
引入模块
require('xxx'); // 第三方库
require('./xxx'); // 自定义模块,必须以 ./ 或者 ../ 开头
const sun = require('./module.js');
const {name:sunName} = require('./module.js');
浏览器端不认识 require 所以必须 npm install browserify -g // 查看全局的包在哪儿 npm get prefix
模块需要提前编译打包处理
npm install browserify -g
browserify js/src/app.js -o js/dist/appOutput.js
<script src="js/dist/appOutput.js"></script>
- AMD ----> RequireJS
Asynchronous Module Definition 异步模块定义
https://github.com/amdjs/amdjs-api/wiki/AMD
专门用于浏览器端,模块的加载是异步的
- 暴露模块
1. 定义一个没有依赖的模块
define(function(){
return 模块;
});
2. 定义又依赖的模块
define(['module1', 'module2'... ...], function(m1, m2){... ...}); // 破坏了 就近声明原则
- 引入模块
浏览器端,模块的加载是异步的 :
坑:
去 .js 后缀
jquery 迎合 小写 jquery
- modules/dataService.js // return 必须是一个对象;
- modules/loger.js
- main.js // 模块化入口主文件,需要编写配置对象,固定写法
- index.html
- CMD ----> SeaJS
参见: https://www.cnblogs.com/tianxiaxuange/p/11084178.html#MySignature