mirror of
https://github.com/discourse/discourse.git
synced 2026-08-11 02:59:07 +08:00
1. Remove 'federated exports' system, which was named entrypoint exports for every module inside the plugin. Replace it with a single import of the target plugin's 'compatModules', and then update call sites to do a 'just in time' lookup of the module and export. This is implemented in a new `babel-resolve-plugin-imports` plugin 2. Update theme & plugin build systems to produce a list of external plugins which are imported. For plugins, it's stored in the manifest. For themes, it's stored in a new column of the javascript_caches table. 3. Refactor theme extra_js loading to use a more structured data model, and move the HTML generation to the erb template 4. Update core importmap to identify any missing plugin dependencies and add a fake placeholder module for them. This allows the imports to exist without causing a boot error. The imported values will resolve to 'null'. 5. Update core plugins to remove use of `optionalRequire`, and replace it with simple imports. These are now functionally equivalent, but without leaning on the legacy `loader.js` system of core Co-authored-by: Jarek Radosz <jarek@cvx.dev>
103 lines
2.7 KiB
JavaScript
Vendored
103 lines
2.7 KiB
JavaScript
Vendored
const SUPPORTED_FILE_EXTENSIONS = [".js", ".js.es6", ".hbs", ".gjs"];
|
|
|
|
const IS_CONNECTOR_REGEX = /(^|\/)connectors\//;
|
|
|
|
export default {
|
|
"virtual:entrypoint": (moduleFilenames, { themeId }) => {
|
|
const imports = [];
|
|
const entries = [];
|
|
const warnings = [];
|
|
|
|
const exportedModules = new Set();
|
|
|
|
let i = 1;
|
|
for (const moduleFilename of moduleFilenames) {
|
|
if (
|
|
!SUPPORTED_FILE_EXTENSIONS.some((ext) => moduleFilename.endsWith(ext))
|
|
) {
|
|
// Unsupported file type. Log a warning and skip
|
|
warnings.push(
|
|
`console.warn("[THEME ${themeId}] Unsupported file type: ${moduleFilename}");`
|
|
);
|
|
continue;
|
|
}
|
|
|
|
const filenameWithoutExtension = moduleFilename.replace(
|
|
/\.[^\.]+(\.es6)?$/,
|
|
""
|
|
);
|
|
|
|
let compatModuleName = filenameWithoutExtension;
|
|
|
|
if (moduleFilename.match(IS_CONNECTOR_REGEX)) {
|
|
const isTemplate = moduleFilename.endsWith(".hbs");
|
|
const isInTemplatesDirectory =
|
|
moduleFilename.match(/(^|\/)templates\//);
|
|
|
|
if (isTemplate && !isInTemplatesDirectory) {
|
|
compatModuleName = compatModuleName.replace(
|
|
IS_CONNECTOR_REGEX,
|
|
"$1templates/connectors/"
|
|
);
|
|
} else if (!isTemplate && isInTemplatesDirectory) {
|
|
compatModuleName = compatModuleName.replace(
|
|
/(^|\/)templates\//,
|
|
"$1"
|
|
);
|
|
}
|
|
}
|
|
|
|
const importPath = filenameWithoutExtension.match(IS_CONNECTOR_REGEX)
|
|
? moduleFilename
|
|
: filenameWithoutExtension;
|
|
|
|
if (exportedModules.has(importPath)) {
|
|
continue;
|
|
}
|
|
exportedModules.add(importPath);
|
|
|
|
imports.push(`import * as Mod${i} from "./${importPath}";`);
|
|
entries.push(` "${compatModuleName}": Mod${i},`);
|
|
|
|
i += 1;
|
|
}
|
|
|
|
return [
|
|
...imports,
|
|
...warnings,
|
|
"const compatModules = {",
|
|
...entries,
|
|
"};",
|
|
"export default compatModules;",
|
|
"",
|
|
].join("\n");
|
|
},
|
|
"virtual:theme": ({ themeId }) => {
|
|
return cleanMultiline(`
|
|
import { getObjectForTheme } from "discourse/lib/theme-settings-store";
|
|
|
|
export const settings = getObjectForTheme(${themeId});
|
|
|
|
export function themePrefix(key) {
|
|
return \`theme_translations.${themeId}.\${key}\`;
|
|
}
|
|
`);
|
|
},
|
|
};
|
|
|
|
function cleanMultiline(str) {
|
|
const lines = str.split("\n");
|
|
|
|
if (lines.at(0).trim() === "") {
|
|
lines.shift();
|
|
}
|
|
if (lines.at(-1).trim() === "") {
|
|
lines.pop();
|
|
}
|
|
|
|
const minLeadingWhitspace = Math.min(
|
|
...lines.filter(Boolean).map((line) => line.match(/^\s*/)[0].length)
|
|
);
|
|
|
|
return lines.map((line) => line.slice(minLeadingWhitspace)).join("\n") + "\n";
|
|
}
|