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 ...
随机推荐
- 剑指Offer编程题(Java实现)——链表中倒数第k个结点
题目描述 输入一个链表,输出该链表中倒数第k个结点. 注意: 该题目不可以用先反转链表再输出第k个结点的方式,因为反转链表会改变该结点的next指向 思路一 使用栈Stack倒序存储,顺序pop第k个 ...
- Spring Boot 深度调优,6得飞起~
项目调优 作为一名工程师,项目调优这事,是必须得熟练掌握的事情. 在SpringBoot项目中,调优主要通过配置文件和配置JVM的参数的方式进行. 一.修改配置文件 关于修改配置文件applicati ...
- [FJOI2007]轮状病毒 题解(dp(找规律)+高精度)
[FJOI2007]轮状病毒 题解(dp(找规律)+高精度) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/1335733 没什么好说的,直接把规律找出来,有 ...
- [LeetCode] 108. 将有序数组转换为二叉搜索树
题目链接 : https://leetcode-cn.com/problems/convert-sorted-array-to-binary-search-tree/ 题目描述: 将一个按照升序排列的 ...
- Django @csrf_exempt不能在类视图中工作(Django @csrf_exempt not working in class View)
我在Django 1.9中有一个使用SessionMiddleware的应用程序.我想在同一个项目中为这个应用程序创建一个API,但是在做一个POST请求时,它不能使用@csrf_exempt注释. ...
- Git 使用疑问
1) fatal: remote origin already exists. 解决办法 ..$ git remote add origin git@git.*.com:tang/comment_s ...
- webdriver 的使用 java 和python 两个版本
在使用webdriver前要先做下准备,1.下载相应的支持包,可以pom.xml文件引入 2.下载版本对应的浏览器驱动(我这里用的是chromedriver.exe),很多问题都是由于浏览器驱动引起的 ...
- if [ $? -eq 0 ]; then该语句是什么含义?
某个shell脚本 # mkimage.sh echo "make and copy android images" ./mkimage.sh ]; then echo " ...
- C#索引器2 字符串作为索引号
6.索引器 字符串作为索引号 public class Demo { private Hashtable name = new Hashtable(); public string this[st ...
- laplace transform 拉普拉斯变换
参考网址: 1. https://en.wikipedia.org/wiki/First-hitting-time_model 2. https://en.wikipedia.org/wiki/Lap ...