什么是模块化?

  • 将若干功能进行封装,以备将来被重复使用。

为什么要前端模块化?

  • 将公共功能进行封装实现复用
  • 灵活解决依赖
  • 解决全局变量污染

如何实现前端模块化?

<!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)

Nodejs 是运行在服务端的Javascript,它是按着commonjs的规范实现的模块化

经过实践发现浏览器端Javascript按着commonjs的规范实现模块化时,有很不足之处,此时就有人在commonjs的基础上重新定了一个规范AMD(Async Module Define),其代表就是require.js

随前端开发演变,又有人定义另外一个浏览器端模块化的规范CMD(Common Module Define),淘宝的玉伯定义的,其代表是seajs

前端模块化使用requirejs

  • requirejs 本身是一个js文件,它按照AMD规范实来实现模块的定义和加载规则,应用在浏览器端。

定义模块

  模块是以文件形式存在的(一个文件对应一个模块也可以一个文件对应多个模块),通过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>

入口文件

  •   通过为引入require的标签加入 data-main 属性,其属性值为某一个模块的路径,此模块可以自动被加载并执行。
    <!-- 使用自定义属性指定的模块,称为入口文件 -->
<!-- 此文件会自动被执行 -->
<script src="./libs/require.js" data-main="./index.js"></script>

加载路径

 requirejs加载模块时,路径是遵照一些规则的,分成以下几种情况

  1. 当没有入口文件时,加载路径以引入requirejs的页面为准
  2. 当存在入口文件时,加载路径以入口文件所在目录为准
  3. 通过配置可以自定义加载路径
    <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),这样配置后可以使得路径调整变的灵活。

// 通过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提供了解决方案。

为了帮助理解,总结了模块的两个特点“舍与得”

     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...
});

先写到这里吧,有机会再补充

require.js 模块化的更多相关文章

  1. require.js模块化

    require.js简单来说就是把js代码分装模块化了 模块化 模块就是实现特定功能的一组方法.只要把不同的函数(以及记录状态的变量)简单地放在一起,就算是一个模块. 我拿一个运动框架来解释一下req ...

  2. 初步理解require.js模块化编程

    初步理解require.js模块化编程 一.Javascript模块化编程 目前,通行的Javascript模块规范共有两种:CommonJS和AMD. 1.commonjs 2009年,美国程序员R ...

  3. require.js模块化写法

    模块化 模块就是实现特定功能的一组方法.只要把不同的函数(以及记录状态的变量)简单地放在一起,就算是一个模块. 下述两种写法等价 exports 对象是当前模块的导出对象,用于导出模块公有方法和属性. ...

  4. require.js 模块化简单理解

    组件化 基于UI 样式布局 没有过多 js 代码操作的 比如:一个导航栏 一个表单 一个搜索框 一个侧边栏 一个html 等等.... 模块化 基于功能模块 一个可以替换的js部分称之为模块(modu ...

  5. require.js模块化管理和加载js(按需加载)简单实例教学

    一.为什么要用require.js? 最早的时候,所有Javascript代码都写在一个文件里面,只要加载这一个文件就够了.后来,代码越来越多,一个文件不够了,必须分成多个文件,依次加载.下面的网页代 ...

  6. require.js模块化开发

    模块化开发的原因: 1.引入的js过多然后在加载的过程中容易出现假死的状态,导致页面会发生白屏 2.变量名的问题 在多人协作开发的时候容易出现变量名的冲突 面向对象 3.引入优先级的问题 模块化开发分 ...

  7. javascript模块化编程库require.js的用法

    随着javascript的兴起,越来越多的公司开始将JS模块化,以增加开发的效率和减少重复编写代码的.更是为了能更加容易的维护日后的代码,因为现在的随着人们对交互效果的越来越强烈的需求,我们的JS代码 ...

  8. Support for AMD usage of jwplayer (require js)

    使用require js 模块化代码时,其中播放器用的是jwplayer7.x 然后载入jwplayer.js后总是报license无效(license已经加入),最后在jwplayer官网论坛里找到 ...

  9. Uncaught Error: Script error for "popper.js", needed by: bootstrap - require.js

    Uncaught Error: Script error for "popper.js", needed by: bootstrap https://requirejs.org/d ...

随机推荐

  1. C++ string和int相互转换

    首先需要C++ 11的支持 打开devC++,点击tools,点击编译环境,然后出现的框第一个勾选,输入-std=c++11即可 然后使用 to_string() 和 atoi() 就可以轻松实现其相 ...

  2. Asp.Net Core 生成图形验证码

    前几天有朋友问我怎么生成图片验证码,话不多说直接上代码. 支持.NET CORE开源.助力.NET Core社区发展. using System; using System.IO; using Sys ...

  3. Python起源与发展

    Python的创始人为吉多*范罗苏姆(Gudio van Rossum) 1.1989年的圣诞节期间,吉多*范罗苏姆为了在阿姆斯特丹打发时间,决心开发一个新的解释程序,作为ABC语言的一种继承. 2. ...

  4. 4.2 执行环境及作用域【JavaScript高级程序设计第三版】

    执行环境(execution context,为简单起见,有时也称为“环境”)是JavaScript 中最为重要的一个概念.执行环境定义了变量或函数有权访问的其他数据,决定了它们各自的行为.每个执行环 ...

  5. Java HotSpot(TM) 64-Bit Server VM warning: INFO: os::commit_memory(0x0000000

    启动程序报错: Java HotSpot(TM) 64-Bit Server VM warning: INFO: os::commit_memory(0x00000006fff80000, 28636 ...

  6. python——元组(tuple)基本操作

    元组被称为只读列表,数据可被查询,但不能被修改,类似于列表的切片操作,元组写在小括号里面()元素之前用逗号隔开 对于一些不想被修改的数据,可以用元组来保存 #  创建元组 1)创建空元组 # 创建空元 ...

  7. 【GUI】一、Swing外观框架BeautyEye使用

    一.Swing外观框架BeautyEye使用 1.1 导包 BeautyEye.jar 1.2 使用BeautyEye L&F public static void main(String[] ...

  8. 洛谷(P1006 传纸条)

    题目描述 小渊和小轩是好朋友也是同班同学,他们在一起总有谈不完的话题.一次素质拓展活动中,班上同学安排做成一个mm行nn列的矩阵,而小渊和小轩被安排在矩阵对角线的两端,因此,他们就无法直接交谈了.幸运 ...

  9. (长期更新)OI常用模板

    代码很简单的模板就不收录了. DFT 离散傅立叶变换 void dft(pdd *a,int l,bool r){ int i,j=l/2,k; for(i=1;i<l;++i){ if(i&l ...

  10. python2.7练习小例子(六)

        6):题目:斐波那契数列.     程序分析:斐波那契数列(Fibonacci sequence),又称黄金分割数列,指的是这样一个数列:0.1.1.2.3.5.8.13.21.34.……. ...