<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <!-- 经过标签加载js是不能作到模块化的 --> <script src="./js/jquery.min.js"></script> <script src="./js/a.js"></script> <script src="./js/b.js"></script> </body> </html>
Javascript 语言自己是不具有模块化能力的,须要自已进行封装来实现模块的定义以及加载,其实现遵守必定的规范(COMMONJS)html
Nodejs 是运行在服务端的Javascript,它是按着commonjs的规范实现的模块化前端
通过实践发现浏览器端Javascript按着commonjs的规范实现模块化时,有很不足之处,此时就有人在commonjs的基础上从新定了一个规范AMD(Async Module Define),其表明就是require.jsjquery
随前端开发演变,又有人定义另一个浏览器端模块化的规范CMD(Common Module Define),淘宝的玉伯定义的,其表明是seajs数组
模块是以文件形式存在的(一个文件对应一个模块也能够一个文件对应多个模块),经过define()方法来定义一个模块。浏览器
define(function () { // 回调函数中即模块逻辑 var str = 'a'; alert(str); // code.... });
// 经过一个数组来声明,模块的依赖 define(['./a'], function (a) { var str = 'b'; // 经过形式参数a来接收a模块的返回值 // a模块返回值(对象)包含了方法now a.now(); // a模块返回值(对象)包含了方法sayHi a.sayHi(a.name); console.log(str); // code.... });
定义模块时,能够有返回值,但并非必须,返回数据类型没有任何约束,一般返回值是对象更有意义。模块化
define(function () { // 回调函数中即模块逻辑 var str = 'a'; // console.log(str); // 直接返回字符串 // return str; // 还能够是一个函数 // return function () { // console.log('如今是' + new Date); // } // 也能够是一个对象 return { name: '小明', sayHi: function (name) { console.log('你好' + name); }, now: function () { console.log('如今是' + new Date); } } // 返回值能够是任意类型,对象更有意义 // code.... });
经过 require() 或者 requirejs() 方法来加载一个模块函数
<!-- 引入requirejs --> <script src="./libs/require.js"></script> <script> // 加载模块 // 同时加载两个模块,执行顺序与书写顺序无关 require(['./a', './b']); </script>
<!-- 引入requirejs --> <script src="./libs/require.js"></script> <script> // 加载模块 // b和c模块同时依赖了a模块 // 当加载b和c模块时,a模块能够自动被加载进来 require(['./b', './c']); </script>
<script> require(['./a'], function (a) { console.log(a); a.sayHi(a.name) a.now(); }); </script>
<!-- 使用自定义属性指定的模块,称为入口文件 --> <!-- 此文件会自动被执行 --> <script src="./libs/require.js" data-main="./index.js"></script>
requirejs加载模块时,路径是遵守一些规则的,分红如下几种状况requirejs
<h2>配置requirejs的的路径</h2> <script src="./libs/require.js" data-main="./main.js"></script> <script> // 相对于当前页面 // require(['./src/a']); // 假如使用入口文件, // 路径参照的是入口文件所在的目录 // require(['./src/src/a']); </script>
// 经过config方法能够对requirejs进行配置 // 其中经过baseUrl来配置加载路径 require.config({ baseUrl: './public' });
经过path属性能够配置模块真实路径(baseUrl + path),这样配置后能够使得路径调整变的灵活。ui
// 经过config方法能够对requirejs进行配置 // 其中经过baseUrl来配置加载路径 require.config({ baseUrl: './public', // 使用path能够为模块真实路径起个"别名" paths: { jquery: 'assets/jquery/jquery.min' } }); // a和b模块都依赖于jquery,当改变jquery路径时 // 只须要改变配置里的path就能够了 require(['./src/a', 'src/b']);
在现实开发中并非全部的JS库都是按着模块化形式开发,可是咱们又不得不使用这些JS库,requirejs提供了解决方案。spa
为了帮助理解,总结了模块的两个特色“舍与得”
a) “舍”指模块将自身模块的功能提供给其它模块使用
define(function () { var obj = { name: '小明', sayHi: function () { //code... }, now: function () { // code... } } // 将自身功能提供给其它模块 return obj; })
b) “得”指模块将其它模块提供的功能直接拿来用
define(['demo'], function (demo) { // 经过数组形式提定依赖的模块 // 以形参的形式使用其它模块提供的功能 });
对于非模块requirejs也有解决方案,经过另一种形式来知足“舍与得”的特色,以下
// 经过config方法能够对requirejs进行配置 // 其中经过baseUrl来配置加载路径 require.config({ baseUrl: './public', // 使用path能够为模块真实路径起个"别名" paths: { jquery: 'assets/jquery/jquery.min', c: 'src/c', demo: 'assets/custom/demo' }, shim: { c: { // 指定当前c模块依赖于demo // 至关于标准模块里的 // define(['demo'], function () {}); deps: ['demo'], exports: 'newobj' }, demo: { // 指明当前demo模块的返回值 // 至关于标准模块里的 // define(function () {return obj;}); exports: 'obj' } } }); // require(['./src/a', 'src/b', 'c']); require(['c']);
// 匿名 define([], function () { // code... // return }); // 具名 define('demo', [], function () { // code... });
先写到这里吧,有机会再补充