合并js 和用requirejs js合并冲突吗

使用 RequireJS 按需动态加载JS | 尘埃
使用 RequireJS 按需动态加载JS
PS:基于 AMD(Asynchronous Module Definition)的 JavaScript 设计已经在目前较为流行的前端框架中大行其道,jQuery、Dojo、MooTools、EmbedJS 等纷纷在其最新版本中加入了对 AMD 的支持。本文介绍的是另一款较为精简的 RequireJS 框架,既想使用 AMD 的特性又不想引入一个庞大的库的开发人员,不妨试试 RequireJS。RequireJS 可以帮助用户异步按需的加载 JavaScript 代码,并解决 JavaScript 模块间的依赖关系,提升了前端代码的整体质量和性能
前端开发在近一两年发展的非常快,JavaScript作为主流的开发语言得到了前所未有的热捧。大量的前端框架出现了,这些框架都在尝试着解决一 些前端开发中的共性问题,但是实现又不尽相同。在这个背景下,CommonJS社区诞生了,为了让前端框架发展的更加成熟,CommonJS鼓励开发人员 一起在社区里为一些完成特定功能的框架制定规范。 AMD(Asynchronous Module Definition) 就是其中的一个规范。
传统JavaScript代码的问题
让我们来看看一般情况下JavaScript代码是如何开发的:通过&script&标签来载入JavaScript文件,用全局变量 来区分不同的功能代码,全局变量之间的依赖关系需要显式的通过指定其加载顺序来解决,发布应用时要通过工具来压缩所有的JavaScript代码到一个文 件。当Web项目变得非常庞大,前端模块非常多的时候,手动管理这些全局变量间的依赖关系就变得很困难,这种做法显得非常的低效。
AMD (Asynchronous Module Definition) 的引入
从名称上看便知它是适合script tag的。也可以说AMD是专门为浏览器中JavaScript环境设计的规范。它吸取了CommonJS的一些优点,但又不照搬它的格式。开始AMD作为CommonJS的存在,因无法与CommonJS开发者达成一致而独立出来。它有自己的和
AMD提出了一种基于模块的异步加载JavaScript代码的机制,它推荐开发人员将JavaScript代码封装进一个个模块,对全局对象的依 赖变成了对其他模块的依赖,无须再声明一大堆的全局变量。通过延迟和按需加载来解决各个模块的依赖关系。模块化的JavaScript代码好处很明显,各 个功能组件的松耦合性可以极大的提升代码的复用性、可维护性。这种非阻塞式的并发式快速加载JavaScript代码,使Web页面上其他不依赖 JavaScript代码的UI元素,如图片、CSS以及其他DOM节点得以先加载完毕,Web页面加载速度更快,用户也得到更好的体验。
CommonJS的AMD规范中只定义了一个全局的方法,如清单1所示
define(id?, dependencies?, factory);
该方法用来定义一个 JavaScript 模块,开发人员可以用这个方法来将部分功能模块封装在这个 define 方法体内
dependencies 是一个字符串 Array,表示该模块依赖的其他所有模块标识,模块依赖必须在真正执行具体的 factory 方法前解决,这些依赖对象加载执行以后的返回值,可以以默认的顺序作为 factory 方法的参数。dependencies 也是可选参数,当用户不提供该参数时,实现 AMD 的框架应提供默认值为 [“require”,”exports”,“module”]。
factory 是一个用于执行改模块的方法,它可以使用前面 dependencies 里声明的其他依赖模块的返回值作为参数,若该方法有返回值,当该模块被其他模块依赖时,返回值就是该模块的输出。
CommonJS 在规范中并没有详细规定其他的方法,一些主要的 AMD 框架如 RequireJS、curl、bdload 等都实现了 define 方法,同时各个框架都有自己的补充使得其 API 更实用。
AMD设计出一个简洁的写模块API:
define(id?, dependencies?, factory);
id: 模块标识,可以省略。
dependencies: 所依赖的模块,可以省略。
factory: 模块的实现,或者一个JavaScript对象。
以下是使用AMD模式开发的简单三层结构(基础库/UI层/应用层):
定义无依赖的模块
(base.js)
define(function() {
mix: function(source, target) {
定义有依赖的模块
(ui.js,page.js)
define(['base'], function(base) {
show: function() {
// todo with module base
define(['data', 'ui'], function(data, ui) {
// init here
定义数据对象模块 (data.js)
users: [],
members: []
define('index', ['data','base'], function(data, base) {
具名模块多数时候是不推荐的,一般由打包工具合并多个模块到一个js文件中时使用。
前面提到dependencies元素的顺序和factory一一对应,其实不太严谨。AMD开始为摆脱CommonJS的束缚,开创性的提出了自己的模块风格。但后来又做了妥协,兼容了 CommonJS
Modules/Wrappings
。即又可以这样写
define(function(require, exports, module) {
var base = require('base');
exports.show = function() {
// todo with module base
不考虑多了一层函数外,格式和Node.js是一样的。使用require获取依赖模块,使用exports导出API
除了define外,AMD还保留一个关键字require。
&作为规范保留的全局标识符,可以实现为module loader。也可以不实现。
目前,实现AMD的库有&、&、&、、&、&等。
也有很多库支持AMD规范,即将自己作为一个模块存在,如&、&、&、&&甚至还有&
require.config({
jquery: 'jquery-1.7.2'
require(['jquery'], function($) {
alert($().jquery);
main.js中就两个函数调用require.config和require。
require.config用来配置一些参数,它将影响到requirejs库的一些行为。require.config的参数是一个JS对象,常用的
有baseUrl,paths等。
这里配置了paths参数,使用模块名“jquery”,其实际文件路径jquery-1.7.2.js(后缀.js可以省略)。
这里require函数的第一个参数是数组,数组中存放的是模块名(字符串类型),数组中的模块与回调函数的参数一一对应。这里的例子则只有一个模块“jquery”。
我们知道jQuery从1.7后开始支持AMD规范,即如果jQuery作为一个AMD模块运行时,它的模块名是“jquery”。注意“jquery”是固定的
,不能写“jQuery”或其它。
如果文件名“jquery-1.7.2.js”改为“jquery.js”就不必配置paths参数了。
require.config中config可以省略
jQuery中的支持AMD代码如下
if ( typeof define === "function" && define.amd && define.amd.jQuery ) {
define( "jquery", [], function () { return jQ } );
访问index.html,网络请求如下
我们看到除了require.js外main.js和jquery-1.7.2.js也请求下来了。而它们正是通过requirejs请求的
* 暂无相关文章
1、本站所有主题由该文章作者发表,该文章作者与享有文章相关版权
2、其他单位或个人使用、转载或引用本文时必须同时征得该文章作者和的同意
3、本帖部分内容转载自其它媒体,但并不代表本站赞同其观点和对其真实性负责
4、如本帖侵犯到任何版权问题,请立即告知本站,本站将及时予与删除并致以最深的歉意
5、原文链接:
Posted in ,
2016 年三月
14151617181920
21222324252627
牛逼的人儿requirejs(shim)处理加载非AMD规范的js库-爱编程
requirejs(shim)处理加载非AMD规范的js库
  使用requirejs加载模块,模块的定义得遵守AMD规范,也即定义模块的时候使用如下函数定义模块:
1 define(function(){
var private = function(){
console.log('私有方法...');
public:function(){private();}
  即使用define包括模块代码,如果想在requirejs中嵌入自己以前的某些代码,但是这些代码没有遵守AMD规范,该怎么办呢?骚年不用担心,require的config中的shim能帮你解决痛苦!例如本人的文件目录结构如下:
我想要在quikTip.js文件中使用framewokr.js提供的对象,但是framework.js是不遵守AMD规范的,在quikTip.js文件中require &framework模块之前必须先处理下framework.js使其符合AMD规范,代码如下:
1 require.config({
baseUrl:'js/utily',//指定js文件的基路径
'framework':{//这个键名为要载入的目标文件的文件名,不能随便命名否则加载framework.js文件后是拿不到改文件对外提供的接口的。因为这个坑了哥一下午!!!
exports:'PXJSFrame'//exports的值为framework.js提供的 对外接口的名称
9 require(['framework'],function(frame){
var PXJSFrame =
console.log(frame);//此处就会打印framework.js中对外提供的接口对象啦哈啊哈
版权所有 爱编程 (C) Copyright 2012. . All Rights Reserved.
闽ICP备号-3
微信扫一扫关注爱编程,每天为您推送一篇经典技术文章。前一篇:JS模块化工具requirejs教程(一):初识requirejs 我们以非常简单的方式引入了requirejs,这一篇将讲述一下requirejs中的一些基本知识,包括API使用方式等。基本APIrequire会定义三个变量:define,require,requirejs,其中require === requirejs,一般使用require更简短define 从名字就可以看出这个api是用来定义一个模块require 加载依赖模块,并执行加载完后的回调函数前一篇中的a.js:define(function(){
function fun1(){
alert(&it works&);
fun1();})通过define函数定义了一个模块,然后再页面中使用:require([&js/a&]);来加载该模块(注意require中的依赖是一个数组,即使只有一个依赖,你也必须使用数组来定义),requir API的第二个参数是callback,一个function,是用来处理加载完毕后的逻辑,如:require([&js/a&],function(){
alert(&load finished&);})加载文件之前的例子中加载模块都是本地js,但是大部分情况下网页需要加载的JS可能来自本地服务器、其他网站或CDN,这样就不能通过这种方式来加载了,我们以加载一个jquery库为例:require.config({
&jquery& : [&/jquery/2.0.3/jquery&]
}})require([&jquery&,&js/a&],function($){
$(function(){
alert(&load finished&);
})})这边涉及了require.config,require.config是用来配置模块加载位置,简单点说就是给模块起一个更短更好记的名字,比如将百度的jquery库地址标记为jquery,这样在require时只需要写[&jquery&]就可以加载该js,本地的js我们也可以这样配置:require.config({
&jquery& : [&/jquery/2.0.3/jquery&],
&a& : &js/a&
}})require([&jquery&,&a&],function($){
$(function(){
alert(&load finished&);
})})通过paths的配置会使我们的模块名字更精炼,paths还有一个重要的功能,就是可以配置多个路径,如果远程cdn库没有加载成功,可以加载本地的库,如:require.config({
&jquery& : [&/jquery/2.0.3/jquery&, &js/jquery&],
&a& : &js/a&
}})require([&jquery&,&a&],function($){
$(function(){
alert(&load finished&);
})})这样配置后,当百度的jquery没有加载成功后,会加载本地js目录下的jquery在使用requirejs时,加载模块时不用写.js后缀的,当然也是不能写后缀上面例子中的callback函数中发现有$参数,这个就是依赖的jquery模块的输出变量,如果你依赖多个模块,可以依次写入多个参数来使用:require([&jquery&,&underscore&],function($, _){
$(function(){
_.each([1,2,3],alert);
})})如果某个模块不输出变量值,则没有,所以尽量将输出的模块写在前面,防止位置错乱引发误解全局配置上面的例子中重复出现了require.config配置,如果每个页面中都加入配置,必然显得十分不雅,requirejs提供了一种叫&主数据&的功能,我们首先创建一个main.js:require.config({
&jquery& : [&/jquery/2.0.3/jquery&, &js/jquery&],
&a& : &js/a&
}})然后再页面中使用下面的方式来使用requirejs:&script data-main=&js/main& src=&js/require.js&&&/script&解释一下,加载requirejs脚本的script标签加入了data-main属性,这个属性指定的js将在加载完reuqire.js后处理,我们把require.config的配置加入到data-main后,就可以使每一个页面都使用这个配置,然后页面中就可以直接使用require来加载所有的短模块名data-main还有一个重要的功能,当script标签指定data-main属性时,require会默认的将data-main指定的js为根路径,是什么意思呢?如上面的data-main=&js/main&设定后,我们在使用require([&jquery&])后(不配置jquery的paths),require会自动加载js/jquery.js这个文件,而不是jquery.js,相当于默认配置了:require.config({
baseUrl : &js&})解释一下,加载requirejs脚本的script标签加入了data-main属性,这个属性指定的js将在加载完reuqire.js后处理,我们把require.config的配置加入到data-main后,就可以使每一个页面都使用这个配置,然后页面中就可以直接使用require来加载所有的短模块名data-main还有一个重要的功能,当script标签指定data-main属性时,require会默认的将data-main指定的js为根路径,是什么意思呢?如上面的data-main=&js/main&设定后,我们在使用require([&jquery&])后(不配置jquery的paths),require会自动加载js/jquery.js这个文件,而不是jquery.js,相当于默认配置了:第三方模块通过require加载的模块一般都需要符合AMD规范即使用define来申明模块,但是部分时候需要加载非AMD规范的js,这时候就需要用到另一个功能:shim,shim解释起来也比较难理解,shim直接翻译为&垫&,其实也是有这层意思的,目前我主要用在两个地方 1. 非AMD模块输出,将非标准的AMD模块&垫&成可用的模块,例如:在老版本的jquery中,是没有继承AMD规范的,所以不能直接require[&jquery&],这时候就需要shim,比如我要是用underscore类库,但是他并没有实现AMD规范,那我们可以这样配置require.config({
&underscore& : {
exports : &_&;
}})这样配置后,我们就可以在其他模块中引用underscore模块:require([&underscore&], function(_){
_.each([1,2,3], alert);})插件形式的非AMD模块,我们经常会用到jquery插件,而且这些插件基本都不符合AMD规范,比如jquery.form插件,这时候就需要将form插件&垫&到jquery中:require.config({
&underscore& : {
exports : &_&;
&jquery.form& : {
deps : [&jquery&]
}})也可以简写为:require.config({
&underscore& : {
exports : &_&;
&jquery.form& : [&jquery&]
}})这样配置之后我们就可以使用加载插件后的jquery了require.config([&jquery&, &jquery.form&], function($){
$(function(){
$(&#form&).ajaxSubmit({...});
})})好了,requirejs的基本配置大致就是这么多,还有一些扩展的功能会在之后的篇幅中提到文章来源:/liuxey/blog/issues/2 
 文章为作者独立观点,不代表微头条立场
的最新文章
什么是bowerBower是一个客户端技术的软件包管理器,它可用于搜索、安装和卸载如JavaScript、H每一个行业都有自己的"潜规则", "黑话", "共识", 软件行业也不例外, 来测一测你对软件行业了解多少?前言前两天看到 Polymer 1.0 发布了,出于好奇,来试试水,体验下,感受下 WebComponent在HTML中,在文件上传的过程中,很多情况都是没有任何的提示,这在体验上很不好,用户都不知道到时有没有在上传背景前端任务打包工具选用的是 gulp, 当时选用 gulp 也是偶然,在使用 grunt 初期,翻阅 daExpressJS入门指南(二)作者:chszs,转载需注明。博客主页:http://blog.csdn.n响应式布局响应式布局Phones and HandheldsiPhonesGalaxy PhonesHTC 真的就3件事?如果构造函数有返回值呢?new至少做了4件事new的不足再说一点关于constructor的参
大约是三月初吧,在网上看到一道面试题,怎么判断一个变量类型是不是数组。然后从犀牛书以及查阅一些资简介Web 应用程序越来越关注于前端,使用客户端脚本与 Ajax 进行交互。由于 JavaScript 应用  GIF/PNG/JPG/WEBP/APNG都是属于位图(位图 ,务必区别于矢量图);  GIF/PNG和bowerBower 是 twitter 推出的一款包管理工具,基于nodejs的模块化思想,把功能分散到各Flux is the application architecture that Facebook use和properties一样,state(状态)影响着一个组件的行为和渲染. 但与properties不同的是Properties(属性)对于React就像Attribute对于HTML.事实上, 在JSX中, proComponents(以下称为&组件&)是React最小但是最重要的组成部分.在概念上类似于&模块&,&插件事实上 React 用称之为Component 的来代替了View层. Component包括了两种对象: props (存储当创建对象实例时传递的不会变化的参数) 和 state (包括了Component当前状态React is “A JavaScript library for building user interfaces”. 前一篇:JS模块化工具requirejs教程(一):初识requirejs 我们以非常简单的方式引入了re随着网站功能逐渐丰富,网页中的js也变得越来越复杂和臃肿,原有通过script标签来导入一个个的js文件这种JSZip 是一款可以创建、读取、修改 .zip 文件的 javaScript 工具。在 web 应用中,免起因深入解析Page Visibility APIPage Visibility API使用方法起因最近浏览起因深入解析Page Visibility APIPage Visibility API使用方法起因最近浏览WebRTC是争取开放和无阻碍Web的漫长战争中一条新战线题记:JavaScript中有很多令人困惑的地方,或者叫做机制。但是,就是这些东西让JavaScript显得由于同源策略的限制,Javascript跨域的问题,一直是一个比较棘手的问题,为了解决页面之间的跨域通信,大家煞费苦心,研究了各种跨域方案。今天要讨论的话题是TypeScript。之前在微博上转载过一篇《The Rise of TypeScript之前在博客上写了一篇装逼的博客《我是如何同时拿到阿里和腾讯offer的》,在文章上面本着学习和共享的精神分享了自己的简历,无意中暴露了不少个人隐私,结果这几天不少认识的和不认识的朋友都加我QQ或微信,请叫我怎么学习Web。对于前端开发人员,在开发过程中经常需要监控某些表达式或变量的值,如果使用用 debugger 会显得过于笨重最近两年前端圈子犹如春秋战国:群雄并起,中原未定,就连各路大神也纷纷感叹最近两年技术选型难做。10月10日在丹麦举行的Goto会议上,谷歌Dart语言项目的领导人Lars Bak宣布推出编程语言Dart。Lars Bak表示,Dart是一种“结构化的Web编程”语言,Dart编程语言在所有现代的浏览器和环境中提供高性能。\n\nCSS3 大大强化了制作动画的能力,但是如果要做出图案比较复杂的动画,选择 GIF 依然是一个不错的选择。真的就3件事?如果构造函数有返回值呢?new至少做了4件事new的不足再说一点关于constructor的参 一、聊天室简单介绍  采用nodeJS设计,基于express框架,使用WebSocket编程之 sock响应式布局响应式布局Phones and HandheldsiPhonesGalaxy PhonesHTC node中文社区Node.js专业中文社区:https://cnodejs.org/ node文档node.gh_15d32a71b93c介绍各种前端技巧,帮助提高前端开发的速度,逐渐做到分分钟完成开发。热门文章最新文章gh_15d32a71b93c介绍各种前端技巧,帮助提高前端开发的速度,逐渐做到分分钟完成开发。URL中的!和RequireJS的插件机制 - welefen的随笔
URL中的!和RequireJS的插件机制
去年下半年开始,团队内部开始使用RequireJS作为模块加载器,并且建立了对应的模块化展现和开发平台。
前几天有个同事问我,使用RequireJS来加载一个CDN上的JS文件,没有得到预期的效果。代码大致如下:
require([&/!b964179a/widget.1.0.2.js&], function(){
//logic code
查看了下对应的network,发现请求的URL并不是/!b964179a/widget.1.0.2.js,而是变成了/?r=4。这样返回的内容并不是一个JS,而是HTML,导致有脚本错误。
仔细查看了下URL,发现除了!这个特殊字符外,没有什么可疑的地方。拿着!去RequireJS的源码里查找,发现了如下的代码:
//Turns a plugin!resource to [plugin, resource]
//with the plugin being undefined if the name
//did not have a plugin prefix.
function splitPrefix(name) {
var prefix,
index = name ? name.indexOf('!') : -1;
if (index & -1) {
prefix = name.substring(0, index);
name = name.substring(index + 1, name.length);
return [prefix, name];
原来RequireJS里的插件机制使用了!作为分隔符,由于URL里含有!,导致URL被分割成2部分,最终请求的URL并不是我们预期的URL。
RequireJS里的插件机制
当时由于时间有限,让同事临时换了个URL,今天仔细看了下RequireJS的插件机制。
RequireJ核心只是个加载器,通过动态创建script标签来加载模块化的JS文件。但项目开发中,仅仅加载JS文件有时候并不能满足我们的需求,如:加载一个HTML片段,DomReady后执行,国际化语言包处理等等。
为了解决这些问题,RequireJS提供了插件的机制,插件和要加载的模块之间使用!分割。如:
require(['foo!something/for/foo'], function (something) {
//something is a reference to the resource
//'something/for/foo' that was loaded by foo.js.
这里的foo是个插件,somthing/for/foo是个模块。RequireJS会优先加载foo这个插件对应的JS文件,然后插件里根据自己的逻辑处理something/for/foo模块。
RequireJS官方默认提供了一些插件,如:text,domReady,i18n。
插件使用方法
这里通过text插件大致介绍下插件的使用方法。
text插件可以用来加载一个非JS文件的内容,如:HTML片段,CSS片段。
可以从下载text插件,可以放到RequireJS的plugins目录下。
require.js文件在module/require/2.1.8/require.js
text.js文件在module/requirejs/2.1.8/plugins/text.js
那么就可以通过下面的方式来使用:
require([&module/require/2.1.8/plugins/text.js!html/a.html&], function(content){
console.log(content)
其中module和html是平行的目录,并且是配置baseUrl的目录下。
这样通过text插件就可以拿到html/a.html的内容了,实际上text插件是通过ajax去获取内容的。
既然RequireJS使用了!作为插件的分隔符,那URL中就不能含有!了。
ps: URL含有!本身感觉也挺奇怪的。
本文链接:

我要回帖

更多关于 requirejs js合并 的文章

 

随机推荐