NW.js 没有正确清除缓存
NW.js not clearing cache correctly
环境
- NW.js v0.12.3(32 位)
- Windows 8
- Webchimera.js(播放器)VLC Build (2.2.1)
- require-new
问题
新 window 从 parent window 打开。 Webchimera 模块已加载但崩溃,因为其 window object 指向 parent window.那是因为NW.jscaches its modules。
PARENT
<div id="chimera_container"></div>
...
var gui; // global variable for parent object
var wjs; // global variable for parent object
....
gui = require('nw.gui');
wjs = wjs = require('wcjs-player');
....
video_emit = gui.Window.open('video_emit.html',{
"window" : {
"focus": true,
"toolbar": true,
"frame": true,
"width" : 640,
"height" : 640
},
"dependencies": {
"require-new": "^1.1.0",
"wcjs-player": "^0.5.6"
},
});
video_emit window
<div id="vid"></div>
....
var wjs; // global variable for new window object
wjs = require('wcjs-player');
video_container = new wjs("#vid"); <---- CRASHES **** !!!
在node_modules\wcjs-player\index.js第82行我添加了
console.log(window.document);
PARENT 控制台输出
#document
...
<div id="chimera_container"></div>
video_emit 控制台输出
#document
...
<div id="chimera_container"></div>
尝试过的解决方案
手动清除缓存
在要求 'wcjs-player' 模块之前调用函数 clearRequiredModules video_emit window.
var clearRequiredModules = function(){
// clear wcjs-player from require cache to force new load
var clearModules = [
"wcjs-player",
"jquery" // https://github.com/jaruba/wcjs-player/issues/38
];
for (var i in clearModules) {
for (var module in global.require.cache) {
if ( global.require.cache.hasOwnProperty(module)
&& module.indexOf(clearModules[i]) > -1
)
delete global.require.cache[module];
}
}
};
不工作。同样的问题,就好像我根本没有清除一样。仍然指向 parent window object.
使用require-new模块
这段代码没有科学依据,我加载模块并在 video_emit window.
中使用它
var req_new = require('require-new');
wjs = req_new('wcjs-player');
仍然崩溃。
我知道将 ** new-instance: true** 添加到 parent 的 gui.Window.open
会解决这个问题,但我需要 parent 和新的 window 通过 global 变量进行通信,只有当它们在同一个渲染器上时才可用。
------------------------ 解决方案 ---------- ------------------------------
单独清除缓存不起作用,为了使其有效,必须从 parent window 中完成以下操作.
video_emit = gui.Window.open('video_emit.html',{
...
});
video_emit .on('document-start', function() {
video_emit .reload(3);
});
并且在 child window:
clearRequiredModules(); //Same code as protrayed above
wjs = require('wcjs-player');
video_container = new wjs("#vid");
问题
注意,这样做会使 global 变量(用于在 windows 之间共享信息的变量)无用。所以这与在 parent window(并且不清除 child window 中的缓存):
video_emit = gui.Window.open('video_emit.html',{
"window" : {
"focus": true,
"toolbar": true,
"frame": true,
"width" : 640,
"height" : 640
},
"new-instance" : true // <---- That right there
});
此问题的一个可能解决方案是使用 localStorage 来代替 windows 之间的通信。
wcjs-player
严重依赖于能够访问 window.document
。 NW.js
v0.12.3 有一个错误,将父对象的 window
对象泄露给子对象 window。
我已经看到这会产生许多问题,包括将所有错误和日志推送到主 window,并且它总是会破坏所有依赖于 window
.
的模块
解决此问题的方法是在创建子项 window 后重新加载 node.js 级别。
用法示例:
var new_win = require('nw.gui').Window.open('index.html');
new_win.on('document-start', function() {
new_win.reload(3);
});
备注:
还应该提到的是,这是一个 NW.js
特定问题,Electron
新的 windows 没有这个问题。
因为这是一个高级页面重新加载,global
对象也将被清除,将信息传递给这个新的 window 的替代解决方案是使用 localStorage
(即持久性),或用于更复杂的需求 websockets。
尝试 "touching" 服务器上的所有 js 文件。 "Clearing cache" 没有想象中的那么简单。我没有清除浏览器上的缓存,而是意识到 "touching" 缓存的服务器文件实际上会更改服务器上缓存的源文件的日期和时间(在 Edge、Chrome 和 Firefox 上测试)和大多数浏览器将自动下载您服务器上最新的最新副本(代码、图形和任何多媒体)。我建议您在程序运行之前只复制服务器上的最新脚本和 "do the touch thing" 解决方案,这样它会将所有问题文件的日期更改为最新的日期和时间,然后下载一个新副本到您的浏览器:
<?php
touch('/www/sample/file1.js');
touch('/www/sample/file2.js');
touch('/www/sample/file2.js');
?>
然后...您程序的其余部分...
我花了一些时间来解决这个问题(因为许多浏览器对不同命令的行为不同,但它们都会检查文件时间并与您在浏览器中下载的副本进行比较,如果日期和时间不同,将执行刷新),如果你不能按照假定的正确方式行事,总有另一种可用且更好的解决方案。最好的问候和快乐的露营。顺便说一句 touch();或替代方案适用于 javascript bash sh php 中的许多编程语言,您可以在 html.
中包含或调用它们
环境
- NW.js v0.12.3(32 位)
- Windows 8
- Webchimera.js(播放器)VLC Build (2.2.1)
- require-new
问题
新 window 从 parent window 打开。 Webchimera 模块已加载但崩溃,因为其 window object 指向 parent window.那是因为NW.jscaches its modules。
PARENT
<div id="chimera_container"></div>
...
var gui; // global variable for parent object
var wjs; // global variable for parent object
....
gui = require('nw.gui');
wjs = wjs = require('wcjs-player');
....
video_emit = gui.Window.open('video_emit.html',{
"window" : {
"focus": true,
"toolbar": true,
"frame": true,
"width" : 640,
"height" : 640
},
"dependencies": {
"require-new": "^1.1.0",
"wcjs-player": "^0.5.6"
},
});
video_emit window
<div id="vid"></div>
....
var wjs; // global variable for new window object
wjs = require('wcjs-player');
video_container = new wjs("#vid"); <---- CRASHES **** !!!
在node_modules\wcjs-player\index.js第82行我添加了
console.log(window.document);
PARENT 控制台输出
#document
...
<div id="chimera_container"></div>
video_emit 控制台输出
#document
...
<div id="chimera_container"></div>
尝试过的解决方案
手动清除缓存
在要求 'wcjs-player' 模块之前调用函数 clearRequiredModules video_emit window.
var clearRequiredModules = function(){
// clear wcjs-player from require cache to force new load
var clearModules = [
"wcjs-player",
"jquery" // https://github.com/jaruba/wcjs-player/issues/38
];
for (var i in clearModules) {
for (var module in global.require.cache) {
if ( global.require.cache.hasOwnProperty(module)
&& module.indexOf(clearModules[i]) > -1
)
delete global.require.cache[module];
}
}
};
不工作。同样的问题,就好像我根本没有清除一样。仍然指向 parent window object.
使用require-new模块
这段代码没有科学依据,我加载模块并在 video_emit window.
中使用它var req_new = require('require-new');
wjs = req_new('wcjs-player');
仍然崩溃。
我知道将 ** new-instance: true** 添加到 parent 的 gui.Window.open
会解决这个问题,但我需要 parent 和新的 window 通过 global 变量进行通信,只有当它们在同一个渲染器上时才可用。
------------------------ 解决方案 ---------- ------------------------------
单独清除缓存不起作用,为了使其有效,必须从 parent window 中完成以下操作.
video_emit = gui.Window.open('video_emit.html',{
...
});
video_emit .on('document-start', function() {
video_emit .reload(3);
});
并且在 child window:
clearRequiredModules(); //Same code as protrayed above
wjs = require('wcjs-player');
video_container = new wjs("#vid");
问题
注意,这样做会使 global 变量(用于在 windows 之间共享信息的变量)无用。所以这与在 parent window(并且不清除 child window 中的缓存):
video_emit = gui.Window.open('video_emit.html',{
"window" : {
"focus": true,
"toolbar": true,
"frame": true,
"width" : 640,
"height" : 640
},
"new-instance" : true // <---- That right there
});
此问题的一个可能解决方案是使用 localStorage 来代替 windows 之间的通信。
wcjs-player
严重依赖于能够访问 window.document
。 NW.js
v0.12.3 有一个错误,将父对象的 window
对象泄露给子对象 window。
我已经看到这会产生许多问题,包括将所有错误和日志推送到主 window,并且它总是会破坏所有依赖于 window
.
解决此问题的方法是在创建子项 window 后重新加载 node.js 级别。
用法示例:
var new_win = require('nw.gui').Window.open('index.html');
new_win.on('document-start', function() {
new_win.reload(3);
});
备注:
还应该提到的是,这是一个
NW.js
特定问题,Electron
新的 windows 没有这个问题。因为这是一个高级页面重新加载,
global
对象也将被清除,将信息传递给这个新的 window 的替代解决方案是使用localStorage
(即持久性),或用于更复杂的需求 websockets。
尝试 "touching" 服务器上的所有 js 文件。 "Clearing cache" 没有想象中的那么简单。我没有清除浏览器上的缓存,而是意识到 "touching" 缓存的服务器文件实际上会更改服务器上缓存的源文件的日期和时间(在 Edge、Chrome 和 Firefox 上测试)和大多数浏览器将自动下载您服务器上最新的最新副本(代码、图形和任何多媒体)。我建议您在程序运行之前只复制服务器上的最新脚本和 "do the touch thing" 解决方案,这样它会将所有问题文件的日期更改为最新的日期和时间,然后下载一个新副本到您的浏览器:
<?php
touch('/www/sample/file1.js');
touch('/www/sample/file2.js');
touch('/www/sample/file2.js');
?>
然后...您程序的其余部分...
我花了一些时间来解决这个问题(因为许多浏览器对不同命令的行为不同,但它们都会检查文件时间并与您在浏览器中下载的副本进行比较,如果日期和时间不同,将执行刷新),如果你不能按照假定的正确方式行事,总有另一种可用且更好的解决方案。最好的问候和快乐的露营。顺便说一句 touch();或替代方案适用于 javascript bash sh php 中的许多编程语言,您可以在 html.
中包含或调用它们