Home >Web Front-end >JS Tutorial >JS modularity-RequireJS
Today I bring you JS modularization-RequireJS. What are the precautions about JS modularization and how to use RequireJS? The following is a practical case, let’s take a look.
I have always heard of RequireJS before, but I have never had the opportunity to understand it. I only know that it is an API for modularization of js. I'm working on React recently, and its componentization ideas coincide with js modularization ideas. I just want to add RequireJS to the project while applying React to see if it will have a good effect on page loading or development.
What is RequireJS?
Before explaining what RequireJS is, I have to mention the background of the history of Javascriptmodularization. In fact, in the early days, JavaScript emerged as an emerging scripting language with a huge vision. It was not a language designed only for the client. It’s just that with the popularity of web applications later, JavaScript quickly spread as a browser-side scripting language, and the competition between Netscape and Microsoft standardized it prematurely. This has led to many defects of JS, one of which is modularity (but you can be surprised to find that javascript actually uses import, export, etc. as reserved words, which shows that it was actually considered during the design. The new standard es6 also allows native Supports modularization). Then as web applications become more and more complex, more and more JavaScript codes are embedded, and with the rise of node, modular programming becomes a must.
So there was the module system later supported by the Dojo toolkit and Google's Closure library. There are also two very common standards specifications, CommonJS and AMD. I won’t go into details here. We only need to know that the API that implements the CommonJS specification loads modules synchronously, while the API that implements the AMD specification loads modules asynchronously.
So theoretically speaking, the non-blocking loading of AMD specifications is more suitable for the browser side. RequireJS is the best implementation of the AMD specification. Copy a description of RequireJS from an official document:
RequireJS is a JavaScript module loader. It's great for use in the browser, but it can also be used in other scripting environments, like Rhino and Node. Using RequireJS to load modular scripts will improve the loading speed and quality of your code.
Why RequireJS?
So, now that we know what RequireJS does, we almost know why we use RequireJS. But let’s summarize the benefits of using RequireJS.
Asynchronous "loading". We know that websites usually put the script at the end of the html, so as to avoid page blocking caused by the browser executing js. Using RequireJS, the callback function will be executed after the relevant js is loaded. This process is asynchronous, so it will not block the page.
Load on demand. Through RequireJS, you can load the corresponding js module when you need to load the js logic, thus avoiding a large number of requests and data transmission when initializing the web page. Perhaps for some people, some modules may not be available at all. If it is needed, then it seems unnecessary.
More convenient module dependency management. I believe you must have encountered dependency errors due to script tag order issues. This function is undefined, that variable is undefined, and so on. Through the mechanism of RequireJS, you can ensure that relevant files are executed after all dependent modules are loaded, so it can play a role in dependency management.
More efficient version management. Think about it, if you still use a script script to introduce a jQuery2. Go modify these 100 pages. But if your requireJS has jQuery path mapping in the config, then you only need to change one place.
Of course, there are other advantages such as cdn unable to load js files, local files can be requested, etc., which will not be listed here.
RequireJS Use
Files that need to be introduced in the page
<script data-main="js/main" src="xxx/xxxx/require.js"></script>
Using RequireJS, you only need to introduce a require.js. It should be noted that a better practice is that you should only introduce this js through the 3f1c4e4b6b16bbbd69b2ee476dc4f83a tag on your page. Then all the business logic of your page only needs to be written in main.js (the role of the data-main attribute will be discussed later). What to do with other referenced dependencies? Of course, it is introduced on demand through require!
Basic overview of Require
In fact, the entire source file of Requirejs, including comments, only has 2000 lines, and its externally exposed variables are actually three, requirejs, require, and define.
requirejs is just an alias of require. The purpose is that if there is another implementation of require in the page, you can still use requireJS API by using requirejs (there is no relevant conflict in this article, so require is still used).
So this means that as a starter, you only need to master require, require.config, and define.
本文将以介绍require,require.config,data-main,define的顺序来介绍RequireJS。让比较简单的RequireJS更加简单,争取让大家只看这篇文章就能用好RequireJS。至于RequireJS是如何解决循环依赖,对于没有实现amd的模块如何通过shim来导出,如何在node中使用等问题。本文并没有提及,详细有需要可以去官方查阅。
require.js可以通过npm下载或者在官网获得。jquery同理,jquery需要下载1.7.0或以上的版本。然后把对应的代码拷入对应的文件中,给出余下两个文件的代码:
// js/script/index.html<!DOCTYPE html><html><head> <title>Require Demo 1</title></head><body> <div> <h1>Require Demo 1 -- usage of Require()</h1> <button id="contentBtn">Click me</button> <p id="messagebox"></p> </div> <script data-main="js/script/main" src="js/lib/require.js" type="text/javascript"></script> </body></html> // js/script/main.js require.config( { paths: { 'jquery': '../lib/jquery-1.7.2' } } ); require(['jquery'],function ($) { $(document).on('click','#contentBtn',function(){ $('#messagebox').html('You have access Jquery by using require()'); }); });
先看index.html的代码,其实比较简单,页面上在js中会用到的就是一个button和一个p标签。然后整个页面就只是一个js文件是通过3f1c4e4b6b16bbbd69b2ee476dc4f83a标签加载的,就是require.js。注意到标签中有一个data-main属性,你现在只需要了解require.js会在加载完成以后通过回调方法去加载这个data-main里面的js文件,所以这个js文件被加载的时候,RequireJS已经加载执行完毕。
然后接着看main.js文件,里面被一个匿名立即执行函数所包括。在require.config(...)中,可以配置许多配置项,后面会有详细说明。上面在config中添加了一个path,在path配置了一个模块ID和路径的映射,这样在后续的所有函数中就可以直接通过模块ID来引入依赖,而不用再多次引入依赖多次输入路径带来的麻烦。
然后接着就是我们的require(...)函数了。上面的语法中require函数接受的第一个参数是,所依赖模块的一个数组。即使你只需要传入一个依赖,也需要把这个依赖放进数组中传入。如果你有如本例子中设置了模块ID和路径的映射,那你在传入依赖的时候就可以使用模块ID来代替路径,如果没有配置模块ID你当然也可以通过路径来引进对应的模块。接着是传入回调函数,当引入的依赖加载完毕后,这个回调函数就会被触发。如果你传入的依赖有注入变量(函数),然后在回调函数中需要用到,你就需要按照顺序在回调函数的参数中添加别名,在本例子中可以通过别名$来使用jQuery的相关API。所以有注入的模块需要放在无注入或者不需要调用模块的模块前面,方便回调函数传入别名。例子中在回调函数中为id为contentBtn的button注册监听事件,如果触发,则往id为messagebox的p标签添加相应的内容。
另外还需要额外说明的是路径,不管是在配置中写路径还是直接在require函数中写路径,你都需要了解requireJS在不同情况下的相对路径。
以下是相对路径的规则:
1.如果3f1c4e4b6b16bbbd69b2ee476dc4f83a标签引入require.js时没有指定data-main属性,则以引入该js的html文件所在的路径为根路径。
2.如果有指定data-main属性,也就是有指定入口文件,则以入口文件所在的路径为根路径。在本例子中也就是main.js所在的script文件夹就是根路径,这也是为什么配置jQuery的时候需要返回上层目录再进入lib目录才能找到jQuery文件。
3.如果再require.config()中有配置baseUrl,则以baseUrl的路径为根路径。
以上三条优先级逐级提升,如果有重叠,后面的根路径覆盖前面的根路径。
define
讲完了如何引入模块,现在讲如何定义一个模块,require定义一个模块是通过 define = function (name, deps, callback)完成的,第一个参数是定义模块名,第二个参数是传入定义模块所需要的依赖,第三个函数则是定义模块的主函数,主函数和require的回调函数一样,同样是在依赖加载完以后再调用执行。
先看个例子:
当你没有任何依赖的时候,你可以这么写:
// js/script/desc.jsdefine(function(){ return{ decs : 'this js will be request only if it is needed', };}) // 然后在main.js的添加如下代码// js/script/main.js $('#messagebox').html('You have access Jquery by using require()'); + require(['script/desc'],function(desc){ + alert(JSON.stringify(desc));
再次打开网页,打开network视图,点击按钮,通过require获得的desc模块就会alert出来,同时你会发现,desc.js是按需请求的,并不是在页面一开始的时候就请求的。
总结
以上就是关于关于RequireJS简单使用的介绍了,大家有需要可以直接看源码,大概就2000多行,不看具体实现,看它对几个函数声明的描述,对使用起来也是很有帮助的,你会发现有一些连官方文档都没提及到的一些特性(比如require()方法可以直接传入config配置作为第一个参数)。
In addition, a little aside, if you need to check the official API of RequireJS, it is recommended to visit the official English documentation directly if possible. If the official Chinese documentation is still stuck in the old version, forget it because the translation is jerky and difficult to understand. Some descriptions that are obviously wrong are really liability issues. It was really hard for me to understand when I was reading the Chinese document. Later, when I read the English document directly, it became much smoother.
I believe you have mastered the methods after reading these cases. For more exciting information, please pay attention to other related articles on the php Chinese website!
Related reading:
Use Video.js to implement H5 live broadcast interface
How to remember account and password with JS code
JavaScript basic mental data type
The above is the detailed content of JS modularity-RequireJS. For more information, please follow other related articles on the PHP Chinese website!