http://netmvc.blogspot.com/2012/11/javascript-modularity-with-requirejs.html

Today I would like to describe how you can make your JavaScript code much much much better.

We know a lot about how to make our c# code much better. And we always use it.
We split out our c# code to classes, put the classes to modules, put the modules to layers, etc.

But we never do the same for our JavaScript code. And this is a big mistake.

And that's why we have a lot of Spaghetti Code inside our apps.

The main problems with function spaghetti code are:

  • It's really hard to figure out where the one block of code begins and where the other ends
  • Who's responsible for what?
  • How are we deal with global scope pollution (e.g. use the same variables in different pieces of code)
  • Low code re-use
  • Not easy to maintain, test and debug.

I'm not going to describe in details what the functional spaghetti code
is, because you can find a lot of references in the Internet.
I would like to show here how to avoid it and make your code better using RequireJS.

RequireJS

The following command in the Package Manager console will install RequireJS package into your ASP.NET application:

PM > Install-Package RequireJS

RequireJS is a JavaScript file
and module loader. It is optimized for in-browser use, but it can be
used in other JavaScript environments, like Rhino and Node. Using a
modular script loader like RequireJS will improve the speed and quality
of your code.

In other words RequireJS really helps:

  • To define our modules
  • To resolve module dependencies
  • To load scripts in the proper order (and asynchronously)

So, RequireJS really helps to define a structure to the modules in a JavaScript applications.

RequireJS modules

First I would like to show how you can create modules using RequireJS.
I will use the same example as I used to show how to create a JavaScript module.

define('messenger',
['jquery'],
function ($) {
var text = 'I am a module',
showMessage = function() {
$("#messagebox").html(text);
}; return {
showMessage: showMessage
};
}
);

It looks as easy as a JavaScript module. But I would like to describe some differences.
The RequireJS module starts with:

define('messenger',

Where 'messenger' is the module ID. You can use this ID if you want to reference this module in other modules.

The next line describes dependencies of this module:

['jquery'],
In this example our module depends on jQuery only.

And then you have to specify module body as a function.

As you can see it's really simple to create a module using RequireJS.

 

Using RequireJS

Let's change all of our modules.

config.js
define('config', //module id
[], //no dependency
function () {
var baseUrl = '/api/messenger/'; return {
baseUrl: baseUrl
};
}
);

dataservice.js

define('dataservice',  //module id
['jquery', 'config'], //depend on two other modules
function ($, config) {
var
callApi = function (url, type, callback) {
$.ajax({
url: url,
type: type,
dataType: 'json',
success: function (data) {
callback(data);
}
});
}, getMessage = function (id, callback) {
url = config.baseUrl + id;
callApi(url, 'GET', callback);
}; return {
getMessage: getMessage
};
}
);

messager.js

define('messenger',   //module id
['jquery', 'dataservice'], //depend on two modules
function ($, dataservice) {
var showMessage = function (id) {
dataservice.getMessage(id, function (message) {
$("#messagebox").html(message);
});
}; return {
showMessage: showMessage
};
}
);

main.js

(function() {
requirejs.config(
{
paths: {
'jquery': '../Scripts/jquery-1.8.2.min'
}
}
); require(
['messenger'],
function(messenger) {
var id = 55;
messenger.showMessage(id);
}
);
})();

All of the modules look as they were before, except of main module.

In this module I have configured RequireJS to specify where RequiteJS can find the jquery module.

requirejs.config(
{
paths: {
'jquery': '../Scripts/jquery-1.8.2.min'
}
}
);

After all, we have to change our HTML to load our modules.

index.html

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Phase 1</title>
</head>
<body>
<div>
<h1>Modular Demo 1</h1>
</div>
<div id="messagebox"></div> <script data-main="main" src="../Scripts/require.js" type="text/javascript"></script> </body>
</html>

Small remarks about our HTML changes.

We should not load any of our modules or jQuery, because RequireJS will handle it for us.
We have to load RequireJS only, and specify 'data-main' attribute,
which tells RequireJS to load main.js script after RequireJS loads. In
other words, we specify start up script in 'data-main' attribute.

And after all RequireJS does the 'magic' and loads all of our modules in proper order automatically.

As a result, our code becomes much much better now, as I promised at the beginning of this post.

That's all. And see you next time.

 
 

JavaScript modularity with RequireJS (from spaghetti code to ravioli code)的更多相关文章

  1. 从Script到Code Blocks、Code Behind到MVC、MVP、MVVM

    刚过去的周五(3-14)例行地主持了技术会议,主题正好是<UI层的设计模式——从Script.Code Behind到MVC.MVP.MVVM>,是前一天晚上才定的,中午花了半小时准备了下 ...

  2. 从Script到Code Blocks、Code Behind到MVC、MVP、MVVM(转载)

    http://www.cnblogs.com/indream/p/3602348.html 刚过去的周五(3-14)例行地主持了技术会议,主题正好是<UI层的设计模式——从Script.Code ...

  3. jQuery选择器中,通配符[id^='code']input[id$='code'][id*='code']

     1.选择器 (1)通配符: $("input[id^='code']");//id属性以code开始的所有input标签 $("input[id$='code']&qu ...

  4. 1.什么是Code First(EF Code First 系列)

    EF4.1中开始支持Code First .这种方式在领域设计模式中非常有用.使用Code First模式,你可以专注于领域设计,根据需要,为你一个领域的对象创建类集合,而不是首先来设计数据库,然后来 ...

  5. Query的选择器中的通配符[id^='code']或[name^='code']

        1.选择器 (1)通配符: $("input[id^='code']");//id属性以code开始的所有input标签 $("input[id$='code'] ...

  6. jQuery的选择器中的通配符[id^='code']或[name^='code']

    这两天在做一个专题的时候遇到了一个通配符的问题 //弹层操作$(function(){ //视频播放 $("a[href^='#video']").each(function(in ...

  7. VSX(翻译)Moving Code Blocks Among Code Regions using VS 2010 Extensions

    Moving Code Blocks Among Code Regions using VS 2010 Extensions (翻译)使用VS 2010 扩展性将代码块移至Region区域中 Down ...

  8. 2.Vue 获取企业微信的Code并把Code发送的后台进行验证

    1 . 在企业微信配置请求的页面写入下面代码 mounted() { //获取微信请求的的Code let code = this.$route.query.code; if (code) { thi ...

  9. VS Code Just My Code Debugging

    VS Code Just My Code Debugging VS Code for C++ doesn't support Just My Code Refer here: Add support ...

随机推荐

  1. P1162填涂颜色

    这还是一个搜索题,难度较低,但我提交第三次才AC.. 观察0地图左上角的上面和左面都是一,所以先把他找粗来,然后设成start,然后dfs找到与他联通的块,涂成2即可.再说一下自己犯的低级错误:1.当 ...

  2. [luogu5339] [TJOI2019]唱、跳、rap和篮球(容斥原理+组合数学)(不用NTT)

    [luogu5339] [TJOI2019]唱.跳.rap和篮球(容斥原理+组合数学)(不用NTT) 题面 略 分析 首先考虑容斥,求出有i堆人讨论的方案. 可以用捆绑法,把每堆4个人捆绑成一组,其他 ...

  3. CSP-J&S 2019游记

    $Day -???$ 和爱国爱党的$LQX$书记打了个赌,谁$TG$分低请另一个京味斋. $Day 0$ 机房同学去聚餐,美其名曰"散伙饭",可能又有几个进队的... 我没有去,因 ...

  4. Redis : 为什么我们做分布式使用 Redis ?(转)

    绝大部分写业务的程序员,在实际开发中使用 Redis 的时候,只会 Set Value 和 Get Value 两个操作,对 Redis 整体缺乏一个认知.这里对 Redis 常见问题做一个总结,解决 ...

  5. 剑指offer-复杂链表的复制-链表-python

    题目描述 输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head.(注意,输出结果中请不要返回参数中的节点引用,否 ...

  6. iOS开发之详解剪贴板

    关于UIMenuController的用法例子 今天终于搞明白了UIMenuController显示的相关内容,把源代码分享给大家! 要正常显示菜单,必须做到以下几点:1. -(BOOL)canBec ...

  7. 使用量产工具合并U盘空间一例

      1.问题提出: 朋友拿到一只别人赠送的广告U盘,上面印刷有产品广告.插入电脑后,在系统的磁盘管理中,显示为两块“硬盘”,其中一块“硬盘”中有广告视频.产品介绍等,占用大概6GB,这块“硬盘”中的这 ...

  8. 〇——什么是SHELL

    在这段时间里中我们了解一下SHELL编程. 什么是shell shell是Linux的命令解释器,用于解释用户对操作系统的操作. 用shell解释的Linux命令有很多,可以通过cat/etc/she ...

  9. java并发学习--第七章 JDK提供的线程工具类

    一.ThreadLocal ThreadLocal类用于隔离多线程中使用的对象,为ThreadLocal类中传递的泛型就是要隔离的对象,简单的来说:如果我们在主线程创建了一个对象,并且需要给下面的多线 ...

  10. 微信公众号接口类(PHP版本)

    [项目需求] 通过微信提供的接口,实现微信公众号与后端的应用程序数据交互.消息响应等功能. [项目疑难点] 理解接口工作方式,统一接口API,响应速度.安全性等   [代码举例]   WeixinAp ...