RequireJS 入门指南 已翻译 100%

oschina 投递于 2013/08/15 08:58 (共 8 段, 翻译完成于 08-19)
阅读 75705
收藏 178
19
加载中

Introduction

One of the most commonly used JavaScript libraries today is RequireJS. In every project that I’m involved lately, we use RequireJS or I suggest to add RequireJS. In this article I’m going to describe what RequireJS is and some of its basic scenarios.

Async Module Definitions (AMD) First

You can’t start talking about RequireJS without mentioning what JavaScript modules are and what AMD is.

JavaScript modules are just pieces of code that follow the SRP (Single Responsibility Principle) and expose a public API. In today’s JavaScript development, you encapsulate a lot of functionality inside modules and in most projects each module exists in its own file. That makes the life of JavaScript developers a little harder since they need to constantly watch for dependencies between modules and load the modules in a specific order or else have errors during runtime.

已有 1 人翻译此段
我来翻译

When you want to load JavaScript modules, you use script tags. In order to load module dependencies, you need to load the dependency first and then the dependent. When using script tags, you need to arrange their loading in that specific order and the scripts will be loaded synchronously. You can use the asyncanddeferkeywords to make the load asynchronous but you might lose the order of loading in the process. Another option is to bundle all the scripts but still you will need to order them in the right order during the bundling.

AMD is all about defining modules in a way that the module and its dependencies can be asynchronously loaded and in the right order.

Getting Started with RequireJS Library

CommonJS, which is an attempt to standardize common JavaScript patterns, includes an AMD definition that I encourage you to read before you proceed in this post. In ECMAScript 6, the JavaScript vNext specifications, there are specifications for exports, imports and modules which are going to be a part of the JavaScript language but only in the near future. This is where RequireJS is entering our story.

已有 1 人翻译此段
我来翻译

RequireJS?

RequireJS is a JavaScript file and module framework that can be downloaded from http://requirejs.org/ or by using Nuget, if you work in Visual Studio environment. It is supported both in the browsers and in server environments like node.js. Using RequireJS, you will load only the relevant module dependencies in their right order.

What RequireJS is doing when you use it is to create script tags for each dependency you defined and load those dependencies on-the-fly using thehead.appendChild()function. Then, after the dependencies are loaded, RequireJS will figure the right order to define the modules and will call each module definition in that right order. That means that you only need one root to load the entire functionality that you need and RequireJS will do the rest. In order to use that functionality appropriate, you will have to define each of your modules using RequireJS API or else nothing will work as expected.

已有 1 人翻译此段
我来翻译

RequireJS API exists inside thereq lang=jscriptuirejsnamespace which is loaded when you load the RequireJS script. RequireJS includes three main API functions:

  • define– the function is used to define a module. Each module is defined with a unique module ID which will be used by RequireJS runtime functionality. Thedefinefunction is a global function and you don’t need to use it with therequirejsnamespace.
  • require– the function is used to load required dependencies. It is a global function and you don’t need to use it with therequirejsnamespace.
  • config– the function is used to configure the requirejs runtime functionality.

Later on we will examine how to use those functions, but first lets understand how to start the RequireJS loading process.

已有 1 人翻译此段
我来翻译

The data-main Attribute

Once you downloaded RequireJS, the first thing to do after you put its script in your solution is to understand how RequireJS starts working. Once RequireJS is loaded, it search for a script withdata-mainattribute (it should be the same script with thesrcattribute set to load RequireJS). Thedata-mainshould be set to the base URL for all the scripts. From the base URL, RequireJS will start loading all the relevant modules. Here is an example of a script tag with thedata-mainattribute:

<script src="scripts/require.js" data-main="scripts/app.js"></script>

Another way to define the base URL is using theconfigfunction which we will see later on. RequireJS assumes that all the dependencies are scripts so when you declare a dependency you don’t need to use the .js suffix.

已有 1 人翻译此段
我来翻译

The config Function

If you want to change the default RequireJS configuration values with your own configurations, you can do that using therequirejs.config function. Theconfigfunction receives an options object that can include a lot of configurations options. Here are some of the configurations that you can use:

  • baseUrl– the root path to start the loading of modules.
  • paths– path mapping for modules that don’t exists in under the base URL
  • shims– configuration for dependencies, exports and initialization function to wrap scripts/modules that don’t use the RequireJSdefinefunction. For example, if underscore library doesn’t use the RequireJSdefinefunction and you still want to use it with RequireJS, you will have to define it as a shim in theconfigfunction. 
  • deps– array of dependencies to load.

Here is an example of using theconfigfunction:

require.config({
    //By default load any module IDs from scripts/app
    baseUrl: 'scripts/app',
    //except, if the module ID starts with "lib"
     paths: {
        lib: '../lib'
    }, 
    // load backbone as a shim
    shim: {
        'backbone': {
            //The underscore script dependency should be loaded before loading backbone.js
            deps: ['underscore'],
            // use the global 'Backbone' as the module name.
            exports: 'Backbone'
        }
    }
});

The base URL in the example is set to scripts/app, every module that starts with lib is configured to be used from the scripts/lib folder and backbone is loaded as a shim with dependencies.

已有 1 人翻译此段
我来翻译

Defining Modules Using RequireJS

Modules are just well-scoped objects that expose an API and encapsulate their internals. In order to define a module, RequireJS exposes thedefinefunction. There should be only one call fordefinein each JavaScript file by convention. Thedefinefunction receives an array of dependencies and a function which is going to hold all the module definitions. By convention the module definition function receives as parameters all the previous dependencies and in the order they were supplied in the array. For example, here is a simple module definition:

define(["logger"], function(logger) {        
        return {
             firstName: “John",
             lastName: “Black“,
             sayHello: function () {
                logger.log(‘hello’);
             }
        }
    }
);

As you can see, an array is passed to thedefinefunction with a logger dependency which is later used in the module. Also, you can see that in the module definition function there is a parameter calledloggerwhich will be set to the loaded logger module. Every module should return its API which in this case is two properties (firstNameandlastName) and a function (sayHello). Later on, if you will load this module as another module dependency with a module ID, you will be able to use the exposed API.

已有 1 人翻译此段
我来翻译

Using the require Function

Another useful function in RequireJS is therequirefunction. Therequirefunction is used to load dependencies without the creation of a module. For example, here is a usage of therequirefunction which defines a function that requires jQuery to work:

require(['jquery'], function ($) {
    //jQuery was loaded and can be used now
});

Summary

In the article, I introduced RequireJS which is one of the libraries that I’m using in every JavaScript app project. Other than just loading module dependencies and in the relevant order, RequireJS helps to write modular JavaScript code which is much more maintainable and reusable.

已有 1 人翻译此段
我来翻译
本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接。
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。
加载中

评论(37)

kkkppp7979
kkkppp7979

引用来自“stackvirgi”的评论

data-main属性这段里最后一句: 另外一种方式定义根路'劲'是使用配置函数, 错别字...
😓
请叫我小黄毛
两位兄弟讨论的很是激烈啊!不过,在下看来,关于require.js ,尔等认同也好,排斥也罢。他无疑是模块化最好的实现者之一。当下,前端模块化的呼声如此之高,乃至w3c新出台的ES6中也有相关内容,可见前端模块化已是大势所趋。
zhaoyou
zhaoyou

引用来自“jQer”的评论

引用来自“李惟”的评论

引用来自“jQer”的评论

引用来自“我是一名新人”的评论

引用来自“jQer”的评论

引用来自“我是一名新人”的评论

引用来自“jQer”的评论

引用来自“李惟”的评论

引用来自“jQer”的评论

引用来自“張凡”的评论

有沒有應用示例啊,看不出它的優勢哦

服务器用比较合适, 前端用会增加请求次数降低性能

你JS跟谁学的?不是这样的哦,传统的<script>存在几个问题:1.严格的读取顺序,多个文件互相依赖,依赖性最小的文件必须放在最前面,否则代码会报错;2.性能问题,浏览器采用"同步模式"加载<script>标签,也就是说,页面会"堵塞"。
##为了解决这些问题,可以使用DOM方法,动态加载Javascript文件。##,注意哦,动态加载JS,并不会造成性能问题,而是更好的解决JS性能问题

小孩子, 没有实战经验就别在这bb。 你去打听下谁家的商业站在浏览器端用require js的

多了去了,至少我知道,bat就有很多团队钻研这种,商业化场景也很多,举1,2个吧,百度统计,支付宝(支付宝用的是seajs,思想和这个差不多),commonjs,requirejs,seajs都是趋势啊

对于前端需要的是命名空间, 而不是文件路径。
require js 的目标就是一个文件一个类(对象), 调用某个对象时,直接通过对方的路径进行引用。
而对于前端, js文件最快速或者隐藏式的下载缓存到用户浏览器中, 以后不再要求用户对服务器请求js。 所有的js在合理的命名空间下管理。 一个懂请求的人怎么会用require js。

你不知道发布的时候有工具可以把所有的js打包到1个js文件吗?

如果在一个文件里, 你打算用require 多次一举的定义命名空间吗. 直接写个namespace() 函数就足够了

1.加载是加载,命名空间是命名空间,我不能说我有命名空间了,就不需要更好的加载方法了,这是两回事,这也是你的误区;2.require只是帮你更好的加载,但只是帮你更好的加载,而不是取代加载哦,他不会影响你的请求和再次请求

为什么 node.js采用了require js, juqery yui却不采用?

node.js 没有采用 require js. (require.js 是实现AMD 规范的一种)。Node.js 是实现的 Common Module define CMD )。当然 npm 里面是有requrejs 模块。
Ambitor
Ambitor
好激烈啊,看的好精彩啊。。哈哈 看了这么多 还是这位兄弟说的最恰当啊。。@simply哈哈
北京冰帆科技
北京冰帆科技

引用来自“jQer”的评论

引用来自“我是一名新人”的评论

引用来自“jQer”的评论

引用来自“我是一名新人”的评论

引用来自“jQer”的评论

引用来自“李惟”的评论

引用来自“jQer”的评论

引用来自“張凡”的评论

有沒有應用示例啊,看不出它的優勢哦

服务器用比较合适, 前端用会增加请求次数降低性能

你JS跟谁学的?不是这样的哦,传统的<script>存在几个问题:1.严格的读取顺序,多个文件互相依赖,依赖性最小的文件必须放在最前面,否则代码会报错;2.性能问题,浏览器采用"同步模式"加载<script>标签,也就是说,页面会"堵塞"。
##为了解决这些问题,可以使用DOM方法,动态加载Javascript文件。##,注意哦,动态加载JS,并不会造成性能问题,而是更好的解决JS性能问题

小孩子, 没有实战经验就别在这bb。 你去打听下谁家的商业站在浏览器端用require js的

多了去了,至少我知道,bat就有很多团队钻研这种,商业化场景也很多,举1,2个吧,百度统计,支付宝(支付宝用的是seajs,思想和这个差不多),commonjs,requirejs,seajs都是趋势啊

对于前端需要的是命名空间, 而不是文件路径。
require js 的目标就是一个文件一个类(对象), 调用某个对象时,直接通过对方的路径进行引用。
而对于前端, js文件最快速或者隐藏式的下载缓存到用户浏览器中, 以后不再要求用户对服务器请求js。 所有的js在合理的命名空间下管理。 一个懂请求的人怎么会用require js。

你不知道发布的时候有工具可以把所有的js打包到1个js文件吗?

如果在一个文件里, 你打算用require 多次一举的定义命名空间吗. 直接写个namespace() 函数就足够了

现在require js打包方案相当成熟,你能不能看一看别人的原理再来喷?现在稍微大点的公司都有用到require js,这个已经变成js的一个事实标准了,你就不要闭门造车了啊,多出去看看,好不?对了,你应该是小公司的吧?或者学生?
令狐乐儿
令狐乐儿
这个东西不是会增加页面的js的请求次数吗,这样做有必要?
simply
simply

引用来自“jQer”的评论

引用来自“李惟”的评论

引用来自“jQer”的评论

引用来自“我是一名新人”的评论

引用来自“jQer”的评论

引用来自“我是一名新人”的评论

引用来自“jQer”的评论

引用来自“李惟”的评论

引用来自“jQer”的评论

引用来自“張凡”的评论

有沒有應用示例啊,看不出它的優勢哦

服务器用比较合适, 前端用会增加请求次数降低性能

你JS跟谁学的?不是这样的哦,传统的<script>存在几个问题:1.严格的读取顺序,多个文件互相依赖,依赖性最小的文件必须放在最前面,否则代码会报错;2.性能问题,浏览器采用"同步模式"加载<script>标签,也就是说,页面会"堵塞"。
##为了解决这些问题,可以使用DOM方法,动态加载Javascript文件。##,注意哦,动态加载JS,并不会造成性能问题,而是更好的解决JS性能问题

小孩子, 没有实战经验就别在这bb。 你去打听下谁家的商业站在浏览器端用require js的

多了去了,至少我知道,bat就有很多团队钻研这种,商业化场景也很多,举1,2个吧,百度统计,支付宝(支付宝用的是seajs,思想和这个差不多),commonjs,requirejs,seajs都是趋势啊

对于前端需要的是命名空间, 而不是文件路径。
require js 的目标就是一个文件一个类(对象), 调用某个对象时,直接通过对方的路径进行引用。
而对于前端, js文件最快速或者隐藏式的下载缓存到用户浏览器中, 以后不再要求用户对服务器请求js。 所有的js在合理的命名空间下管理。 一个懂请求的人怎么会用require js。

你不知道发布的时候有工具可以把所有的js打包到1个js文件吗?

如果在一个文件里, 你打算用require 多次一举的定义命名空间吗. 直接写个namespace() 函数就足够了

1.加载是加载,命名空间是命名空间,我不能说我有命名空间了,就不需要更好的加载方法了,这是两回事,这也是你的误区;2.require只是帮你更好的加载,但只是帮你更好的加载,而不是取代加载哦,他不会影响你的请求和再次请求

为什么 node.js采用了require js, juqery yui却不采用?

这三个库你都没有说对厄..

首先, 没有 node.js 采用 require.js之说. node.js 是 commonJS 的一个实现.

其次, jQuery 在 1.7 版本加入 AMD 支持

何为 AMD? 度娘下吧. require.js 是AMD 的一个实现

最后, 关于 yui,
Y.add 也是一种异步模块加载.

你可以不用 require.js, 但是异步模块机制是发展所趋.

你所认知的 require.js 缺点 , AMD 社区早认识到, 并有相应的解决方案
niubo_
niubo_
前面的讨论还挺激烈的。不过话说RequireJS也好,AMD规范也好,确实存在很大争议,接触SeaJS的时候多少了解过一点。只能说每种技术都有特定的理念和设计哲学,很多都是针对某些特定范围的问题而出现的。从这点来看RequireJS肯定不是可以敲尽世间所有钉子的大锤。
技术人员在不同公司解决着不同的问题,使用着不同的技术,用久了肯定对自己熟悉的领域有着各种各样的心得和见解。你不能拿着自己熟悉的技术或者解决问题的思路非要跟别人一较高下对吧。解决问题的途径有很多种,每种都有自己的优缺点,每个人都可能出于不同的关注点来权衡。即使你用的是最优的解决方法,也并不是说用其他方法的人都是死路一条。
大家兴致勃勃讨论感兴趣的技术时突然插一脚上来劈头就是一句什“么狗屁玩意”——我只能说这种人只是不解风情而已,跟技术无关。
好了,看了前面这么多评论不吐不快……
niubo_
niubo_

引用来自“-萧-”的评论

这种写法让我想起来DOJO

因为新版的DOJO和RequireJS一样也开始遵守AMD规范了呗。
jQer
jQer

引用来自“李惟”的评论

引用来自“jQer”的评论

引用来自“李惟”的评论

引用来自“jQer”的评论

引用来自“我是一名新人”的评论

引用来自“jQer”的评论

引用来自“我是一名新人”的评论

引用来自“jQer”的评论

引用来自“李惟”的评论

引用来自“jQer”的评论

引用来自“張凡”的评论

有沒有應用示例啊,看不出它的優勢哦

服务器用比较合适, 前端用会增加请求次数降低性能

你JS跟谁学的?不是这样的哦,传统的<script>存在几个问题:1.严格的读取顺序,多个文件互相依赖,依赖性最小的文件必须放在最前面,否则代码会报错;2.性能问题,浏览器采用"同步模式"加载<script>标签,也就是说,页面会"堵塞"。
##为了解决这些问题,可以使用DOM方法,动态加载Javascript文件。##,注意哦,动态加载JS,并不会造成性能问题,而是更好的解决JS性能问题

小孩子, 没有实战经验就别在这bb。 你去打听下谁家的商业站在浏览器端用require js的

多了去了,至少我知道,bat就有很多团队钻研这种,商业化场景也很多,举1,2个吧,百度统计,支付宝(支付宝用的是seajs,思想和这个差不多),commonjs,requirejs,seajs都是趋势啊

对于前端需要的是命名空间, 而不是文件路径。
require js 的目标就是一个文件一个类(对象), 调用某个对象时,直接通过对方的路径进行引用。
而对于前端, js文件最快速或者隐藏式的下载缓存到用户浏览器中, 以后不再要求用户对服务器请求js。 所有的js在合理的命名空间下管理。 一个懂请求的人怎么会用require js。

你不知道发布的时候有工具可以把所有的js打包到1个js文件吗?

如果在一个文件里, 你打算用require 多次一举的定义命名空间吗. 直接写个namespace() 函数就足够了

1.加载是加载,命名空间是命名空间,我不能说我有命名空间了,就不需要更好的加载方法了,这是两回事,这也是你的误区;2.require只是帮你更好的加载,但只是帮你更好的加载,而不是取代加载哦,他不会影响你的请求和再次请求

对于你的技术, 我只能说你写的代码都是烂到家的文件依赖代码。
一个良好的js文件夹中的代码, 只有一个总框架文件和其他组件代码文件,依赖于这唯一一个文件。
还加载顺序, 先好好组织你的代码编写能力吧

诺,这不就是你的误区么,我想无论我、还是你,还是大家凡是尽力过公司项目开发,都应该切实感受到过:无论多大的项目,无论多大的公司,凡是多人项目开发的,必然会有多个JS文件,或者多请求,虽然这不是硬性规定,但却是避免不了,注意哦,我是在说实际,不是在说概念哦,大家想想是不是如此呢。更重要的是,我不能因为一些优点而摒弃其他的特点,举例子吧,比如说我有了命名空间,就放弃了请求,我不能因为目的是打包JS,而说明其他代码就不够好,我不能因为有了YUI,就说明node.js不对。就好比,不能因为面包不错,我们就放弃吃饭,你说是不是呢?

说什么呢, 多人合作啊, 共建一个文件, 好好跟你的同事协商好接口, 我觉得再跟你说下去就是废话了, 完全说不通了
返回顶部
顶部