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.
作者:Chuck Lu GitHub |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
2017-06-26 ISheet ICell
2014-06-26 委托的begininvoke
2014-06-26 C# 给某个方法设定执行超时时间
2014-06-26 C#中的Invoke----control上的以及delegate的是不一样的