mirror of
https://github.com/discourse/discourse.git
synced 2026-08-06 02:51:10 +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 optional 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 regular imports, and a `with { discourseImport: "optional" }`
suffix. This is functionally equivalent to optionalRequire, but without
leaning on the legacy `loader.js` system of core
6. Add support for `with { discourseImport: "optional" }` for
plugins/themes importing core modules. This is useful when a
theme/plugin needs to target multiple versions of Discourse core.
Co-authored-by: Jarek Radosz <jarek@cvx.dev>
92 lines
2.9 KiB
JavaScript
Vendored
92 lines
2.9 KiB
JavaScript
Vendored
/* eslint-disable qunit/require-expect */
|
|
import { transformSync } from "@babel/core";
|
|
import { expect, test } from "vitest";
|
|
import BabelResolveCoreImports from "./babel-resolve-core-imports.js";
|
|
|
|
function compile(input) {
|
|
return transformSync(input, {
|
|
configFile: false,
|
|
plugins: [BabelResolveCoreImports],
|
|
}).code;
|
|
}
|
|
|
|
test("destructures core imports from moduleBroker", () => {
|
|
expect(
|
|
compile(`
|
|
import concatClass from "discourse/helpers/concat-class";
|
|
import { default as renamedDefaultImport, namedImport, otherNamedImport as renamedImport } from "discourse/module-1";
|
|
`)
|
|
).toMatchInlineSnapshot(`
|
|
"const {
|
|
default: concatClass
|
|
} = window.moduleBroker.lookup("discourse/helpers/concat-class");
|
|
const {
|
|
default: renamedDefaultImport,
|
|
namedImport: namedImport,
|
|
otherNamedImport: renamedImport
|
|
} = window.moduleBroker.lookup("discourse/module-1");"
|
|
`);
|
|
});
|
|
|
|
test("handles core namespace imports", () => {
|
|
expect(
|
|
compile(`
|
|
import * as MyModule from "discourse/module-1";
|
|
import defaultExport, * as MyModule2 from "discourse/module-2";
|
|
`)
|
|
).toMatchInlineSnapshot(`
|
|
"const MyModule = window.moduleBroker.lookup("discourse/module-1");
|
|
const {
|
|
default: defaultExport
|
|
} = window.moduleBroker.lookup("discourse/module-2");
|
|
const MyModule2 = window.moduleBroker.lookup("discourse/module-2");"
|
|
`);
|
|
});
|
|
|
|
test("marks optional core imports with a second lookup argument", () => {
|
|
expect(
|
|
compile(`
|
|
import concatClass from "discourse/helpers/concat-class" with { discourseImport: "optional" };
|
|
import * as MyModule from "discourse/module-1" with { discourseImport: "optional" };
|
|
`)
|
|
).toMatchInlineSnapshot(`
|
|
"const {
|
|
default: concatClass
|
|
} = window.moduleBroker.lookup("discourse/helpers/concat-class", true);
|
|
const MyModule = window.moduleBroker.lookup("discourse/module-1", true);"
|
|
`);
|
|
});
|
|
|
|
test('`discourseImport: "required"` keeps the default required lookup', () => {
|
|
expect(
|
|
compile(`
|
|
import concatClass from "discourse/helpers/concat-class" with { discourseImport: "required" };
|
|
`)
|
|
).toMatchInlineSnapshot(`
|
|
"const {
|
|
default: concatClass
|
|
} = window.moduleBroker.lookup("discourse/helpers/concat-class");"
|
|
`);
|
|
});
|
|
|
|
test("throws on an unknown `discourseImport` value", () => {
|
|
expect(() =>
|
|
compile(`
|
|
import concatClass from "discourse/helpers/concat-class" with { discourseImport: "maybe" };
|
|
`)
|
|
).toThrow(/Invalid `discourseImport` import attribute "maybe"/);
|
|
});
|
|
|
|
test("leaves relative, virtual, theme and plugin imports untouched", () => {
|
|
expect(
|
|
compile(`
|
|
import sibling from "./sibling";
|
|
import { settings } from "discourse/theme-12/settings";
|
|
import Thing from "discourse/plugins/other/lib/thing";
|
|
`)
|
|
).toMatchInlineSnapshot(`
|
|
"import sibling from "./sibling";
|
|
import { settings } from "discourse/theme-12/settings";
|
|
import Thing from "discourse/plugins/other/lib/thing";"
|
|
`);
|
|
});
|