如何利用Require.Js管理多页面站点文件(译)

简介: 英文版地址 最近使用 Require.Js 的时候我发现它确实是一个改善代码管理的一个好方法。我以前发表Backbone类的文章时曾提到过 Require,但此前,我从未在传统的多页面网站内使用到 Require。

英文版地址

最近使用 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 里:

 1 //The build will inline common dependencies into this file.
 2 
 3 requirejs.config({
 4   baseUrl: './js',
 5   paths: {
 6     'jquery': 'vendor/jquery',
 7     'bootstrap': 'vendor/bootstrap'
 8   },
 9   shim: {
10     'bootstrap': ['jquery']
11   }
12 });

除了 common.js,我还在 app/models 下创建了BasicModel文件以表明common.js是公用的,并把BasicModel放进common.js里。

 

编译

编译之前需要有一个 option.js 来指定哪些文件需要编译,哪些不需要:

 1 module.exports = {
 2   appDir: 'www',
 3   baseUrl: 'js/',
 4   mainConfigFile: 'www/js/common.js',
 5   dir: 'www-release',
 6   modules: [
 7     {
 8       name: 'common',
 9       include: [
10         'app/models/basicModel',
11         'jquery',
12         'bootstrap'
13       ]
14     },
15     {
16       name: 'app/main-about',
17       exclude: ['common']
18     },
19     {
20       name: 'app/main-contact',
21       exclude: ['common']
22     }
23   ]
24 };

 上面的代码中,首先把所有的文件用 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 ,只需要按下面的顺序加载文件即可:

 1 <script src="./js/vendor/require.js"></script>
 2 <script type="text/javascript">
 3 // Load common code that includes config,
 4 // then load the app logic for this page.
 5 require(['./js/common'], function (common) {
 6   // ./js/common.js sets the baseUrl to be ./js/
 7   // You can ask for 'app/main-about' here instead
 8   // of './js/app/main-about'
 9   require(['app/main-about']);
10 });
11 </script>

通过层层引入 RequireJs --> common.js --> main-about.js 实现了明晰简便的代码管理方式。

谢谢。

 

前端技术文章翻译QQ群:338353879

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

目录
相关文章
|
24天前
|
JavaScript API
深入探索fs.WriteStream:Node.js文件写入流的全面解析
深入探索fs.WriteStream:Node.js文件写入流的全面解析
|
1月前
|
开发框架 JavaScript 前端开发
揭秘:如何让你的asp.net页面变身交互魔术师——先施展JavaScript咒语,再引发服务器端魔法!
【8月更文挑战第16天】在ASP.NET开发中,处理客户端与服务器交互时,常需先执行客户端验证再提交数据。传统上使用ASP.NET Button控件直接触发服务器事件,但难以插入客户端逻辑。本文对比此法与改进方案:利用HTML按钮及JavaScript手动控制表单提交。后者通过`onclick`事件调用JavaScript函数`SubmitForm()`来检查输入并决定是否提交,增强了灵活性和用户体验,同时确保了服务器端逻辑的执行。
35 5
|
10天前
|
JavaScript 前端开发
js怎么定位不同的页面元素
在JavaScript中,有多种方法定位和选择页面元素。
|
8天前
|
存储 JSON JavaScript
学习node.js十三,文件的上传于下载
学习node.js十三,文件的上传于下载
|
26天前
|
JavaScript 前端开发
【Azure Developer】在App Service上放置一个JS页面并引用msal.min.js成功获取AAD用户名示例
【Azure Developer】在App Service上放置一个JS页面并引用msal.min.js成功获取AAD用户名示例
|
28天前
|
JavaScript 前端开发
使用js生成表格标题、表格内容并且每行附带删除按钮然后插入到页面中
使用js生成表格标题、表格内容并且每行附带删除按钮然后插入到页面中
29 2
|
28天前
|
JavaScript
分别用jquery和js修改页面元素
分别用jquery和js修改页面元素
27 2
|
1月前
|
JavaScript 数据安全/隐私保护
如何在Vue组件中调用封装好的外部js文件方法
这篇文章介绍了如何在Vue组件中调用封装好的外部js文件方法,包括在Vue项目中全局引入外部js文件,并在组件中通过this.$myMethod()的方式调用外部js文件中定义的方法。
如何在Vue组件中调用封装好的外部js文件方法
|
1月前
|
JavaScript 前端开发 API
js全屏,监听页面是否全屏
js全屏,监听页面是否全屏
36 4
|
27天前
|
前端开发 JavaScript Linux
【Azure 应用服务】在Azure App Service for Linux环境中,部署的Django应用,出现加载css、js等静态资源文件失败
【Azure 应用服务】在Azure App Service for Linux环境中,部署的Django应用,出现加载css、js等静态资源文件失败