JavaScript 模块化开发实例详解【seajs、requirejs库使用】

本文实例讲述了JavaScript 模块化开发。分享给大家供大家参考,具体如下:

JS开发的问题

  • 冲突
  • 依赖
  • JS引入的文件,产生依赖.

使用命名空间解决:

  • 命名空间的弊端
  • 调用的时候 名字比较长.
  • 只能减低冲突,不能完全避免

SeaJs使用

  1. 引入sea.js的库
  2. 如何变成模块? define
  3. 如何调用模块? exports 和 seajs.use
  4. 如何依赖模块? require
//html:
<script src="js/sea.js" type="text/javascript" charset="utf-8"></script>

<script type="text/javascript">

//      console.log( seajs );

seajs.use('./js/main.js',function ( main ) {

  main.show();

});      

</script>
//main.js
define(function ( require,exports,module ) {

  var header = require('./header.js');

  function show () {

    alert(123);

  }

  exports.show = show;

});

seajs.use()

加载一个或多个模块

// 加载一个模块
seajs.use('./main.js');

// 加载一个模块,在加载完成时,执行回调
seajs.use('./main.js', function ( main ) {

});

// 加载多个模块,在加载完成时,执行回调
seajs.use(['./main.js', './b'], function(a, b) {
 a.doSomething();
 b.doSomething();
});

seajs.use 与 DOM ready 事件没有任何关系。如果某些操作要确保在 DOM ready 后执行,需要使用 jquery 等类库来保证。

seajs.use(['jquery','./main'],function ( $,main ) {

  $(function () {

    main.init();

  })

});

use方法第一个参数一定要有,但是可以是null,也可以是一个变量

var app = ['app.js', 'header.css', 'header.js'];

seajs.use(app, function( app ) {
  //do something
});

seajs.use() 只用于加载启动, 不应该出现在define的模块代码中,如果模块代码里需要加载其它模块时,使用 require() ,需要加载异步其它异步模块时,使用 require.async()

seajs.use 是模块加载器必备的一个接口

define函数

当传递一个参数时候,那么这个参数就是一个模块,参数可以是任意类型
传递一个字符串,那么这个模块就是一个字符串模块
传递一个对象的时候,那么这个模块就是一个对象模块

传递一个函数(最常用的方式)
这函数自带三个参数
Require:引用其他模块的工厂方法
Exports:返回的接口对象
Module:模块module属性

当传递过参数时(两个,或者三个)
如果传递两个参数的时候,第一个该模块依赖的模块数组集合,最后一个参数是function
如果传递三个参数的时候,第一个表示该模块的名称,第二个参数表示该模块依赖的模块集合,第三个

//第一个参数,当前模块的ID,也就是当前模块的地址
//第二个参数,以来模块的地址的数组

define('./main.js',['./drag.js'],function( require,exports,moduels ){

});

三个参数解释

require

  • require不能简写
  • require不能被重定义
    不能赋值:var req = require
    不能定义函数:function require
    不能被子函数当成参数
    不能在子函数作用域内重定义

    // 错误 - 重命名 "require"!
    var req = require, mod = req("./mod");

    // 错误 - 重定义 "require"!
    require = function() {};

    // 错误 - 重定义 "require" 为函数参数!
    function F(require) {}

    // 错误 - 在内嵌作用域内重定义了 "require"!
    function F() {

     var require = function() {};

    }

  • require的参数只能是完整的字符串 require(‘abc' + ‘bcd')是不允许的

exports

  • 模块的接口
  • 第一种,直接对exports添加属性,如exports.color = 'red'
  • 第二种,通过module来定义,module.exports.color = 'red'
  • 第三种,通过module来定义,module.exports = {color: 'orange'}
  • 第四种,通过return来定义, return {color: 'green'}
  • 在一个模块中定义接口时候要用一种方式,不能混用
  • 注意,不可以直接对exports赋值新对象

module

  • 模块的属性
  • id:表示模块的id
  • uri:表示该模块文件对应的url
  • exports:表示模块返回的接口集合
  • dependencies:表示依赖模块集合(数组表示形式)
  • deps:表示依赖模块集合(对象表示形式)

CMD 模块定义规范

一个模块就是一个文件

define 是一个全局函数, 用来定义模块

define( facotry )

facotry可以是一个函数,也可以是一个对象或字符串

definde( { color: 'tan' } );

当参数为 函数时。 默认会有三个参数 :require,exports,module

definde( function ( require,exports,module ) {

} );

define ([id,deps],factory)

define 也可以接受两个以上的参数,字符串id表示模块标识。deps是模块依赖。

define('main',['mina.js'],function ( require,exports,module ) {
  //模块代码
});

id ,deps 参数省略,可以通过构建工具自动生成。
id和 deps 参数, 不属于CMD规范。

require function

require 是一个方法,接受 模块标识 作为唯一参数,用来获取其他模块提供的接口。

deifne(function ( requrie,exports ) {

  //获取模块 main 的接口
  var main = require('./main');

  //调用 模块 main 中的定义方法
  main.init();

});

require.async(id,[cb]);
模块内部异步加载模块,并在加载完成后执行指定的回调函数。

require.async('./a',function(){});
//加载多个异步模块
require.async(['./a','./b'],function(){});  

//异步加载 所需要的模块
define(function ( require,expotrs,module ) {

  var loadSync = false;

  if ( loadSync ) {

    var skin = require.async('./skin');

  } else {

    var header = require.async('./header');

  }

});

exports

exports , 用来向外提供模块接口

define(function ( require, exports,module ) {

 // 对外提供 foo 属性
 exports.color = 'pink';

 // 对外提供 doSomething 方法
 exports.doSomething = function() {};

});


通过return 提供接口

define(function () {

  //通过 return 直接提供接口
  return {
    color: 'deeppink',
    sayName: function () {}
  }

});

CMD模块中,经常使用的API 有:define,require,require.async,exports,module.expotrs

seajs 配置

seajs.config()

alias

定义模块别名
当引用一些基础库的时候,涉及到基础库升级,在alias中定义这个模块时,修改只需要修改这个别名配置。

seajs.config({
  alias: {
    jquery: 'lib/jquery.1.10.1'
  }
});

模块中使用

require('jquery');

paths

定义模块路径
一些模块创建目录结构很深的时候,可以将这个层级定义成一个简写的path, 引用这个模块的时候,直接通过 pathName+模块名称。

seajs.config({

paths: {
  hd: './modules/header'
}

});

模块中使用

require('hd/header.js');

vars

在某些情况下,模块路径在运行时才能确定,可以使用 vars 变量来配置。

seajs.config({
  vars: {
    skin: 'header/skin'
  }
});

模块中使用

require('{skin}/skin.js'); //需要使用 {} 来标识

map

映射配置,匹配文件,做映射处理
开发完一些模块时候,需要打包或压缩处理,此时文件名可能会不同,可以通过map映射,来找到这个文件,修改成对应的文件名

seajs.config({
  map: [
    ['main.js','main-min.js']
  ]
});

seajs.use(['main'],function ( main ) {
  // do ...
});

base

设置模块的根目录
有时候开发用seajs不一定在当前页面目录下,此时想引用这个模块比较麻烦,可以通过base来重定义该页面模块文件根目录。

charset

设置模块的编码格式

seajs.config({
  charset: 'utf-8'
});

seajs.config({
 charset: function(url) {

  // xxx 目录下的文件用 gbk 编码加载
  if (url.indexOf('http://example.com/js/xxx') === 0) {
   return 'gbk';
  }

  // 其他文件用 utf-8 编码
  return 'utf-8';

 }
});

常用的配置项: alias,paths,base

seajs插件

seajs-preload.js

<script type="text/javascript" src="js/lib/seajs-preload.js"></script>
加载js文件

seajs.config({
  //预加载jquery文件
  preload: ['jquery.js']
});

模块中文件使用

definde(function ( require,exports,module ) {
  $(document).css('background','tan');
});

seajs-css.js

加载css文件

<script type="text/javascript" src="js/seajs-css.js"></script>

definde(function ( require,expotrs,module ) {
  require('../css/css.css');
});

requireJs

引入模块文件时候,requirejs是根据引用了require文件的script标签中data-main属性对应的文件所在的目录

define定义模块

传递一个对象可以
传递一个函数(commonjs规范的实现)
区别 在于module

id表示模块的id,id没有后缀名(注意:seajs有后缀名)
没有依赖的模块集合
config配置属性

模块接口

在AMD规范定义的模块中,没有exports参数,只能通过return将接口暴露出来。

  • return 对象,这种方式可以将模块内部多个属性多个方法暴露出来。
  • return 方法,这种方式将一个方法返回出来,引用这个模块就是引用这个接口方法,在它父模块(引用它的模块中)可以直接调用该方法。是在自己模块的作用域中。

requirejs配置

baseUrl

设置根目录
用途:有时候启动文件不在预期的位置,可以通过baseUrl来设置根目录

require.config({
  baseUrl: 'lib'
});

paths

简写路径

require.config({
  paths: {
    hd: 'module/header'
  }
});

map

当存在多个页面,可能每个页面引用代码库不一样,可以通过map进行配置,对每个文件配置不同的代码库文件。

require.config({
  map: {
    //modules 模块下的dom模块引用的是lib/dom
    'modules': {
      'dom': 'lib/dom'
    },
    //modules-new 模块下的dom模块引用的是lib/dom.2.0
    'modules-new': {
      'dom': 'lib/dom.2.0'
    }
  }

});

使用css插件

requireJs 加载css 插件

//配置
require.config({
  map: {
    '*': {
      'css': 'lib/css'
    }
  }
});

//使用 

define(['css!css/index.css'],function () {
});

shim

表示配置模块依赖关系
对于一些定义在全局作用域下的代码库,常常获取不到这类库的模块,此时通过定义shim的莫开依赖关系,可以在模块中获取到这类代码库。

require.config({
  shim: {
    'lib/jquery': {
      //依赖的模块集合
      deps: [],
      expotrs: '$'
    }
  }
});

感兴趣的朋友可以使用在线HTML/CSS/JavaScript代码运行工具:http://tools.jb51.net/code/HtmlJsRun测试上述代码运行效果。

更多关于JavaScript相关内容感兴趣的读者可查看本站专题:《javascript面向对象入门教程》、《JavaScript错误与调试技巧总结》、《JavaScript数据结构与算法技巧总结》、《JavaScript遍历算法与技巧总结》及《JavaScript数学运算用法总结》

希望本文所述对大家JavaScript程序设计有所帮助。

(0)

相关推荐

  • Seajs 简易文档 提供简单、极致的模块化开发体验

    非官方文档,整理来自己官方文档的文字与实例,方便速查. 为什么使用 Sea.js ? Sea.js 追求简单.自然的代码书写和组织方式,具有以下核心特性: 简单友好的模块定义规范:Sea.js 遵循 CMD 规范,可以像 Node.js 一般书写模块代码. 自然直观的代码组织方式:依赖的自动加载.配置的简洁清晰,可以让我们更多地享受编码的乐趣. Sea.js 还提供常用插件,非常有助于开发调试和性能优化,并具有丰富的可扩展接口. 兼容性 Sea.js 具备完善的测试用例,兼容所有主流浏览器: C

  • 了解Javascript的模块化开发

    小A是某个创业团队的前端工程师,负责编写项目的Javascript程序. 全局变量冲突 根据自己的经验,小A先把一些常用的功能抽出来,写成函数放到一个公用文件base.js中: 复制代码 代码如下: var _ = {     $: function(id) { return document.getElementById(id); },     getCookie: function(key) { ... },     setCookie: function(key, value) { ...

  • JavaScript模块化开发之SeaJS

    前言   SeaJS是一个遵循CommonJS规范的JavaScript模块加载框架,可以实现JavaScript的模块化开发及加载机制.使用SeaJS可以提高JavaScript代码的可读性和清晰度,解决目前JavaScript编程中普遍存在的依赖关系混乱和代码纠缠等问题,方便代码的编写和维护. SeaJS本身遵循KISS(Keep it Simple,Stupid)理念进行开发,后续的几个版本更新也都是吵着这个方向迈进. 如何使用SeaJS 下载及安装在这里不赘述了,不了解的请查询官网. 基

  • 详解JavaScript模块化开发

    什么是模块化开发? 前端开发中,起初只要在script标签中嵌入几十上百行代码就能实现一些基本的交互效果,后来js得到重视,应用也广泛起来了,jQuery,Ajax,Node.Js,MVC,MVVM等的助力也使得前端开发得到重视,也使得前端项目越来越复杂,然而,JavaScript却没有为组织代码提供任何明显帮助,甚至没有类的概念,更不用说模块(module)了,那么什么是模块呢? 一个模块就是实现特定功能的文件,有了模块,我们就可以更方便地使用别人的代码,想要什么功能,就加载什么模块.模块开发

  • javascript 构建模块化开发过程解析

    在使用 sea.js .require.js . angular 的时候. 我们使用到 define . module(require) 的方式,定义模块,和依赖模块 下面给出 define 和 module 的简单实现. 其本质,就是往一个对象上面添加方法 var F = {}; F.define = function(str,fn){ var parts = str.split("."); var parent = this; // parent 当前模块的父模块 var i =

  • seajs和requirejs模块化简单案例分析

    本文实例讲述了seajs和requirejs模块化.分享给大家供大家参考,具体如下: 如今,webpack.gulp等构件工具流行,有人说seajs.requirejs等纯前端的模块化工具已经被淘汰了,我不这么认为,毕竟纯前端领域想要实现模块化就官方来讲,还是有一段路要走的.也因此纯前端的模块化工具依然有价值,而且就我了解一些中小企业一直都在用纯前端的模块化手段. 如今,重新关注seajs和requirejs,不求理解多么深刻,要求会用能用就可以. 模块化的起因是传统的直接引入js方法存在问题:

  • 在Html中使用Requirejs进行模块化开发实例详解

    在前端模块化的时候,不仅仅是js需要进行模块化管理,html有时候也需要模块化管理.这里就介绍下如何通过requirejs,实现html代码的模块化开发. 如何使用requirejs加载html Reuqirejs有一个text的插件,它可以读取指定文件的内容,读取到的内容就是文本. 如何下载text插件 第一种方法,可以通过npm下载: npm install requirejs/text 第二种方法,也可以直接去官方github上面直接下载. 直接拷贝内容到text.js中即可. 如何安装t

  • 基于RequireJS和JQuery的模块化编程——常见问题全面解析

    由于js的代码逻辑越来越重,一个js文件可能会有上千行,十分不利于开发与维护.最近正在把逻辑很重的js拆分成模块,在一顿纠结是使用requirejs还是seajs的时候,最终还是偏向于requirejs.毕竟官方文档比较专业嘛... 不过即便是有完整的官方文档,仍然遇到不少的问题,比如jquery-ui的使用. 下面就循序渐进的讲解一下我遇到的问题,以及解决的办法. 关于AMD和CMD的理解 AMD(异步模块定义)的典型就是requirejs,而CMD(通用模块定义)的典型是淘宝的seajs.

  • JavaScript的模块化开发框架Sea.js上手指南

    Sea.js所有源码都存放在 GitHub 上:https://github.com/seajs/examples,目录结构为: examples/ |-- sea-modules 存放 seajs.jquery 等文件,这也是模块的部署目录 |-- static 存放各个项目的 js.css 文件 | |-- hello | |-- lucky | `-- todo `-- app 存放 html 等文件 |-- hello.html |-- lucky.html `-- todo.html

  • 深入探寻seajs的模块化与加载方式

    由于一直在使用,所以了解了下seajs的源代码.这里是我对下面几个问题的理解: 1.seajs的require(XXX)的方法是怎样实现模块加载的? 2.为什么需要预加载? 3.为什么需要构建工具? 4.构建前后的代码究竟有些什么区别,为什么要这么做? 问题1: seajs的require(XXX)的方法是怎样实现模块加载的? 代码逻辑比较绕,对源代码的理解放在文章的末尾,这里先简单梳理下模块加载的逻辑: 1.从seajs.use方法入口,开始加载use到的模块. 2.use到的模块这时mod缓

  • 基于RequireJS和JQuery的模块化编程日常问题解析

    由于js的代码逻辑越来越重,一个js文件可能会有上千行,十分不利于开发与维护.最近正在把逻辑很重的js拆分成模块,在一顿纠结是使用requirejs还是seajs的时候,最终还是偏向于requirejs.毕竟官方文档比较专业嘛... 不过即便是有完整的官方文档,仍然遇到不少的问题,比如jquery-ui的使用. 下面就循序渐进的讲解一下我遇到的问题,以及解决的办法. 关于AMD和CMD的理解 AMD(异步模块定义)的典型就是requirejs,而CMD(通用模块定义)的典型是淘宝的seajs.

  • 使用requirejs模块化开发多页面一个入口js的使用方式

    描述 知道requirejs的都知道,每一个页面需要进行模块化开发都得有一个入口js文件进行模块配置.但是现在就有一个很尴尬的问题,如果页面很多的话,那么这个data-main对应的入口文件就会很多.理论这样其实也没什么,但是到后面用grunt进行合并压缩就会有很多入口js,虽然这个入口js都把配置的模块内容都压缩到里面了,但是各个入口合并压缩后的文件中其实都有很多重合的代码,所以考虑到这个就想到把所以的入口文件都统一了,使用一个,到时候用grunt合并压缩也只有这么一个入口文件,也很方便. 实

随机推荐