fix: recognize globally registered components
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@wrnexus/cli",
|
"name": "@wrnexus/cli",
|
||||||
"version": "0.8.61",
|
"version": "0.8.62",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "src/index.ts",
|
"main": "src/index.ts",
|
||||||
"exports": {
|
"exports": {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@wrnexus/dev-server",
|
"name": "@wrnexus/dev-server",
|
||||||
"version": "0.8.53",
|
"version": "0.8.54",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "src/index.ts",
|
"main": "src/index.ts",
|
||||||
"exports": {
|
"exports": {
|
||||||
|
|||||||
@@ -367,6 +367,12 @@ export async function startServer(opts: ServeOptions): Promise<RunningServer> {
|
|||||||
externalRoutes: pluginContributions.routes,
|
externalRoutes: pluginContributions.routes,
|
||||||
middlewareFiles: pluginContributions.middleware,
|
middlewareFiles: pluginContributions.middleware,
|
||||||
});
|
});
|
||||||
|
// UI and plugin components are intentionally registered application-wide;
|
||||||
|
// using them without a source import is not an implicit-import diagnostic.
|
||||||
|
setCompileImportOptions(appRoot, {
|
||||||
|
...importConfig,
|
||||||
|
globalComponents: router.components.map((component) => component.name),
|
||||||
|
});
|
||||||
const styleEntry = opts.styleEntry ?? null;
|
const styleEntry = opts.styleEntry ?? null;
|
||||||
|
|
||||||
const devToolbarConfig = resolveDevToolbarConfig(mode, opts.devToolbar);
|
const devToolbarConfig = resolveDevToolbarConfig(mode, opts.devToolbar);
|
||||||
|
|||||||
@@ -86,6 +86,7 @@ interface CompileImportOptions {
|
|||||||
mode: ImportMode;
|
mode: ImportMode;
|
||||||
aliases: Record<string, string>;
|
aliases: Record<string, string>;
|
||||||
autoImport: boolean;
|
autoImport: boolean;
|
||||||
|
globalComponents: Set<string>;
|
||||||
}
|
}
|
||||||
const compileImportOptions = new Map<string, CompileImportOptions>();
|
const compileImportOptions = new Map<string, CompileImportOptions>();
|
||||||
const warnedImportDiagnostics = new Set<string>();
|
const warnedImportDiagnostics = new Set<string>();
|
||||||
@@ -104,12 +105,18 @@ export function setDevCompilerPipeline(pipeline: DevCompilerPipeline | null): vo
|
|||||||
|
|
||||||
export function setCompileImportOptions(
|
export function setCompileImportOptions(
|
||||||
appRoot: string,
|
appRoot: string,
|
||||||
options: { mode?: ImportMode; aliases?: Record<string, string>; autoImport?: boolean } = {},
|
options: {
|
||||||
|
mode?: ImportMode;
|
||||||
|
aliases?: Record<string, string>;
|
||||||
|
autoImport?: boolean;
|
||||||
|
globalComponents?: Iterable<string>;
|
||||||
|
} = {},
|
||||||
): void {
|
): void {
|
||||||
compileImportOptions.set(resolve(appRoot), {
|
compileImportOptions.set(resolve(appRoot), {
|
||||||
mode: options.mode ?? "compatible",
|
mode: options.mode ?? "compatible",
|
||||||
aliases: { "@": "./app", ...(options.aliases ?? {}) },
|
aliases: { "@": "./app", ...(options.aliases ?? {}) },
|
||||||
autoImport: options.autoImport ?? true,
|
autoImport: options.autoImport ?? true,
|
||||||
|
globalComponents: new Set(options.globalComponents ?? []),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -141,11 +148,18 @@ function importOptionsHash(file: string): string {
|
|||||||
mode: "compatible" as const,
|
mode: "compatible" as const,
|
||||||
aliases: { "@": "./app" },
|
aliases: { "@": "./app" },
|
||||||
autoImport: true,
|
autoImport: true,
|
||||||
|
globalComponents: new Set<string>(),
|
||||||
};
|
};
|
||||||
const aliases = Object.fromEntries(
|
const aliases = Object.fromEntries(
|
||||||
Object.entries(options.aliases).sort(([left], [right]) => left.localeCompare(right)),
|
Object.entries(options.aliases).sort(([left], [right]) => left.localeCompare(right)),
|
||||||
);
|
);
|
||||||
return hashPath(JSON.stringify({ ...options, aliases }));
|
return hashPath(
|
||||||
|
JSON.stringify({
|
||||||
|
...options,
|
||||||
|
aliases,
|
||||||
|
globalComponents: [...options.globalComponents].sort(),
|
||||||
|
}),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Island bundles already built this dev session, keyed by resolved source. */
|
/** Island bundles already built this dev session, keyed by resolved source. */
|
||||||
@@ -493,7 +507,10 @@ function validateConfiguredImports(_source: string, ast: PageAst, file: string):
|
|||||||
"Transition",
|
"Transition",
|
||||||
]);
|
]);
|
||||||
const missing = [...usedComponents].filter(
|
const missing = [...usedComponents].filter(
|
||||||
(name) => !compilerBuiltins.has(name) && !imported.has(name),
|
(name) =>
|
||||||
|
!compilerBuiltins.has(name) &&
|
||||||
|
!options.globalComponents.has(name) &&
|
||||||
|
!imported.has(name),
|
||||||
);
|
);
|
||||||
if (ast.layoutIsSymbol && ast.layout && !imported.has(ast.layout)) missing.push(ast.layout);
|
if (ast.layoutIsSymbol && ast.layout && !imported.has(ast.layout)) missing.push(ast.layout);
|
||||||
if (!missing.length) return;
|
if (!missing.length) return;
|
||||||
|
|||||||
@@ -71,6 +71,13 @@ test("compiler-native reactive elements do not require application imports", ()
|
|||||||
expect(() => compileWrnArtifacts(page, 5)).not.toThrow();
|
expect(() => compileWrnArtifacts(page, 5)).not.toThrow();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("globally registered plugin components do not require source imports", () => {
|
||||||
|
const { root, page } = fixture();
|
||||||
|
writeFileSync(page, "page Home { view { <SignIn /> } }");
|
||||||
|
setCompileImportOptions(root, { mode: "explicit", globalComponents: ["SignIn"] });
|
||||||
|
expect(() => compileWrnArtifacts(page, 6)).not.toThrow();
|
||||||
|
});
|
||||||
|
|
||||||
test("component examples in comments do not require imports", () => {
|
test("component examples in comments do not require imports", () => {
|
||||||
const { root, page } = fixture();
|
const { root, page } = fixture();
|
||||||
writeFileSync(
|
writeFileSync(
|
||||||
|
|||||||
Reference in New Issue
Block a user