Merge pull request #4512 from node-red/4503-fix-cache-busting

Restore caching busting functionality without using explict version number
This commit is contained in:
Nick O'Leary 2024-01-15 15:54:40 +00:00 committed by GitHub
commit 282bb6c414
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 32 additions and 14 deletions

View File

@ -51,7 +51,7 @@ module.exports = {
var ui = require("./ui"); var ui = require("./ui");
ui.init(runtimeAPI); ui.init(settings, runtimeAPI);
const editorApp = apiUtil.createExpressApp(settings) const editorApp = apiUtil.createExpressApp(settings)

View File

@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
**/ **/
const crypto = require('crypto')
var express = require('express'); var express = require('express');
var fs = require("fs"); var fs = require("fs");
var path = require("path"); var path = require("path");
@ -24,13 +25,16 @@ var apiUtils = require("../util");
var theme = require("./theme"); var theme = require("./theme");
var runtimeAPI; var runtimeAPI;
let settings;
var editorClientDir = path.dirname(require.resolve("@node-red/editor-client")); var editorClientDir = path.dirname(require.resolve("@node-red/editor-client"));
var defaultNodeIcon = path.join(editorClientDir,"public","red","images","icons","arrow-in.svg"); var defaultNodeIcon = path.join(editorClientDir,"public","red","images","icons","arrow-in.svg");
var editorTemplatePath = path.join(editorClientDir,"templates","index.mst"); var editorTemplatePath = path.join(editorClientDir,"templates","index.mst");
var editorTemplate; var editorTemplate;
let cacheBuster
module.exports = { module.exports = {
init: function(_runtimeAPI) { init: function(_settings, _runtimeAPI) {
settings = _settings;
runtimeAPI = _runtimeAPI; runtimeAPI = _runtimeAPI;
editorTemplate = fs.readFileSync(editorTemplatePath,"utf8"); editorTemplate = fs.readFileSync(editorTemplatePath,"utf8");
Mustache.parse(editorTemplate); Mustache.parse(editorTemplate);
@ -91,6 +95,12 @@ module.exports = {
}, },
editor: async function(req,res) { editor: async function(req,res) {
if (!cacheBuster) {
// settings.instanceId is set asynchronously to the editor-api
// being initiaised. So we defer calculating the cacheBuster hash
// until the first load of the editor
cacheBuster = crypto.createHash('md5').update(`${settings.version || 'version'}-${settings.instanceId || 'instanceId'}`).digest("hex").substring(0,12)
}
let sessionMessages; let sessionMessages;
if (req.session && req.session.messages) { if (req.session && req.session.messages) {
@ -99,6 +109,7 @@ module.exports = {
} }
res.send(Mustache.render(editorTemplate,{ res.send(Mustache.render(editorTemplate,{
sessionMessages, sessionMessages,
cacheBuster,
...await theme.context() ...await theme.context()
})); }));
}, },

View File

@ -24,24 +24,24 @@
<title>{{ page.title }}</title> <title>{{ page.title }}</title>
<link rel="icon" type="image/png" href="{{ page.favicon }}"> <link rel="icon" type="image/png" href="{{ page.favicon }}">
<link rel="mask-icon" href="{{ page.tabicon.icon }}" color="{{ page.tabicon.colour }}"> <link rel="mask-icon" href="{{ page.tabicon.icon }}" color="{{ page.tabicon.colour }}">
<link rel="stylesheet" href="vendor/jquery/css/base/jquery-ui.min.css?v={{ page.version }}"> <link rel="stylesheet" href="vendor/jquery/css/base/jquery-ui.min.css?v={{ cacheBuster }}">
<link rel="stylesheet" href="vendor/font-awesome/css/font-awesome.min.css?v={{ page.version }}"> <link rel="stylesheet" href="vendor/font-awesome/css/font-awesome.min.css?v={{ cacheBuster }}">
<link rel="stylesheet" href="red/style.min.css?v={{ page.version }}"> <link rel="stylesheet" href="red/style.min.css?v={{ cacheBuster }}">
{{#page.css}} {{#page.css}}
<link rel="stylesheet" href="{{.}}"> <link rel="stylesheet" href="{{.}}">
{{/page.css}} {{/page.css}}
{{#asset.vendorMonaco}} {{#asset.vendorMonaco}}
<link rel="stylesheet" href="vendor/monaco/style.css?v={{ page.version }}"> <link rel="stylesheet" href="vendor/monaco/style.css?v={{ cacheBuster }}">
{{/asset.vendorMonaco}} {{/asset.vendorMonaco}}
</head> </head>
<body spellcheck="false"> <body spellcheck="false">
<div id="red-ui-editor"></div> <div id="red-ui-editor"></div>
<script src="vendor/vendor.js?v={{ page.version }}"></script> <script src="vendor/vendor.js?v={{ cacheBuster }}"></script>
{{#asset.vendorMonaco}} {{#asset.vendorMonaco}}
<script src="{{ asset.vendorMonaco }}?v={{ page.version }}"></script> <script src="{{ asset.vendorMonaco }}?v={{ cacheBuster }}"></script>
{{/asset.vendorMonaco}} {{/asset.vendorMonaco}}
<script src="{{ asset.red }}?v={{ page.version }}"></script> <script src="{{ asset.red }}?v={{ cacheBuster }}"></script>
<script src="{{ asset.main }}?v={{ page.version }}"></script> <script src="{{ asset.main }}?v={{ cacheBuster }}"></script>
{{# page.scripts }} {{# page.scripts }}
<script src="{{.}}"></script> <script src="{{.}}"></script>
{{/ page.scripts }} {{/ page.scripts }}

View File

@ -27,6 +27,7 @@ var express = require("express");
var path = require('path'); var path = require('path');
var fs = require("fs"); var fs = require("fs");
var os = require("os"); var os = require("os");
const crypto = require("crypto")
const {log,i18n,events,exec,util,hooks} = require("@node-red/util"); const {log,i18n,events,exec,util,hooks} = require("@node-red/util");
@ -51,7 +52,7 @@ var adminApi = {
var nodeApp; var nodeApp;
var adminApp; var adminApp;
var server; var server;
let userSettings;
/** /**
* Initialise the runtime module. * Initialise the runtime module.
@ -61,8 +62,9 @@ var server;
* better abstracted. * better abstracted.
* @memberof @node-red/runtime * @memberof @node-red/runtime
*/ */
function init(userSettings,httpServer,_adminApi) { function init(_userSettings,httpServer,_adminApi) {
server = httpServer; server = httpServer;
userSettings = _userSettings
if (server && server.on) { if (server && server.on) {
// Add a listener to the upgrade event so that we can properly timeout connection // Add a listener to the upgrade event so that we can properly timeout connection
@ -134,7 +136,12 @@ function start() {
.then(function() { return settings.load(storage)}) .then(function() { return settings.load(storage)})
.then(function() { return library.init(runtime)}) .then(function() { return library.init(runtime)})
.then(function() { .then(function() {
if (settings.available()) {
if (settings.get('instanceId') === undefined) {
settings.set('instanceId', crypto.randomBytes(8).toString('hex'))
}
userSettings.instanceId = settings.get('instanceId') || ''
}
if (log.metric()) { if (log.metric()) {
runtimeMetricInterval = setInterval(function() { runtimeMetricInterval = setInterval(function() {
reportMetrics(); reportMetrics();

View File

@ -29,7 +29,7 @@ describe("api/editor/ui", function() {
var app; var app;
before(function() { before(function() {
ui.init({ ui.init({}, {
nodes: { nodes: {
getIcon: function(opts) { getIcon: function(opts) {
return new Promise(function(resolve,reject) { return new Promise(function(resolve,reject) {