From 7f25a3c4b1675b25e1aeb2aed6b93729b3b27f1d Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Mon, 17 Jul 2023 20:37:02 -0700 Subject: [PATCH] UI loading improvements Fixed: Caching for dynamically loaded JS files Fixed: Incorrect caching of initialize.js (cherry picked from commit f0cb5b81f140c67fa84162e094cc4e0f3476f5da) Closes #2690 Closes #2696 --- frontend/build/webpack.config.js | 5 ++-- frontend/src/bootstrap.tsx | 21 +++++++++++++++ frontend/src/index.ejs | 13 +++++++--- frontend/src/index.js | 26 ------------------- frontend/src/index.ts | 19 ++++++++++++++ frontend/tsconfig.json | 4 +-- package.json | 2 +- ...troller.cs => InitializeJsonController.cs} | 0 .../Frontend/Mappers/HtmlMapperBase.cs | 4 ++- .../Frontend/Mappers/StaticResourceMapper.cs | 2 +- .../Middleware/CacheableSpecification.cs | 2 +- 11 files changed, 60 insertions(+), 38 deletions(-) create mode 100644 frontend/src/bootstrap.tsx delete mode 100644 frontend/src/index.js create mode 100644 frontend/src/index.ts rename src/Readarr.Http/Frontend/{InitializeJsController.cs => InitializeJsonController.cs} (100%) diff --git a/frontend/build/webpack.config.js b/frontend/build/webpack.config.js index feae43f1b..e0ec27c27 100644 --- a/frontend/build/webpack.config.js +++ b/frontend/build/webpack.config.js @@ -36,7 +36,7 @@ module.exports = (env) => { }, entry: { - index: 'index.js' + index: 'index.ts' }, resolve: { @@ -98,7 +98,8 @@ module.exports = (env) => { new HtmlWebpackPlugin({ template: 'frontend/src/index.ejs', filename: 'index.html', - publicPath: '/' + publicPath: '/', + inject: false }), new FileManagerPlugin({ diff --git a/frontend/src/bootstrap.tsx b/frontend/src/bootstrap.tsx new file mode 100644 index 000000000..c07e581b5 --- /dev/null +++ b/frontend/src/bootstrap.tsx @@ -0,0 +1,21 @@ +import { createBrowserHistory } from 'history'; +import React from 'react'; +import { render } from 'react-dom'; +import createAppStore from 'Store/createAppStore'; +import { fetchTranslations } from 'Utilities/String/translate'; +import App from './App/App'; + +export async function bootstrap() { + const history = createBrowserHistory(); + const store = createAppStore(history); + const hasTranslationsError = !(await fetchTranslations()); + + render( + , + document.getElementById('root') + ); +} diff --git a/frontend/src/index.ejs b/frontend/src/index.ejs index e8fa753d5..a6be6c3db 100644 --- a/frontend/src/index.ejs +++ b/frontend/src/index.ejs @@ -48,7 +48,15 @@ /> - + + + + <% for (key in htmlWebpackPlugin.files.js) { %><% } %> + <% for (key in htmlWebpackPlugin.files.css) { %><% } %> Readarr @@ -77,7 +85,4 @@
- - - diff --git a/frontend/src/index.js b/frontend/src/index.js deleted file mode 100644 index acdfc6517..000000000 --- a/frontend/src/index.js +++ /dev/null @@ -1,26 +0,0 @@ -import { createBrowserHistory } from 'history'; -import React from 'react'; -import { render } from 'react-dom'; -import { fetchTranslations } from 'Utilities/String/translate'; - -import './preload'; -import './polyfills'; -import 'Styles/globals.css'; -import './index.css'; - -const history = createBrowserHistory(); -const hasTranslationsError = !await fetchTranslations(); - -const { default: createAppStore } = await import('Store/createAppStore'); -const { default: App } = await import('./App/App'); - -const store = createAppStore(history); - -render( - , - document.getElementById('root') -); diff --git a/frontend/src/index.ts b/frontend/src/index.ts new file mode 100644 index 000000000..d3445e4da --- /dev/null +++ b/frontend/src/index.ts @@ -0,0 +1,19 @@ +import './polyfills'; +import 'Styles/globals.css'; +import './index.css'; + +const initializeUrl = `${ + window.Readarr.urlBase +}/initialize.json?t=${Date.now()}`; +const response = await fetch(initializeUrl); + +window.Readarr = await response.json(); + +/* eslint-disable no-undef, @typescript-eslint/ban-ts-comment */ +// @ts-ignore 2304 +__webpack_public_path__ = `${window.Readarr.urlBase}/`; +/* eslint-enable no-undef, @typescript-eslint/ban-ts-comment */ + +const { bootstrap } = await import('./bootstrap'); + +await bootstrap(); diff --git a/frontend/tsconfig.json b/frontend/tsconfig.json index dfddb15a3..4ff9d4e87 100644 --- a/frontend/tsconfig.json +++ b/frontend/tsconfig.json @@ -1,11 +1,11 @@ { "compilerOptions": { - "target": "es6", + "target": "esnext", "allowJs": true, "checkJs": false, "baseUrl": "src", "jsx": "react", - "module": "commonjs", + "module": "esnext", "moduleResolution": "node", "noEmit": true, "esModuleInterop": true, diff --git a/package.json b/package.json index 12cff00df..7471f30d2 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ "author": "Team Readarr", "license": "GPL-3.0", "readmeFilename": "readme.md", - "main": "index.js", + "main": "index.ts", "browserslist": [ "defaults" ], diff --git a/src/Readarr.Http/Frontend/InitializeJsController.cs b/src/Readarr.Http/Frontend/InitializeJsonController.cs similarity index 100% rename from src/Readarr.Http/Frontend/InitializeJsController.cs rename to src/Readarr.Http/Frontend/InitializeJsonController.cs diff --git a/src/Readarr.Http/Frontend/Mappers/HtmlMapperBase.cs b/src/Readarr.Http/Frontend/Mappers/HtmlMapperBase.cs index 2a97ce243..03700d682 100644 --- a/src/Readarr.Http/Frontend/Mappers/HtmlMapperBase.cs +++ b/src/Readarr.Http/Frontend/Mappers/HtmlMapperBase.cs @@ -62,9 +62,11 @@ namespace Readarr.Http.Frontend.Mappers url = cacheBreakProvider.AddCacheBreakerToPath(match.Groups["path"].Value); } - return string.Format("{0}=\"{1}{2}\"", match.Groups["attribute"].Value, UrlBase, url); + return $"{match.Groups["attribute"].Value}=\"{UrlBase}{url}\""; }); + text = text.Replace("__URL_BASE__", UrlBase); + _generatedContent = text; return _generatedContent; diff --git a/src/Readarr.Http/Frontend/Mappers/StaticResourceMapper.cs b/src/Readarr.Http/Frontend/Mappers/StaticResourceMapper.cs index d71f2c993..49a6f7bad 100644 --- a/src/Readarr.Http/Frontend/Mappers/StaticResourceMapper.cs +++ b/src/Readarr.Http/Frontend/Mappers/StaticResourceMapper.cs @@ -37,7 +37,7 @@ namespace Readarr.Http.Frontend.Mappers } return resourceUrl.StartsWith("/content") || - (resourceUrl.EndsWith(".js") && !resourceUrl.EndsWith("initialize.js")) || + resourceUrl.EndsWith(".js") || resourceUrl.EndsWith(".map") || resourceUrl.EndsWith(".css") || (resourceUrl.EndsWith(".ico") && !resourceUrl.Equals("/favicon.ico")) || diff --git a/src/Readarr.Http/Middleware/CacheableSpecification.cs b/src/Readarr.Http/Middleware/CacheableSpecification.cs index cc14bd7e0..51660da3b 100644 --- a/src/Readarr.Http/Middleware/CacheableSpecification.cs +++ b/src/Readarr.Http/Middleware/CacheableSpecification.cs @@ -46,7 +46,7 @@ namespace Readarr.Http.Middleware return false; } - if (path.EndsWith("/initialize.js")) + if (path.EndsWith("/initialize.json")) { return false; }