英文版地址
最近使用 Require.Js 的时候我发现它确实是一个改善代码管理的一个好方法。我以前发表Backbone类的文章时曾提到过 Require,但此前,我从未在传统的多页面网站内使用到 Require。在多页面网站里面配置 Require 的过程相当繁琐,所以我想将教程整理出来帮助那些可能会遇到困惑的朋友们。
概述
注意,本文假设你已经熟悉 Require.Js 和基本的配置使用方法,如果不是,建议你先看看官网的手册。
创建一个单页应用 (single-page App) 时,许多人喜欢在发布之前把所有的js文件全部打包编译为一个文件,可以减少断断续续的 http 请求,操作体验简洁明快更像 app,同样的,这种做法增加了首次加载时页面的量级。
部署多页面站点的时候,编译合并所有文件并非一个好方案,因为你不能保证用户会访问到每一个页面,而且加载中的文件会有很多用不到的js,这拖慢了页面渲染速度,用户体验变差。比如说,用户只是访问了Contact页面,那么有必要把About页面要用到的js给加载一遍吗?
完美的情景是每一个页面都有自己的 main 文件用来存放特定页面的方法,外加一个独立文件(最好是缓存起来)用来存放公共 Javascript 库。
例如,你有一个About页面和一个 Contact 页面,于是你新建一个 mian-about.js 和一个 main-contact.js,而且假设 mian-about 和 main-contact 都需要 jQuery 和 underscore。这时,不建议把 jQuery 和 underscore 编译到每一个 main 文件里面,那样会造成不必要的重复和臃肿,我们只用新建一个包含 jQuery 和 underscore 的 common.js 并且保证它在 mian-*.js 文件之前加载就可以了。下表可以加深理解:
common.js
----------------
js/vendor/jquery.js
js/vendor/underscore.js
About
----------------
js/common.js
js/app/main-about.js
Contact
----------------
js/common.js
js/app/main-contact.js
将那些公用的 js 文件编译合并到 common.js 后减少了每个页面的 http 请求,而且,第一个页面加载完毕,common.js 就可以从浏览器缓存里直接读取了。下面我们再来看一个例子。
例子
RequireJS 的作者 James Burke,做了很多有效组织代码,利用 RequireJS Optimizer 压缩优化代码的努力,有些例子是我经常提到的:example-multipage-shim.,example-multipage。但我更喜欢用 shim 版本(它支持非 AMD 方式定义的模块载入)的 RequireJS,因为一个项目里面似乎总有几个非 AMD 的脚本文件。
如果你在用RequireJs创建一个单页站点,那么你可能会这样定义你的script标签:
<!--This sets the baseUrl to the "scripts" directory, and
loads a script that will have a module ID of 'main'-->
<script data-main="scripts/main.js" src="scripts/require.js"></script>
data-main 属性可以很方便的用来设置 RequireJs 的 baseUrl property,通常,你也可以在 main.js 里面加上一些配置,比如,你要加载一个第三方的js库,你要创建一个路径以便引用。因为模板里的每一个单页的 mian-* 文件都不同,所以,我们可以把配置信息放在 common.js 里:
//The build will inline common dependencies into this file. requirejs.config({
baseUrl: './js',
paths: {
'jquery': 'vendor/jquery',
'bootstrap': 'vendor/bootstrap'
},
shim: {
'bootstrap': ['jquery']
}
});
除了 common.js,我还在 app/models 下创建了BasicModel文件以表明common.js是公用的,并把BasicModel放进common.js里。
编译
编译之前需要有一个 option.js 来指定哪些文件需要编译,哪些不需要:
module.exports = {
appDir: 'www',
baseUrl: 'js/',
mainConfigFile: 'www/js/common.js',
dir: 'www-release',
modules: [
{
name: 'common',
include: [
'app/models/basicModel',
'jquery',
'bootstrap'
]
},
{
name: 'app/main-about',
exclude: ['common']
},
{
name: 'app/main-contact',
exclude: ['common']
}
]
};
上面的代码中,首先把所有的文件用 include 方法包含进来,然后把不需要的文件用 exclude 方法排除出去。RequireJs 会根据 exclude 的参数配置理出嵌套依赖关系并把文件排除掉。因为 bootstrap 已经编译合并进 common.js 了,所以不需要单独为 main-about 或 main-contact 再 exclude 掉 bootstrap。
在执行这些操作之前,你需要执行一个 npm 安装。首先你要确保安装了 grunt 工具,安装完成后执行 grunt 命令压缩打包。如果打包顺利完成,会在www-release/build.txt 里看到如下被打包的文件清单:
css/bootstrap-responsive.css
----------------
css/bootstrap-responsive.css css/bootstrap.css
----------------
css/bootstrap.css css/style.css
----------------
css/style.css js/common.js
----------------
js/common.js
js/app/models/basicModel.js
js/vendor/bootstrap.js js/app/main-about.js
----------------
js/app/models/aboutModel.js
js/app/main-about.js js/app/main-contact.js
----------------
js/app/models/contactModel.js
js/app/main-contact.js
www-release/common.js 里面试一大块压缩后的代码,代码里就包含了 BasicModel, Bootstrap, jQuery, and 初始配置代码。要配置 about.html ,只需要按下面的顺序加载文件即可:
<script src="./js/vendor/require.js"></script>
<script type="text/javascript">
// Load common code that includes config,
// then load the app logic for this page.
require(['./js/common'], function (common) {
// ./js/common.js sets the baseUrl to be ./js/
// You can ask for 'app/main-about' here instead
// of './js/app/main-about'
require(['app/main-about']);
});
</script>
通过层层引入 RequireJs --> common.js --> main-about.js 实现了明晰简便的代码管理方式。
谢谢。
前端技术文章翻译QQ群:338353879
如何利用Require.Js管理多页面站点文件(译)的更多相关文章
-
利用require.js实现javascript模块化加载
这种引入很看到很想死吧! <script src="1.js"></script> <script src="2.js">& ...
-
require.js使用baseUrl + paths导入文件配置的3种方法
//main.js requirejs.config({ baseUrl: 'lib/js',//参照于引入这个js文件的index.html页面的相对路径,因为此时mian.js文件已经导入到了in ...
-
利用zepto.js实现移动页面图片全屏滑动
HTML <%-- Created by IntelliJ IDEA. User: fanso2o Date: 2017/2/28 Time: 16:09 To change this temp ...
-
javascript模块化编程库require.js的用法
随着javascript的兴起,越来越多的公司开始将JS模块化,以增加开发的效率和减少重复编写代码的.更是为了能更加容易的维护日后的代码,因为现在的随着人们对交互效果的越来越强烈的需求,我们的JS代码 ...
-
对require.js 的使用进行总结
一.为什么要使用require.js 首先一个页面如果在加载多个js文件的时候,浏览器会停止网页渲染,加载文件越多,网页失去响应的时间就会越长:其次,由于js文件之间存在依赖关系,因此必须严格保证加载 ...
-
js模块化开发——require.js的用法详细介绍(含jsonp)
RequireJS的目标是鼓励代码的模块化,它使用了不同于传统<script>标签脚本加载步骤.可以用它回事.优化代码,但其主要的目的还是为了代码的模块化.它鼓励在使用脚本以moudle ...
-
【前端】Require.js使用方法总结
一.为什么要使用require.js 首先一个页面如果在加载多个js文件的时候,浏览器会停止网页渲染,加载文件越多,网页失去响应的时间就会越长:其次,由于js文件之间存在依赖关系,因此必须严格保证加载 ...
-
require.js 简洁入门
原文地址:http://blog.sae.sina.com.cn/archives/4382 前言 提到require.js大多数人会说提到模块化开发,AMD等等,其实require.js并没有这么多 ...
-
【实践】require.js + r.js 代码打包压缩初体验
第二个分享的是学校项目所接触到的新知识,代码压缩 + 代码打包 这次的项目用了require.js 这个插件做模块化管理的工具,所谓模块化就是在开发的过程中将功能划分成一个独立的模块,使代码可读性更强 ...
随机推荐
-
js禁止重复提交方法
beforeSend: function () { // 禁用按钮防止重复提交 $("#fileForm a[class='btn blue_btn']").removeAttr( ...
-
Vim指令备忘
从网上找来的记忆图,适合于刚上手的童鞋形象记忆. 接下来的是个人在使用过程中容易忘记的命令,特此备份查看. n<space> 会向右移动这一行的n 个字元 n<Enter> 向 ...
-
Spring MVC设计模式
MVC开始是存在于桌面程序中的,M是指业务模型,V是指用户界面,C则是控制器 使用MVC的目的是将M和V的实现代码分离,从而使同一个程序可以使用不同的表现形式.比如一批统计数据可以分别用柱状图.饼图来 ...
-
c#简体繁体转换
方法一已经亲测,使用正常,方法二貌似不能用. 方法一 /// <summary> /// 中文字符工具类 /// </summary> public static class ...
-
CSS3阴影 box-shadow的使用总结
text-shadow是给文本添加阴影效果,box-shadow是给元素块添加周边阴影效果.随着html5和CSS3的普及,这一特殊效果使用越来越普遍. 基本语法是{box-shadow:[inset ...
-
ld: -pie can only be used when targeting iOS 4.2 or later
ld: -pie can only be used when targeting iOS 4.2 or later clang: error: linker command failed with e ...
-
javascript利用jquery-1.7.1来判断是否是谷歌Chrome浏览器
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" con ...
-
C++ 局部静态变量,全局变量,全局静态变量,局部变量的区别和联系
C++变量根据定义位置的不同,具有不同的作用域,作用域可分为6种:全局作用域,局部作用域,语句作用域,类作用域,命名作用域和文件作用域. 从作用域看: 全局变量具有全局作用域.全局变量只需在一个源文件 ...
-
SQL 数据库 学习 007 通过一个示例简单介绍什么是字段、属性、列、元组、记录、表、主键、外键 (上)
SQL 数据库 学习 007 通过一个示例简单介绍什么是字段.属性.列.元组.记录.表.主键.外键 (上) 我们来介绍一下:数据库是如何存储数据的. 数据库是如何存储数据的 来看一个小例子 scott ...
-
ajaxfileupload异步上传文件
ajaxfileupload插件可以以异步方式上传文件(其实现:iframe),不像传统那样需要刷新,下面就介绍下其使用 1.HTML部分(先引入jquery): <!DOCTYPE html& ...