mirror of
https://github.com/clusterio/clusterio.git
synced 2026-11-13 07:04:53 +09:00
Make staticRoot include the static/ prefix and use it for plugin bundles
staticRoot was set to the same value as webRoot, so the static/ prefix
ended up scattered across consumers: index.html relied on the manifest
path containing it, the export stores hardcoded `${staticRoot}static/`,
and bootstrap loaded plugin bundles from webRoot instead. Now staticRoot
is `${webRoot}static/` and the controller strips the static/ prefix from
bundle paths before handing them to the page and to /api/plugins.
Plugins that fetch assets with `${staticRoot}static/...` need to drop the
static/ part.
Fixes #980
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
59cd193b65
commit
2f4e0c4418
8 files changed
+31
-7
No files matched your search
@@ -31,6 +31,16 @@ Many thanks to the following for contributing to this release:
|
|||||||
[@username](https://github.com/username)
|
[@username](https://github.com/username)
|
||||||
-->
|
-->
|
||||||
|
|
||||||
|
## Version 2.0.0-alpha.28
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
|
||||||
|
- Plugin web bundles are now loaded relative to `staticRoot` instead of `webRoot`. [#980](<https://github.com/clusterio/clusterio/issues/980>)
|
||||||
|
|
||||||
|
### Breaking Changes
|
||||||
|
|
||||||
|
- `staticRoot` in the web interface now includes the `static/` prefix. Plugins that fetch assets with `${staticRoot}static/...` should drop the `static/` part. [#980](<https://github.com/clusterio/clusterio/issues/980>)
|
||||||
|
|
||||||
## Version 2.0.0-alpha.27
|
## Version 2.0.0-alpha.27
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|||||||
@@ -1217,7 +1217,7 @@ export default class Controller {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Servers the web interface with the root path set apropriately
|
* Serves the web interface with the root path set appropriately
|
||||||
*
|
*
|
||||||
* @param route - route the interface is served under.
|
* @param route - route the interface is served under.
|
||||||
* @returns Experess.js route handler.
|
* @returns Experess.js route handler.
|
||||||
@@ -1231,7 +1231,7 @@ export default class Controller {
|
|||||||
return function(req: Request, res: Response, next: NextFunction) {
|
return function(req: Request, res: Response, next: NextFunction) {
|
||||||
let depth = routeDepth + Number(req.path.slice(-1) === "/");
|
let depth = routeDepth + Number(req.path.slice(-1) === "/");
|
||||||
let webRoot = "../".repeat(depth) || "./";
|
let webRoot = "../".repeat(depth) || "./";
|
||||||
let staticRoot = webRoot;
|
let staticRoot = `${webRoot}static/`;
|
||||||
let mainBundle: string = "";
|
let mainBundle: string = "";
|
||||||
if (res.app.locals.mainBundle) {
|
if (res.app.locals.mainBundle) {
|
||||||
mainBundle = res.app.locals.mainBundle;
|
mainBundle = res.app.locals.mainBundle;
|
||||||
@@ -1239,6 +1239,7 @@ export default class Controller {
|
|||||||
let stats = res.locals.webpack.devMiddleware.stats.stats[0];
|
let stats = res.locals.webpack.devMiddleware.stats.stats[0];
|
||||||
mainBundle = stats.toJson().assetsByChunkName["main"];
|
mainBundle = stats.toJson().assetsByChunkName["main"];
|
||||||
}
|
}
|
||||||
|
mainBundle = routes.stripStaticPrefix(mainBundle);
|
||||||
|
|
||||||
fs.readFile(path.join(__dirname, "..", "..", "..", "web", "index.html"), "utf8").then((content) => {
|
fs.readFile(path.join(__dirname, "..", "..", "..", "web", "index.html"), "utf8").then((content) => {
|
||||||
res.type("text/html");
|
res.type("text/html");
|
||||||
|
|||||||
@@ -104,6 +104,14 @@ async function getMetrics(req: Request, res: Response, next: any) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the static/ prefix webpack adds to bundle paths so they can be
|
||||||
|
* resolved relative to staticRoot.
|
||||||
|
*/
|
||||||
|
export function stripStaticPrefix(bundlePath: string) {
|
||||||
|
return bundlePath.replace(/^static\//, "");
|
||||||
|
}
|
||||||
|
|
||||||
function getPlugins(req: Request, res: Response) {
|
function getPlugins(req: Request, res: Response) {
|
||||||
let plugins: lib.PluginWebApi[] = [];
|
let plugins: lib.PluginWebApi[] = [];
|
||||||
for (let pluginInfo of req.app.locals.controller.pluginInfos) {
|
for (let pluginInfo of req.app.locals.controller.pluginInfos) {
|
||||||
@@ -129,6 +137,9 @@ function getPlugins(req: Request, res: Response) {
|
|||||||
if (web.main === "remoteEntry.js") {
|
if (web.main === "remoteEntry.js") {
|
||||||
web.error = "Incompatible old remoteEntry.js entrypoint.";
|
web.error = "Incompatible old remoteEntry.js entrypoint.";
|
||||||
}
|
}
|
||||||
|
if (web.main) {
|
||||||
|
web.main = stripStaticPrefix(web.main);
|
||||||
|
}
|
||||||
plugins.push({ name, version: pluginInfo.version, enabled, loaded, web, npmPackage: pluginInfo.npmPackage });
|
plugins.push({ name, version: pluginInfo.version, enabled, loaded, web, npmPackage: pluginInfo.npmPackage });
|
||||||
}
|
}
|
||||||
res.send(plugins);
|
res.send(plugins);
|
||||||
|
|||||||
Vendored
+2
@@ -13,7 +13,9 @@ declare module "*.md" {
|
|||||||
export default value;
|
export default value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Path the web interface is served under, ends with a slash. */
|
||||||
declare const webRoot: string;
|
declare const webRoot: string;
|
||||||
|
/** Path static assets are served under, ends with a slash. */
|
||||||
declare const staticRoot: string;
|
declare const staticRoot: string;
|
||||||
|
|
||||||
declare const __webpack_init_sharing__: (shareScope: string) => Promise<void>;
|
declare const __webpack_init_sharing__: (shareScope: string) => Promise<void>;
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ async function loadPluginInfos(): Promise<[lib.PluginWebpackEnvInfo[], string]>
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
await loadScript(`${webRoot}${meta.web.main}`);
|
await loadScript(`${staticRoot}${meta.web.main}`);
|
||||||
let container: any = (window as { [key: string]: any })[`plugin_${meta.name}`];
|
let container: any = (window as { [key: string]: any })[`plugin_${meta.name}`];
|
||||||
if (!container) {
|
if (!container) {
|
||||||
throw new Error(`Plugin did not expose its container via plugin_${meta.name}`);
|
throw new Error(`Plugin did not expose its container via plugin_${meta.name}`);
|
||||||
|
|||||||
@@ -1102,7 +1102,7 @@ function useExportedAsset(modPack: lib.ModPack | undefined, asset: "settings"|"l
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let response = await fetch(`${staticRoot}static/${assetFilename}`);
|
let response = await fetch(`${staticRoot}${assetFilename}`);
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
let data = await response.json();
|
let data = await response.json();
|
||||||
setAssetData(asset === "locale" ? new Map(data) : data);
|
setAssetData(asset === "locale" ? new Map(data) : data);
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ class ExportLocaleStore {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let response = await fetch(`${staticRoot}static/${cacheEntry.localePath}`);
|
let response = await fetch(`${staticRoot}${cacheEntry.localePath}`);
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
cacheEntry.data = new Map(await response.json() as ExportLocale);
|
cacheEntry.data = new Map(await response.json() as ExportLocale);
|
||||||
for (const callback of cacheEntry.callbacks) {
|
for (const callback of cacheEntry.callbacks) {
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ class ExportPrototypeMetadataStore {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const response = await fetch(`${staticRoot}static/${cacheEntry.metadataPath}`);
|
const response = await fetch(`${staticRoot}${cacheEntry.metadataPath}`);
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
notify(
|
notify(
|
||||||
`Failed to fetch prototype metadata for mod pack ${modPackId}, server returned: ` +
|
`Failed to fetch prototype metadata for mod pack ${modPackId}, server returned: ` +
|
||||||
@@ -43,7 +43,7 @@ class ExportPrototypeMetadataStore {
|
|||||||
|
|
||||||
const metadata = await response.json() as ExportMetadata;
|
const metadata = await response.json() as ExportMetadata;
|
||||||
|
|
||||||
const spriteUrl = `${staticRoot}static/${cacheEntry.spritesheetPath}`;
|
const spriteUrl = `${staticRoot}${cacheEntry.spritesheetPath}`;
|
||||||
const styleContent: string[] = [];
|
const styleContent: string[] = [];
|
||||||
styleContent.push(`\
|
styleContent.push(`\
|
||||||
.factorio-icon\
|
.factorio-icon\
|
||||||
|
|||||||
Reference in new issue
Block a user