浅谈js模块化:commons、AMD、CMD、ES6几种模块化
js模块化是现在比较流行的一种用法,它能避免很多以前js的弊端,是前端工程化的所要涉及到的话题,今天我们来谈谈几种模块化的方法。
一个页面需要引入多个js文件引发的问题:
- 请求过多
- 依赖模糊
- 难以维护
这些问题可以通过现代模块化编码和项目构建来解决
模块化的好处:
- 避免命名冲突(减少命名空间污染)
- 更好的分类,按需加载
- 更高的复用性
- 高可维护性
几种常用的模块化规范
1、 commonJs
commonjs特点: 每个文件都可当作一个模块;在服务器端: 模块的加载是运行时同步加载的;在浏览器: 模块需要提前编译打包处理
暴露模块module.exports = values export.xxx = value
引入 require(xxx)第三方模块
- 一个简单的在服务端运行的例子:
首先你的电脑里面要保证已经安装过nodejs,因为我要用到这环境。
建立一个文件commons,然后在commonjs里面建一个app.js,建立一个modules文件夹,里面分别建三个js文件module1.js,module2.js,module3.js.
执行下列命令
npm init //在根部生成一个package.json文件
在这里插入图片描述
module1.js
module.exports = {
msg: 'module1',
fn () {
console.log(this.msg)
}
}
module2.js
//module.exports 一个文件只能出现一次,要不容易被下面的覆盖
module.exports = function () {
console.log('module2')
}
module3.js
exports.fn = function() {
console.log('fn() module3')
}
exports.bar = function () {
console.log('bar() module3')
}
app.js
let module1 = require('./modules/module1')
let module2 = require('./modules/module2')
let module3 = require('./modules/module3')
module1.fn()
module2();
module3.fn()
module3.bar()
用node运行app.js,效果如下图
在这里插入图片描述
-
commjs基于浏览器端的应用
如果没有工具的编译解析,浏览器是无法识别commjs里面的require的,比如我们建立一个commonjs文件夹,里面内容如下图,dist文件是个建立的空文件,用来打包编译内容放在这里,app.js,module1.js,module2.js, module3.js都还跟上一个例子内容一样,复制过来就可以了。
在这里插入图片描述
index.html文件引入app.js
在浏览器中打开index.html并没有想象的预览效果,报错如下图
在这里插入图片描述
我们需要借助于browserify工具,用命令行安装browserify
npm install browserify -g
npm install browserify -save-dev
然后打包执行
browserify src/app.js -o dist/build.js
index.html引入文件换成打包后的build.js文件,这样再运行,在浏览器就能正常运行了。
在这里插入图片描述
2、 AMD
异步模块定义,专门用于浏览器端模块的加载是异步
定义
AMD自定义规范举例,利用requirejs写一个简单的demo来说明。
首先建立一个requirejs文件,在子级建立一个js文件和index.html,js里面建立一个modules文件和main.js文件
modules文件里面分别是dataService.js 和alerter.js
dataService.js
//没有依赖模块
define(function (){
let name = 'dataService.js'
function getName() {
return name
}
//暴露模块
return { getName }
}
);
alerter.js
//定义有依赖的模块
define([
'dataService'
], function(dataService) {
let msg = 'alert.js';
function showMsg() {
console.log(msg, dataService.getName())
}
return {showMsg}
});
main.js
(function() {
// requirejs配置文件配置
requirejs.config({
baseUrl: 'js/', //基本的路径,从根目录开始
paths: {
dataService: './modules/dataService',
alerter: './modules/alerter'
}
})
//
requirejs(['alerter'], function(alerter){
alerter.showMsg()
})
})()
index.html
<!DOCTYPE html>
<head>
<meta charset="UTF-8"/>
<title>测试</title>
</head>
<body>
<script data-main="js/main.js" src="https://cdn.bootcss.com/require.js/2.1.18/require.js"></script>
</body>
</html>
3、 ES6
ES6模块化是目前比较流行的一种方式,也是以后发展的一种趋势。依赖模块需要编译打包处理,引入模块用import,导出模块的方法是export。
在这里插入图片描述
举例子来说明es6的导入和导出
首先建立一个文件夹es6test,初始化package.json文件,用npm init
安装所需要的插件
qiuqiu$ npm install babel-cli browserify -g
npm install babel-preset-es2015 --save-dev
//preset预设(将es6转换成es5的所有插件打包)
定义一个.babelrc文件,(rc其实是run control)
{
"presets": ["es2015"]
}
在es6test中建立一个src文件和html.html文件
src下建立main.js,module1.js,module2.js
module.js
//暴露模块,分别暴露
export function foo () {
console.log('foo() module1')
}
export function bar () {
console.log('bar() module1')
}
export let arr = [1,2,3,4]
module2.js
function fun () {
console.log('fun() module2')
}
function fun2 () {
console.log('fun2() module2')
}
export {
fun,
fun2
}
main.js
// 引入其他模块
//语法: import xxx from 路径
import {foo, bar, arr} from './module1'
import {fun, fun2} from './module2'
console.log(foo())
console.log(bar())
console.log(arr)
console.log(fun())
console.log(fun2())
编译
- 使用babel将es6编译为es5代码(但包含co m mmjs语法):
babel src -d es6test/lib
运行效果如下图: 在这里插入图片描述 - 使用Browserify编译js:
browserify es6test/lib/main.js -o dist/bundle.js
最后在index.html中引入dist文件中的bundle.js运行可以看到效果。
4、CMD
CMD是SeaJS在推广过程中对模块定义的规范化产出,是一个同步模块定义,是SeaJS的一个标准,SeaJS是CMD概念的一个实现,SeaJS是支付宝团队提供的一个模块开发的js框架.
总结
今天主要通过自己视频学习分享了,js模块化的一些方法,上面的图有的借鉴于视频中的截图,如果想了解更多,请扫描二维码
在这里插入图片描述