html中require.config 缓存问题
在html中,require的官方基本用法如下:
<!DOCTYPE html> <html> <head> <title>My Sample Project</title> <!-- data-main attribute tells require.js to load scripts/main.js after require.js loads. --> <script data-main="scripts/main" src="scripts/require.js"></script> </head> <body> <h1>My Sample Project</h1> </body> </html>
但在实践过程中,我们可能会有很多需要配置的,比如jquery…
然后我们大约会把这些配置写到配置文件,如下:
// require.config.js
require.config({ paths: { jquery : "/js/library/jquery.min", }, shim : { } });
然后,再在 main.js 中引用
//mian.js require(["/js/require.config.js"],function(){ "use strict"; require(["jquery"], function ($) { //功能代码 }); })
因为网页缓存问题,这种方式存在当 require.config.js 有修改时,客户端的 require.config.js 并不会更新的问题。同时如果有多个html都用了require,那每个模块的 main.js 都需要在头部加上述代码。
既然在require中引用 config,会有缓存问题,那我就把 require.config.js 放到 html ,并且增加版本控制。但需要注意的是, rquire.config.js 必须放到 require.js 后面,因为他用到了require类。
如下
<!DOCTYPE html> <html> <head> <title>My Sample Project</title> <!-- data-main attribute tells require.js to load scripts/main.js after require.js loads. --> <script data-main="scripts/main" src="scripts/require.js"></script> <script src="scripts/require.config.js?v=xxx"></script> </head> <body> <h1>My Sample Project</h1> </body> </html>
这种形式会存在一个新的问题:当 require.config.js 修改后,由于 require.js 已经在浏览器缓存,所以很快(快到 require.config.js 还未加载完成)就会加载 main.js ,此时 man.js 没有享受到 require.config.js 中的配置。
这里我想到了 require.js 的模式(先加载 require.js , 再加载 main.js )与现在的需求(先加载 require.config.js ,再加载 main.js )大概相同。所以看了 require.js 中的实现,把相关部分的代码复制到 require.config.js 。
最终,我使用的代码样例如下:
需要注意的是:html 中,需要移动 data-main 的位置:
<!DOCTYPE html> <html> <head> <title>My Sample Project</title> scripts/main.js after require.js loads. --> <script src="scripts/require.js"></script> <!-- data-main 移动到这里 --> <script src="scripts/require.config.js?v=xxx" data-main="scripts/main" ></script> </head> <body> <h1>My Sample Project</h1> </body> </html>
// require.config.js ;(function () { let rev = 'xxxx'; let cfg = { // 不设置超时 = 0 waitSeconds: 60, paths: { 'jquery': '../../../../Common/Common/jquery-3.3.1/dist/jquery.min', }, shim: { 'jquery': {exports: 'jQuery'}, }, urlArgs: function (id, url) { if (url.indexOf('http') === 0) { return ''; } let args = `rev=${rev}`; // /Common/Common 下的文件不用版本控制, 都是 3 方库 if (url.indexOf('/Common/Common/') >= 0) { args = 'v=2' } return (url.indexOf('?') === -1 ? '?' : '&') + args; } }; let dataMain = ''; let scripts = document.getElementsByTagName('script'); for (let i = scripts.length - 1; i > -1; i -= 1) { let script = scripts[i]; let src = script.getAttribute('src'); if (src.indexOf('require.common.config.js') > 0) { dataMain = script.getAttribute('data-main'); if (dataMain) { //Preserve dataMain in case it is a path (i.e. contains '?') let mainScript = dataMain; //Set final baseUrl if there is not already an explicit one, //but only do so if the data-main value is not a loader plugin //module ID. if (!cfg.baseUrl && mainScript.indexOf('!') === -1) { //Pull off the directory of data-main for use as the //baseUrl. src = mainScript.split('/'); mainScript = src.pop(); let subPath = src.length ? src.join('/') + '/' : './'; cfg.baseUrl = subPath; } } break; } } require.config(cfg); if (dataMain) { require([dataMain]); } }());