JavaScript modularity with RequireJS (from spaghetti code to ravioli code)
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'],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.
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)的更多相关文章
- 从Script到Code Blocks、Code Behind到MVC、MVP、MVVM
刚过去的周五(3-14)例行地主持了技术会议,主题正好是<UI层的设计模式——从Script.Code Behind到MVC.MVP.MVVM>,是前一天晚上才定的,中午花了半小时准备了下 ...
- 从Script到Code Blocks、Code Behind到MVC、MVP、MVVM(转载)
http://www.cnblogs.com/indream/p/3602348.html 刚过去的周五(3-14)例行地主持了技术会议,主题正好是<UI层的设计模式——从Script.Code ...
- jQuery选择器中,通配符[id^='code']input[id$='code'][id*='code']
1.选择器 (1)通配符: $("input[id^='code']");//id属性以code开始的所有input标签 $("input[id$='code']&qu ...
- 1.什么是Code First(EF Code First 系列)
EF4.1中开始支持Code First .这种方式在领域设计模式中非常有用.使用Code First模式,你可以专注于领域设计,根据需要,为你一个领域的对象创建类集合,而不是首先来设计数据库,然后来 ...
- Query的选择器中的通配符[id^='code']或[name^='code']
1.选择器 (1)通配符: $("input[id^='code']");//id属性以code开始的所有input标签 $("input[id$='code'] ...
- jQuery的选择器中的通配符[id^='code']或[name^='code']
这两天在做一个专题的时候遇到了一个通配符的问题 //弹层操作$(function(){ //视频播放 $("a[href^='#video']").each(function(in ...
- 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 ...
- 2.Vue 获取企业微信的Code并把Code发送的后台进行验证
1 . 在企业微信配置请求的页面写入下面代码 mounted() { //获取微信请求的的Code let code = this.$route.query.code; if (code) { thi ...
- 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 ...
随机推荐
- C++中的数组操作符重载
1,本文讲述数组操作符重载,上篇博文的字符串类 string 确实强大,但 string 类 对象还具备 C 方式字符串的灵活性吗?还能直接访问单个字符吗? 1,C 方式字符串灵活性是指能够通过数组 ...
- SI 和 MDK 添加Astyle功能
一. 什么是Astyle 1. Astyle是一个用来对C/C++代码进行格式化的插件,可在多个环境中使用.该插件基于 Artistic Style 开发 二. 软件获取地址 1.下载地址:https ...
- c++多线程并发学习笔记(1)
共享数据带来的问题:条件竞争 避免恶性条件竞争的方法: 1. 对数据结构采用某种保护机制,确保只有进行修改的线程才能看到修改时的中间状态.从其他访问线程的角度来看,修改不是已经完成了,就是还没开始. ...
- php批量POST修改
这是一个thinkphp中的批量修改的案例: 如需要删除多项,或者同时修改多项记录 要点: 前端表单中name要加[],如:<input type="hidden" name ...
- django学习笔记(五)
知识点概要 - Session - CSRF - Model操作 - Form验证(ModelForm) - 中间件 - 缓存 - 信号 内容详细: 1. Session 基于Cookie做用户验证时 ...
- C# wpf 列出文件夹所有文件
在网上找了 cmd输入 dir "要列出的文件夹*.*" /a /b /s>"要输出的文件" 可以重定向把文件夹内容输出到文件 tree "要列 ...
- [转载]ISE中COE与MIF文件的联系与区别
原文地址:ISE中COE与MIF文件的联系与区别作者:铁掌北京漂 在ISE中,当用Blcok Memory Generator 生成某个ROM模块时,经常要对ROM中的内容作初始化.这时,就需要我们另 ...
- VMware虚拟机磁盘文件vmdk单文件转多文件相互转换
设置环境变量 set PATH=%PATH%;D:\Program Files (x86)\VMware\VMware Workstation echo %PATH% C:\Users\Admi ...
- 前端之JavaScript:JS之DOM对象一
js之DOM对象一 一.什么是HTML DOM HTML Document Object Model(文档对象模型) HTML DOM 定义了访问和操作HTML文档的标准方法 HTML DOM 把 ...
- Apache+Mysql+PHP 套件
Apache+Mysql+PHP 套件 最近要装个Apache+Mysql+PHP的一个环境. google下后,发现现在的安装变得越来越简单了.不再需要麻烦的配置安装,只需简单执行个sh就搞定了 ...