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 ...
随机推荐
- Java——HashMap底层源码分析
1.简介 HashMap 根据键的 hashCode 值存储数据,大多数情况下可以直接定位到它的值,因而具有很快的访问速度,但遍历顺序却是不确定的. HashMap 最多只允许一条记录的key为 nu ...
- Two modules in a project cannot share the same content root报错解决方案
观察上方是否出现两个同样的项目,删除不需要的那个,我觉得是因为两个项目同时引用一个根目录文件导致的.
- Vue 实现手动刷新组件
Vue 实现手动刷新组件:https://www.jianshu.com/p/742142dc95f3
- Tomcat 一台机器运行多个Tomcat
转 https://www.cnblogs.com/andy1234/p/8866588.html 在一台Win10 PC 上面同时开启两个Tomcat系统为例. 1. 硬件环境 2. 到Tomcat ...
- P1056排坐椅
这是2008普及组真题,是一个提高—的模拟. 仔细读完题便有了思路:累放在i行能隔开wi个,比较排序wi,输出即可.所以在这里遇到了结构体排序的问题与手写cmp的问题.对于两个语法知识掌握得都不好,所 ...
- P1106删数游戏
这道题曾经在CQOJ上考过,是第二次做了. 这是一道使用字符串的贪心题.首先要根据机组例子来确定:删除递增序列的最后一位.即循环找到那一位后,把后面的数往前压.所以我在艰难处理完双重循环后(这个处理不 ...
- [LeetCode] 107. 二叉树的层次遍历 II
题目链接 : https://leetcode-cn.com/problems/binary-tree-level-order-traversal-ii/ 题目描述: 给定一个二叉树,返回其节点值自底 ...
- spring controller 方法测试
controller 测试 不使用其他api接口测试工具 一般而言,我们写好一个模块后,会对其进行单元测试,再集成到现有的系统中. 但是呢~针对Controller.Service.Dao三层来说,我 ...
- MySQL第一讲 一一一一 数据库入门
一. MySQL简介与安装 MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,目前属于 Oracle 旗下产品.MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方 ...
- python email模块
python email模块 官方文档 email模块 电子邮件包是一个用于管理电子邮件消息的库.它的特殊设计不用于向SMTP (RFC 2821).NNTP或其他服务器发送任何电子邮件消息;这些是模 ...