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. Mybatis—动态sql拼接问题

    背景:使用Mybatis的最近半年,经常发现一些小坑,现在总结回顾下,记个小本本,不让它再来欺负我! 百度了许久,才留心到官网文档,比我的全,我很菜的! *************<if> ...

  2. Windows node.js安装运行npm显示类似"ENOENT, stat 'C:\Users\XXXX\AppData\Roaming\npm'错误

    这个错误是在玩一个小的博客的时候,使用到node.js,正好使用的是windows系统就安装了一个windows32的node.js版本 结果一运行npm就出现如上的错误,后来发现,只要在上面提到的目 ...

  3. 使用idea搭建SSH

    一.新建项目 选中Spring strust2 hibernate 二.见项目根路径下的lib下的jar移动到WEB-INF下 移动 修改路径 在lib目录下导入[c3p0-0.9.5.2.jar]. ...

  4. 题解 CF1119A 【Ilya and a Colorful Walk】

    此题就是:给你一个数组,让你找出两个不同的元素,并让它们的下标差距最大. 思路:从2到n,如果与1不同,记录距离,与原数比较,取大. 从1到n-1,如果与n不同,记录距离,与原数比较,取大. AC代码 ...

  5. PHP之简单工厂模式(二)

    定义 简单工厂模式,通过定义一个工厂类,负责完成类实例的创建,根据参数的不同返回不同的类实例.对外部来讲,只需传入一个正常的参数就可以获得想要的对象,而不必需要具体创建细节.创建类实例的方法通常为静态 ...

  6. burp intruder模块详解

    0×01 介绍 安装要求: Java 的V1.5 + 安装( 推荐使用最新的JRE ), 可从这里免费 http://java.sun.com/j2se/downloads.html Burp Sui ...

  7. tornado + nginx + supervisord 环境部署

    学习tornado有一周多了,自己按着demo中的例子手动搬代码,收获还是有的,加深了理解.demo: http://demo.pythoner.com/itt2zh/ch8.html 大概明白了它怎 ...

  8. Restful,SAOP,SOA,RPC的基础理解

    什么是Restful restful是一种架构设计风格,提供了设计原则和约束条件,而不是架构.而满足这些约束条件和原则的应用程序或设计就是 RESTful架构或服务. 主要的设计原则: 资源与URI ...

  9. 自动化部署三剑客 gitlab + ansible + jenkins

    http://www.showerlee.com/archives/1880 https://edu.51cto.com/center/course/lesson/index?id=280700 Gi ...

  10. 03javascript01

    1.javascript语法体系 1)EMCA基础语法(统一) 2)BOM编程(不统一) 3)DOM编程(不统一) 1.1 javascript使用 <!DOCTYPE html> < ...