From 5da33153a9e0f157160bd5e7e101f9527e412dc3 Mon Sep 17 00:00:00 2001 From: Reed von Redwitz Date: Fri, 19 Jan 2024 15:38:28 +0100 Subject: [PATCH 01/19] fix: tailwind now scans dependencies used in plugins for class names --- plugins/tailwind/compiler.ts | 62 +++++++++++++++++++ src/server/types.ts | 4 ++ .../components/PluginComponent.tsx | 3 + tests/fixture_tailwind/fresh.config.ts | 14 +++++ tests/fixture_tailwind/tailwind.config.ts | 2 +- 5 files changed, 84 insertions(+), 1 deletion(-) create mode 100644 tests/fixture_tailwind/components/PluginComponent.tsx diff --git a/plugins/tailwind/compiler.ts b/plugins/tailwind/compiler.ts index 62af242edce..0728a7bd09c 100644 --- a/plugins/tailwind/compiler.ts +++ b/plugins/tailwind/compiler.ts @@ -5,6 +5,10 @@ import cssnano from "npm:cssnano@6.0.1"; import autoprefixer from "npm:autoprefixer@10.4.16"; import * as path from "https://deno.land/std@0.207.0/path/mod.ts"; import { TailwindPluginOptions } from "./types.ts"; +import { + createGraph, + type ModuleGraphJson, +} from "https://deno.land/x/deno_graph@0.63.3/mod.ts"; const CONFIG_EXTENSIONS = ["ts", "js", "mjs"]; @@ -62,6 +66,23 @@ export async function initTailwind( return pattern; }); + const imports = (readDenoConfig()?.imports ?? []) as Record; + for (const plugin of config.plugins ?? []) { + if (!plugin.location) continue; + // if the plugin is declared in a separate place than the project, the plugin developer should have specified a projectLocation + // otherwise, we assume the plugin is in the same directory as the project + const projectLocation = plugin.projectLocation ?? plugin.location; + const moduleGraph = await createGraph(plugin.location, { + resolve: createCustomResolver(imports), + }); + + for (const file of extractSpecifiers(moduleGraph, projectLocation)) { + const response = await fetch(file); + const content = await response.text(); + tailwindConfig.content.push({ raw: content }); + } + } + // PostCSS types cause deep recursion const plugins = [ // deno-lint-ignore no-explicit-any @@ -76,3 +97,44 @@ export async function initTailwind( return postcss(plugins); } + +const fileTypes = [".tsx"]; + +function extractSpecifiers(graph: ModuleGraphJson, projectLocation: string) { + const specifiers: Set = new Set(); + + for (const module of graph.modules) { + if ( + fileTypes.some((type) => + module.specifier.endsWith(type) && + module.specifier.startsWith(path.dirname(projectLocation)) + ) + ) { + specifiers.add(module.specifier); + } + } + return Array.from(specifiers); +} + +function readDenoConfig() { + try { + const configText = Deno.readTextFileSync("./deno.json"); + const config = JSON.parse(configText); + return config; + } catch (err) { + console.error("Error reading deno.json:", err); + return null; + } +} + +function createCustomResolver(imports: Record) { + return function customResolve(specifier: string, referrer: string): string { + for (const [key, value] of Object.entries(imports)) { + if (specifier.startsWith(key)) { + const mappedPath = specifier.replace(key, value); + return new URL(mappedPath, referrer).toString(); + } + } + return new URL(specifier, referrer).toString(); + }; +} diff --git a/src/server/types.ts b/src/server/types.ts index 492eaf87299..99e6fae8ada 100644 --- a/src/server/types.ts +++ b/src/server/types.ts @@ -495,6 +495,10 @@ export interface Plugin> { middlewares?: PluginMiddleware[]; islands?: PluginIslands; + + location?: string; + + projectLocation?: string; } export interface PluginRenderContext { diff --git a/tests/fixture_tailwind/components/PluginComponent.tsx b/tests/fixture_tailwind/components/PluginComponent.tsx new file mode 100644 index 00000000000..a6767f79933 --- /dev/null +++ b/tests/fixture_tailwind/components/PluginComponent.tsx @@ -0,0 +1,3 @@ +export default function PluginComponent() { + return
PluginComponent
; +} diff --git a/tests/fixture_tailwind/fresh.config.ts b/tests/fixture_tailwind/fresh.config.ts index 6f7acca6964..19ad2a3e5a8 100644 --- a/tests/fixture_tailwind/fresh.config.ts +++ b/tests/fixture_tailwind/fresh.config.ts @@ -1,8 +1,22 @@ import { defineConfig } from "$fresh/server.ts"; import tailwind from "$fresh/plugins/tailwind.ts"; +import PluginComponent from "$fresh/tests/fixture_tailwind/components/PluginComponent.tsx"; export default defineConfig({ plugins: [ tailwind(), + { + name: "dummy plugin", + routes: [ + { + path: "routeFromPlugin", + handler: (_req, ctx) => { + return ctx.render(); + }, + component: PluginComponent, + }, + ], + location: import.meta.url + }, ], }); diff --git a/tests/fixture_tailwind/tailwind.config.ts b/tests/fixture_tailwind/tailwind.config.ts index d6a93ea01a1..fe7013093f4 100644 --- a/tests/fixture_tailwind/tailwind.config.ts +++ b/tests/fixture_tailwind/tailwind.config.ts @@ -2,6 +2,6 @@ import { Config } from "tailwindcss"; export default { content: [ - "{routes,islands,components}/**/*.{ts,tsx}", + "{routes,islands}/**/*.{ts,tsx}", ], } satisfies Config; From 51e7f6f92ed8faa5abf7e9bdf0ee1c0a2c0a890c Mon Sep 17 00:00:00 2001 From: Reed von Redwitz Date: Fri, 19 Jan 2024 15:47:03 +0100 Subject: [PATCH 02/19] fix: formatting --- tests/fixture_tailwind/fresh.config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/fixture_tailwind/fresh.config.ts b/tests/fixture_tailwind/fresh.config.ts index 19ad2a3e5a8..6d33a16d618 100644 --- a/tests/fixture_tailwind/fresh.config.ts +++ b/tests/fixture_tailwind/fresh.config.ts @@ -16,7 +16,7 @@ export default defineConfig({ component: PluginComponent, }, ], - location: import.meta.url + location: import.meta.url, }, ], }); From 22a099a3b1012dea7bb1e1768b28c7679413ab5e Mon Sep 17 00:00:00 2001 From: Reed von Redwitz Date: Mon, 22 Jan 2024 23:13:11 +0100 Subject: [PATCH 03/19] fix: tests pass locally --- plugins/tailwind/compiler.ts | 44 ++++++++++----------------------- src/server/config.ts | 1 + src/server/types.ts | 1 + tests/main_test.ts | 2 ++ tests/server_components_test.ts | 2 ++ 5 files changed, 19 insertions(+), 31 deletions(-) diff --git a/plugins/tailwind/compiler.ts b/plugins/tailwind/compiler.ts index 0728a7bd09c..a1e7aec3ac5 100644 --- a/plugins/tailwind/compiler.ts +++ b/plugins/tailwind/compiler.ts @@ -66,7 +66,9 @@ export async function initTailwind( return pattern; }); - const imports = (readDenoConfig()?.imports ?? []) as Record; + const imports = + (await import(config.denoJsonPath, { with: { type: "json" } })) + .default.imports as Record; for (const plugin of config.plugins ?? []) { if (!plugin.location) continue; // if the plugin is declared in a separate place than the project, the plugin developer should have specified a projectLocation @@ -98,41 +100,21 @@ export async function initTailwind( return postcss(plugins); } -const fileTypes = [".tsx"]; - function extractSpecifiers(graph: ModuleGraphJson, projectLocation: string) { - const specifiers: Set = new Set(); - - for (const module of graph.modules) { - if ( - fileTypes.some((type) => - module.specifier.endsWith(type) && - module.specifier.startsWith(path.dirname(projectLocation)) - ) - ) { - specifiers.add(module.specifier); - } - } - return Array.from(specifiers); -} - -function readDenoConfig() { - try { - const configText = Deno.readTextFileSync("./deno.json"); - const config = JSON.parse(configText); - return config; - } catch (err) { - console.error("Error reading deno.json:", err); - return null; - } + return graph.modules + .filter((module) => + module.specifier.endsWith(".tsx") && + module.specifier.startsWith(path.dirname(projectLocation)) + ) + .map((module) => module.specifier); } function createCustomResolver(imports: Record) { - return function customResolve(specifier: string, referrer: string): string { - for (const [key, value] of Object.entries(imports)) { + return (specifier: string, referrer: string) => { + for (const key of Object.keys(imports)) { if (specifier.startsWith(key)) { - const mappedPath = specifier.replace(key, value); - return new URL(mappedPath, referrer).toString(); + specifier = specifier.replace(key, imports[key]); + break; } } return new URL(specifier, referrer).toString(); diff --git a/src/server/config.ts b/src/server/config.ts index c45513d66a0..91d6da24d0f 100644 --- a/src/server/config.ts +++ b/src/server/config.ts @@ -94,6 +94,7 @@ export async function getInternalFreshState( router: config.router, server: config.server ?? {}, basePath, + denoJsonPath, }; if (config.cert) { diff --git a/src/server/types.ts b/src/server/types.ts index 99e6fae8ada..eb2167b79fa 100644 --- a/src/server/types.ts +++ b/src/server/types.ts @@ -119,6 +119,7 @@ export interface ResolvedFreshConfig { router?: RouterOptions; server: Partial; basePath: string; + denoJsonPath: string; } export interface RouterOptions { diff --git a/tests/main_test.ts b/tests/main_test.ts index 252ac46b25f..9ccee900593 100644 --- a/tests/main_test.ts +++ b/tests/main_test.ts @@ -1133,6 +1133,7 @@ Deno.test("Expose config in ctx", async () => { "safari15", ], }, + denoJsonPath: `${Deno.cwd()}/tests/fixture/deno.json`, dev: false, plugins: [], render: "Function", @@ -1182,6 +1183,7 @@ Deno.test("Expose config in ctx", async () => { "safari15", ], }, + denoJsonPath: `${Deno.cwd()}/tests/fixture/deno.json`, dev: false, plugins: [], render: "Function", diff --git a/tests/server_components_test.ts b/tests/server_components_test.ts index 330a632a2d2..df73fe42784 100644 --- a/tests/server_components_test.ts +++ b/tests/server_components_test.ts @@ -93,6 +93,8 @@ Deno.test("passes context to server component", async () => { "safari15", ], }, + denoJsonPath: + `${Deno.cwd()}/tests/fixture_server_components/deno.json`, dev: false, plugins: [ { entrypoints: {}, name: "twind", renderAsync: "AsyncFunction" }, From b0ca59ed0cd7a551000f9be63089f882886afd51 Mon Sep 17 00:00:00 2001 From: Reed von Redwitz Date: Tue, 23 Jan 2024 13:21:41 +0100 Subject: [PATCH 04/19] fix: windows failures --- plugins/tailwind/compiler.ts | 9 +++++---- tests/main_test.ts | 4 ++-- tests/server_components_test.ts | 10 +++++++--- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/plugins/tailwind/compiler.ts b/plugins/tailwind/compiler.ts index a1e7aec3ac5..d6b1c5c3b01 100644 --- a/plugins/tailwind/compiler.ts +++ b/plugins/tailwind/compiler.ts @@ -8,7 +8,7 @@ import { TailwindPluginOptions } from "./types.ts"; import { createGraph, type ModuleGraphJson, -} from "https://deno.land/x/deno_graph@0.63.3/mod.ts"; +} from "https://deno.land/x/deno_graph@0.63.5/mod.ts"; const CONFIG_EXTENSIONS = ["ts", "js", "mjs"]; @@ -66,9 +66,10 @@ export async function initTailwind( return pattern; }); - const imports = - (await import(config.denoJsonPath, { with: { type: "json" } })) - .default.imports as Record; + const imports = (await import(path.toFileUrl(config.denoJsonPath).href, { + with: { type: "json" }, + })) + .default.imports as Record; for (const plugin of config.plugins ?? []) { if (!plugin.location) continue; // if the plugin is declared in a separate place than the project, the plugin developer should have specified a projectLocation diff --git a/tests/main_test.ts b/tests/main_test.ts index 9ccee900593..da2f7ae7178 100644 --- a/tests/main_test.ts +++ b/tests/main_test.ts @@ -1133,7 +1133,7 @@ Deno.test("Expose config in ctx", async () => { "safari15", ], }, - denoJsonPath: `${Deno.cwd()}/tests/fixture/deno.json`, + denoJsonPath: join(Deno.cwd(), "tests", "fixture", "deno.json"), dev: false, plugins: [], render: "Function", @@ -1183,7 +1183,7 @@ Deno.test("Expose config in ctx", async () => { "safari15", ], }, - denoJsonPath: `${Deno.cwd()}/tests/fixture/deno.json`, + denoJsonPath: join(Deno.cwd(), "tests", "fixture", "deno.json"), dev: false, plugins: [], render: "Function", diff --git a/tests/server_components_test.ts b/tests/server_components_test.ts index df73fe42784..ef34c83f046 100644 --- a/tests/server_components_test.ts +++ b/tests/server_components_test.ts @@ -1,4 +1,4 @@ -import { assertEquals } from "./deps.ts"; +import { assertEquals, join } from "./deps.ts"; import { assertSelector, assertTextMany, @@ -93,8 +93,12 @@ Deno.test("passes context to server component", async () => { "safari15", ], }, - denoJsonPath: - `${Deno.cwd()}/tests/fixture_server_components/deno.json`, + denoJsonPath: join( + Deno.cwd(), + "tests", + "fixture_server_components", + "deno.json", + ), dev: false, plugins: [ { entrypoints: {}, name: "twind", renderAsync: "AsyncFunction" }, From 8424c173f78bc380d5e01f26cefc0ee530b47677 Mon Sep 17 00:00:00 2001 From: Reed von Redwitz Date: Tue, 23 Jan 2024 17:24:10 +0100 Subject: [PATCH 05/19] chore: add better test case --- deno.json | 3 +++ tests/fixture_tailwind/fresh.config.ts | 14 ----------- tests/fixture_tailwind/tailwind.config.ts | 2 +- .../components/NestedPluginComponent.tsx | 3 +++ .../components/PluginComponent.tsx | 0 .../fixture_tailwind_remote_classes/deno.json | 13 ++++++++++ tests/fixture_tailwind_remote_classes/dev.ts | 6 +++++ .../fresh.config.ts | 24 +++++++++++++++++++ .../fresh.gen.ts | 21 ++++++++++++++++ tests/fixture_tailwind_remote_classes/main.ts | 11 +++++++++ .../plugins/nestedPlugin.ts | 19 +++++++++++++++ .../routes/_app.tsx | 17 +++++++++++++ .../routes/_middleware.ts | 15 ++++++++++++ .../routes/index.tsx | 3 +++ .../static/styles.css | 3 +++ .../tailwind.config.ts | 7 ++++++ tests/tailwind_test.ts | 13 ++++++++++ 17 files changed, 159 insertions(+), 15 deletions(-) create mode 100644 tests/fixture_tailwind_remote_classes/components/NestedPluginComponent.tsx rename tests/{fixture_tailwind => fixture_tailwind_remote_classes}/components/PluginComponent.tsx (100%) create mode 100644 tests/fixture_tailwind_remote_classes/deno.json create mode 100755 tests/fixture_tailwind_remote_classes/dev.ts create mode 100644 tests/fixture_tailwind_remote_classes/fresh.config.ts create mode 100644 tests/fixture_tailwind_remote_classes/fresh.gen.ts create mode 100644 tests/fixture_tailwind_remote_classes/main.ts create mode 100644 tests/fixture_tailwind_remote_classes/plugins/nestedPlugin.ts create mode 100644 tests/fixture_tailwind_remote_classes/routes/_app.tsx create mode 100644 tests/fixture_tailwind_remote_classes/routes/_middleware.ts create mode 100644 tests/fixture_tailwind_remote_classes/routes/index.tsx create mode 100644 tests/fixture_tailwind_remote_classes/static/styles.css create mode 100644 tests/fixture_tailwind_remote_classes/tailwind.config.ts diff --git a/deno.json b/deno.json index 6cf330a1bff..859483eb6ab 100644 --- a/deno.json +++ b/deno.json @@ -19,5 +19,8 @@ "compilerOptions": { "jsx": "react-jsx", "jsxImportSource": "preact" + }, + "lint": { + "rules": { "exclude": ["no-window"] } } } diff --git a/tests/fixture_tailwind/fresh.config.ts b/tests/fixture_tailwind/fresh.config.ts index 6d33a16d618..6f7acca6964 100644 --- a/tests/fixture_tailwind/fresh.config.ts +++ b/tests/fixture_tailwind/fresh.config.ts @@ -1,22 +1,8 @@ import { defineConfig } from "$fresh/server.ts"; import tailwind from "$fresh/plugins/tailwind.ts"; -import PluginComponent from "$fresh/tests/fixture_tailwind/components/PluginComponent.tsx"; export default defineConfig({ plugins: [ tailwind(), - { - name: "dummy plugin", - routes: [ - { - path: "routeFromPlugin", - handler: (_req, ctx) => { - return ctx.render(); - }, - component: PluginComponent, - }, - ], - location: import.meta.url, - }, ], }); diff --git a/tests/fixture_tailwind/tailwind.config.ts b/tests/fixture_tailwind/tailwind.config.ts index fe7013093f4..d6a93ea01a1 100644 --- a/tests/fixture_tailwind/tailwind.config.ts +++ b/tests/fixture_tailwind/tailwind.config.ts @@ -2,6 +2,6 @@ import { Config } from "tailwindcss"; export default { content: [ - "{routes,islands}/**/*.{ts,tsx}", + "{routes,islands,components}/**/*.{ts,tsx}", ], } satisfies Config; diff --git a/tests/fixture_tailwind_remote_classes/components/NestedPluginComponent.tsx b/tests/fixture_tailwind_remote_classes/components/NestedPluginComponent.tsx new file mode 100644 index 00000000000..6b3f10a572c --- /dev/null +++ b/tests/fixture_tailwind_remote_classes/components/NestedPluginComponent.tsx @@ -0,0 +1,3 @@ +export default function NestedPluginComponent() { + return
PluginComponent
; +} diff --git a/tests/fixture_tailwind/components/PluginComponent.tsx b/tests/fixture_tailwind_remote_classes/components/PluginComponent.tsx similarity index 100% rename from tests/fixture_tailwind/components/PluginComponent.tsx rename to tests/fixture_tailwind_remote_classes/components/PluginComponent.tsx diff --git a/tests/fixture_tailwind_remote_classes/deno.json b/tests/fixture_tailwind_remote_classes/deno.json new file mode 100644 index 00000000000..d9ccbefafc5 --- /dev/null +++ b/tests/fixture_tailwind_remote_classes/deno.json @@ -0,0 +1,13 @@ +{ + "lock": false, + "imports": { + "$fresh/": "../../", + "preact": "https://esm.sh/preact@10.15.1", + "preact/": "https://esm.sh/preact@10.15.1/", + "tailwindcss": "npm:tailwindcss@3.3.5" + }, + "compilerOptions": { + "jsx": "react-jsx", + "jsxImportSource": "preact" + } +} diff --git a/tests/fixture_tailwind_remote_classes/dev.ts b/tests/fixture_tailwind_remote_classes/dev.ts new file mode 100755 index 00000000000..1fe3e340282 --- /dev/null +++ b/tests/fixture_tailwind_remote_classes/dev.ts @@ -0,0 +1,6 @@ +#!/usr/bin/env -S deno run -A --watch=static/,routes/ + +import dev from "$fresh/dev.ts"; +import config from "./fresh.config.ts"; + +await dev(import.meta.url, "./main.ts", config); diff --git a/tests/fixture_tailwind_remote_classes/fresh.config.ts b/tests/fixture_tailwind_remote_classes/fresh.config.ts new file mode 100644 index 00000000000..a5fb73a768d --- /dev/null +++ b/tests/fixture_tailwind_remote_classes/fresh.config.ts @@ -0,0 +1,24 @@ +import { defineConfig } from "$fresh/server.ts"; +import tailwind from "$fresh/plugins/tailwind.ts"; +import PluginComponent from "./components/PluginComponent.tsx"; +import { nestedPlugin } from "./plugins/nestedPlugin.ts"; + +export default defineConfig({ + plugins: [ + tailwind(), + { + name: "dummy plugin", + routes: [ + { + path: "routeFromPlugin", + handler: (_req, ctx) => { + return ctx.render(); + }, + component: PluginComponent, + }, + ], + location: import.meta.url, + }, + nestedPlugin, + ], +}); diff --git a/tests/fixture_tailwind_remote_classes/fresh.gen.ts b/tests/fixture_tailwind_remote_classes/fresh.gen.ts new file mode 100644 index 00000000000..2e895a65907 --- /dev/null +++ b/tests/fixture_tailwind_remote_classes/fresh.gen.ts @@ -0,0 +1,21 @@ +// DO NOT EDIT. This file is generated by Fresh. +// This file SHOULD be checked into source version control. +// This file is automatically updated during development when running `dev.ts`. + +import * as $_app from "./routes/_app.tsx"; +import * as $_middleware from "./routes/_middleware.ts"; +import * as $index from "./routes/index.tsx"; + +import { type Manifest } from "$fresh/server.ts"; + +const manifest = { + routes: { + "./routes/_app.tsx": $_app, + "./routes/_middleware.ts": $_middleware, + "./routes/index.tsx": $index, + }, + islands: {}, + baseUrl: import.meta.url, +} satisfies Manifest; + +export default manifest; diff --git a/tests/fixture_tailwind_remote_classes/main.ts b/tests/fixture_tailwind_remote_classes/main.ts new file mode 100644 index 00000000000..fc9359215e3 --- /dev/null +++ b/tests/fixture_tailwind_remote_classes/main.ts @@ -0,0 +1,11 @@ +/// +/// +/// +/// +/// + +import { start } from "$fresh/server.ts"; +import manifest from "./fresh.gen.ts"; +import config from "./fresh.config.ts"; + +await start(manifest, config); diff --git a/tests/fixture_tailwind_remote_classes/plugins/nestedPlugin.ts b/tests/fixture_tailwind_remote_classes/plugins/nestedPlugin.ts new file mode 100644 index 00000000000..9863220aeee --- /dev/null +++ b/tests/fixture_tailwind_remote_classes/plugins/nestedPlugin.ts @@ -0,0 +1,19 @@ +import type { Plugin } from "../../../src/server/types.ts"; +import NestedPluginComponent from "../components/NestedPluginComponent.tsx"; + +const currentUrl = new URL(import.meta.url); +currentUrl.pathname = currentUrl.pathname.split("/").slice(0, -2).join("/") + + "/"; + +export const nestedPlugin = { + name: "nested plugin", + location: import.meta.url, + projectLocation: currentUrl.href, + routes: [{ + path: "routeFromNestedPlugin", + handler: (_req, ctx) => { + return ctx.render(); + }, + component: NestedPluginComponent, + }], +} satisfies Plugin; diff --git a/tests/fixture_tailwind_remote_classes/routes/_app.tsx b/tests/fixture_tailwind_remote_classes/routes/_app.tsx new file mode 100644 index 00000000000..2e225e497f4 --- /dev/null +++ b/tests/fixture_tailwind_remote_classes/routes/_app.tsx @@ -0,0 +1,17 @@ +import { PageProps } from "$fresh/server.ts"; + +export default function App({ Component }: PageProps) { + return ( + + + + + My Fresh app + + + + + + + ); +} diff --git a/tests/fixture_tailwind_remote_classes/routes/_middleware.ts b/tests/fixture_tailwind_remote_classes/routes/_middleware.ts new file mode 100644 index 00000000000..362a96be86b --- /dev/null +++ b/tests/fixture_tailwind_remote_classes/routes/_middleware.ts @@ -0,0 +1,15 @@ +import { FreshContext } from "$fresh/server.ts"; + +export async function handler( + _req: Request, + ctx: FreshContext, +) { + if (ctx.url.pathname === "/middleware-only.css") { + return new Response(".foo-bar { color: red }", { + headers: { + "Content-Type": "text/css", + }, + }); + } + return await ctx.next(); +} diff --git a/tests/fixture_tailwind_remote_classes/routes/index.tsx b/tests/fixture_tailwind_remote_classes/routes/index.tsx new file mode 100644 index 00000000000..ee3f8f3c9bd --- /dev/null +++ b/tests/fixture_tailwind_remote_classes/routes/index.tsx @@ -0,0 +1,3 @@ +export default function Page() { + return

foo

; +} diff --git a/tests/fixture_tailwind_remote_classes/static/styles.css b/tests/fixture_tailwind_remote_classes/static/styles.css new file mode 100644 index 00000000000..b5c61c95671 --- /dev/null +++ b/tests/fixture_tailwind_remote_classes/static/styles.css @@ -0,0 +1,3 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; diff --git a/tests/fixture_tailwind_remote_classes/tailwind.config.ts b/tests/fixture_tailwind_remote_classes/tailwind.config.ts new file mode 100644 index 00000000000..431b1c75e81 --- /dev/null +++ b/tests/fixture_tailwind_remote_classes/tailwind.config.ts @@ -0,0 +1,7 @@ +import { Config } from "tailwindcss"; + +export default { + content: [ + "{routes,islands}/**/*.{ts,tsx}", // deliberately ignore components + ], +} satisfies Config; diff --git a/tests/tailwind_test.ts b/tests/tailwind_test.ts index ad7b785102a..15cc8f3a957 100644 --- a/tests/tailwind_test.ts +++ b/tests/tailwind_test.ts @@ -122,3 +122,16 @@ Deno.test("TailwindCSS - missing snapshot on Deno Deploy", async () => { }, ); }); + +Deno.test("TailwindCSS remote classes", async () => { + await withFakeServe( + "./tests/fixture_tailwind_remote_classes/dev.ts", + async (server) => { + const res = await server.get("/styles.css"); + const content = await res.text(); + assertStringIncludes(content, ".text-purple-500"); + assertStringIncludes(content, ".text-amber-500"); + }, + { loadConfig: true }, + ); +}); From f9d7895b185b0b12b70a536f38169693474acb30 Mon Sep 17 00:00:00 2001 From: Reed von Redwitz Date: Wed, 24 Jan 2024 14:29:17 +0100 Subject: [PATCH 06/19] fix: support project root imports --- .vscode/import_map.json | 1 + plugins/tailwind/compiler.ts | 21 +++++++++++++++---- .../components/AtPluginComponent.tsx | 3 +++ .../fixture_tailwind_remote_classes/deno.json | 4 +++- .../plugins/nestedPlugin.ts | 7 +++++++ tests/tailwind_test.ts | 1 + 6 files changed, 32 insertions(+), 5 deletions(-) create mode 100644 tests/fixture_tailwind_remote_classes/components/AtPluginComponent.tsx diff --git a/.vscode/import_map.json b/.vscode/import_map.json index 60e08d9425a..d5a9dff5d03 100644 --- a/.vscode/import_map.json +++ b/.vscode/import_map.json @@ -3,6 +3,7 @@ "THIS FILE EXISTS ONLY FOR VSCODE! IT IS NOT USED AT RUNTIME": {} }, "imports": { + "@vscode_787_hack/": "../tests/fixture_tailwind_remote_classes/", "$fresh/": "../", "twind": "https://esm.sh/twind@0.16.19", "twind/": "https://esm.sh/twind@0.16.19/", diff --git a/plugins/tailwind/compiler.ts b/plugins/tailwind/compiler.ts index d6b1c5c3b01..b4c30030943 100644 --- a/plugins/tailwind/compiler.ts +++ b/plugins/tailwind/compiler.ts @@ -74,9 +74,10 @@ export async function initTailwind( if (!plugin.location) continue; // if the plugin is declared in a separate place than the project, the plugin developer should have specified a projectLocation // otherwise, we assume the plugin is in the same directory as the project - const projectLocation = plugin.projectLocation ?? plugin.location; + const projectLocation = plugin.projectLocation ?? + path.dirname(plugin.location); const moduleGraph = await createGraph(plugin.location, { - resolve: createCustomResolver(imports), + resolve: createCustomResolver(imports, projectLocation), }); for (const file of extractSpecifiers(moduleGraph, projectLocation)) { @@ -110,11 +111,23 @@ function extractSpecifiers(graph: ModuleGraphJson, projectLocation: string) { .map((module) => module.specifier); } -function createCustomResolver(imports: Record) { +function createCustomResolver( + imports: Record, + projectLocation: string, +) { + const projectPath = path.fromFileUrl(projectLocation); return (specifier: string, referrer: string) => { for (const key of Object.keys(imports)) { if (specifier.startsWith(key)) { - specifier = specifier.replace(key, imports[key]); + if (imports[key] === "./") { + const modifiedPath = path.join( + projectPath, + specifier.replace(key, ""), + ); + return path.toFileUrl(modifiedPath).href; + } else { + specifier = specifier.replace(key, imports[key]); + } break; } } diff --git a/tests/fixture_tailwind_remote_classes/components/AtPluginComponent.tsx b/tests/fixture_tailwind_remote_classes/components/AtPluginComponent.tsx new file mode 100644 index 00000000000..2bc1893c860 --- /dev/null +++ b/tests/fixture_tailwind_remote_classes/components/AtPluginComponent.tsx @@ -0,0 +1,3 @@ +export default function PluginComponent() { + return
PluginComponent
; +} diff --git a/tests/fixture_tailwind_remote_classes/deno.json b/tests/fixture_tailwind_remote_classes/deno.json index d9ccbefafc5..36098ad7206 100644 --- a/tests/fixture_tailwind_remote_classes/deno.json +++ b/tests/fixture_tailwind_remote_classes/deno.json @@ -4,7 +4,9 @@ "$fresh/": "../../", "preact": "https://esm.sh/preact@10.15.1", "preact/": "https://esm.sh/preact@10.15.1/", - "tailwindcss": "npm:tailwindcss@3.3.5" + "tailwindcss": "npm:tailwindcss@3.3.5", + "@/": "./", + "@vscode_787_hack/": "./" }, "compilerOptions": { "jsx": "react-jsx", diff --git a/tests/fixture_tailwind_remote_classes/plugins/nestedPlugin.ts b/tests/fixture_tailwind_remote_classes/plugins/nestedPlugin.ts index 9863220aeee..5cdce421f00 100644 --- a/tests/fixture_tailwind_remote_classes/plugins/nestedPlugin.ts +++ b/tests/fixture_tailwind_remote_classes/plugins/nestedPlugin.ts @@ -1,5 +1,6 @@ import type { Plugin } from "../../../src/server/types.ts"; import NestedPluginComponent from "../components/NestedPluginComponent.tsx"; +import AtPluginComponent from "@vscode_787_hack/components/AtPluginComponent.tsx"; const currentUrl = new URL(import.meta.url); currentUrl.pathname = currentUrl.pathname.split("/").slice(0, -2).join("/") + @@ -15,5 +16,11 @@ export const nestedPlugin = { return ctx.render(); }, component: NestedPluginComponent, + }, { + path: "atRouteFromNestedPlugin", + handler: (_req, ctx) => { + return ctx.render(); + }, + component: AtPluginComponent, }], } satisfies Plugin; diff --git a/tests/tailwind_test.ts b/tests/tailwind_test.ts index 15cc8f3a957..4135cc71dc0 100644 --- a/tests/tailwind_test.ts +++ b/tests/tailwind_test.ts @@ -131,6 +131,7 @@ Deno.test("TailwindCSS remote classes", async () => { const content = await res.text(); assertStringIncludes(content, ".text-purple-500"); assertStringIncludes(content, ".text-amber-500"); + assertStringIncludes(content, ".text-slate-500"); }, { loadConfig: true }, ); From 064796b4311069d52a5a2e9dea1d05b79c49c484 Mon Sep 17 00:00:00 2001 From: Reed von Redwitz Date: Wed, 24 Jan 2024 15:32:06 +0100 Subject: [PATCH 07/19] fix: remote plugins --- plugins/tailwind/compiler.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/plugins/tailwind/compiler.ts b/plugins/tailwind/compiler.ts index b4c30030943..64ed9c85aff 100644 --- a/plugins/tailwind/compiler.ts +++ b/plugins/tailwind/compiler.ts @@ -115,7 +115,10 @@ function createCustomResolver( imports: Record, projectLocation: string, ) { - const projectPath = path.fromFileUrl(projectLocation); + const isLocal = projectLocation.startsWith("file://"); + const projectPath = isLocal + ? path.fromFileUrl(projectLocation) + : projectLocation; return (specifier: string, referrer: string) => { for (const key of Object.keys(imports)) { if (specifier.startsWith(key)) { From 727d0e729e154323b99b319c04f9805f382949f0 Mon Sep 17 00:00:00 2001 From: Reed von Redwitz Date: Wed, 24 Jan 2024 16:58:52 +0100 Subject: [PATCH 08/19] test: try hacking a remote plugin into the commit history --- .../components/HackyRemoteComponent.tsx | 3 +++ .../hackyRemotePlugin.tsx | 16 ++++++++++++++++ 2 files changed, 19 insertions(+) create mode 100644 tests/fixture_tailwind_remote_classes/components/HackyRemoteComponent.tsx create mode 100644 tests/fixture_tailwind_remote_classes/hackyRemotePlugin.tsx diff --git a/tests/fixture_tailwind_remote_classes/components/HackyRemoteComponent.tsx b/tests/fixture_tailwind_remote_classes/components/HackyRemoteComponent.tsx new file mode 100644 index 00000000000..5c3f9a27474 --- /dev/null +++ b/tests/fixture_tailwind_remote_classes/components/HackyRemoteComponent.tsx @@ -0,0 +1,3 @@ +export default function PluginComponent() { + return
PluginComponent
; +} diff --git a/tests/fixture_tailwind_remote_classes/hackyRemotePlugin.tsx b/tests/fixture_tailwind_remote_classes/hackyRemotePlugin.tsx new file mode 100644 index 00000000000..a2c95968033 --- /dev/null +++ b/tests/fixture_tailwind_remote_classes/hackyRemotePlugin.tsx @@ -0,0 +1,16 @@ +import type { Plugin } from "../../src/server/types.ts"; +import HackyRemoteComponent from "./components/HackyRemoteComponent.tsx"; + +export const hackyRemotePlugin = { + name: "hackyRemotePlugin", + routes: [ + { + path: "remotePluginRoute", + handler: (_req, ctx) => { + return ctx.render(); + }, + component: HackyRemoteComponent, + }, + ], + location: import.meta.url, +} satisfies Plugin; From 6c39f5f14ea15f436961d7382862394b341e5028 Mon Sep 17 00:00:00 2001 From: Reed von Redwitz Date: Thu, 25 Jan 2024 15:51:45 +0100 Subject: [PATCH 09/19] refactor plugins to be separate files, incorporate hackyRemotePlugin from previous commit, switch to using importmap project for resolution --- plugins/tailwind/compiler.ts | 43 ++++++++++--------- .../basicPlugin.ts | 16 +++++++ .../components/HackyRemoteComponent.tsx | 3 -- .../fresh.config.ts | 20 +++------ .../hackyRemotePlugin.tsx | 16 ------- tests/tailwind_test.ts | 1 + 6 files changed, 44 insertions(+), 55 deletions(-) create mode 100644 tests/fixture_tailwind_remote_classes/basicPlugin.ts delete mode 100644 tests/fixture_tailwind_remote_classes/components/HackyRemoteComponent.tsx delete mode 100644 tests/fixture_tailwind_remote_classes/hackyRemotePlugin.tsx diff --git a/plugins/tailwind/compiler.ts b/plugins/tailwind/compiler.ts index 64ed9c85aff..5465ee7ab43 100644 --- a/plugins/tailwind/compiler.ts +++ b/plugins/tailwind/compiler.ts @@ -9,6 +9,11 @@ import { createGraph, type ModuleGraphJson, } from "https://deno.land/x/deno_graph@0.63.5/mod.ts"; +import { + type ImportMap, + resolveImportMap, + resolveModuleSpecifier, +} from "https://deno.land/x/importmap@0.2.1/mod.ts"; const CONFIG_EXTENSIONS = ["ts", "js", "mjs"]; @@ -76,8 +81,16 @@ export async function initTailwind( // otherwise, we assume the plugin is in the same directory as the project const projectLocation = plugin.projectLocation ?? path.dirname(plugin.location); + const resolvedImports = resolveImportMap( + { imports }, + path.toFileUrl(config.denoJsonPath), + ); + const moduleGraph = await createGraph(plugin.location, { - resolve: createCustomResolver(imports, projectLocation), + resolve: createCustomResolver( + resolvedImports, + new URL(plugin.location), + ), }); for (const file of extractSpecifiers(moduleGraph, projectLocation)) { @@ -112,28 +125,16 @@ function extractSpecifiers(graph: ModuleGraphJson, projectLocation: string) { } function createCustomResolver( - imports: Record, - projectLocation: string, + imports: ImportMap, + baseURL: URL, ) { - const isLocal = projectLocation.startsWith("file://"); - const projectPath = isLocal - ? path.fromFileUrl(projectLocation) - : projectLocation; return (specifier: string, referrer: string) => { - for (const key of Object.keys(imports)) { - if (specifier.startsWith(key)) { - if (imports[key] === "./") { - const modifiedPath = path.join( - projectPath, - specifier.replace(key, ""), - ); - return path.toFileUrl(modifiedPath).href; - } else { - specifier = specifier.replace(key, imports[key]); - } - break; - } + if ( + specifier.startsWith("./") || specifier.startsWith("../") || + specifier.startsWith("../../") + ) { + return path.join(path.dirname(referrer), specifier); } - return new URL(specifier, referrer).toString(); + return resolveModuleSpecifier(specifier, imports, baseURL); }; } diff --git a/tests/fixture_tailwind_remote_classes/basicPlugin.ts b/tests/fixture_tailwind_remote_classes/basicPlugin.ts new file mode 100644 index 00000000000..ae22702fc99 --- /dev/null +++ b/tests/fixture_tailwind_remote_classes/basicPlugin.ts @@ -0,0 +1,16 @@ +import type { Plugin } from "../../src/server/types.ts"; +import PluginComponent from "./components/PluginComponent.tsx"; + +export const basicPlugin = { + name: "basic plugin", + routes: [ + { + path: "routeFromPlugin", + handler: (_req, ctx) => { + return ctx.render(); + }, + component: PluginComponent, + }, + ], + location: import.meta.url, +} satisfies Plugin; diff --git a/tests/fixture_tailwind_remote_classes/components/HackyRemoteComponent.tsx b/tests/fixture_tailwind_remote_classes/components/HackyRemoteComponent.tsx deleted file mode 100644 index 5c3f9a27474..00000000000 --- a/tests/fixture_tailwind_remote_classes/components/HackyRemoteComponent.tsx +++ /dev/null @@ -1,3 +0,0 @@ -export default function PluginComponent() { - return
PluginComponent
; -} diff --git a/tests/fixture_tailwind_remote_classes/fresh.config.ts b/tests/fixture_tailwind_remote_classes/fresh.config.ts index a5fb73a768d..c850c8a5bc5 100644 --- a/tests/fixture_tailwind_remote_classes/fresh.config.ts +++ b/tests/fixture_tailwind_remote_classes/fresh.config.ts @@ -1,24 +1,14 @@ -import { defineConfig } from "$fresh/server.ts"; +import { defineConfig, Plugin } from "$fresh/server.ts"; import tailwind from "$fresh/plugins/tailwind.ts"; -import PluginComponent from "./components/PluginComponent.tsx"; +import { basicPlugin } from "./basicPlugin.ts"; import { nestedPlugin } from "./plugins/nestedPlugin.ts"; +import { hackyRemotePlugin } from "https://raw.githubusercontent.com/denoland/fresh/727d0e729e154323b99b319c04f9805f382949f0/tests/fixture_tailwind_remote_classes/hackyRemotePlugin.tsx"; export default defineConfig({ plugins: [ tailwind(), - { - name: "dummy plugin", - routes: [ - { - path: "routeFromPlugin", - handler: (_req, ctx) => { - return ctx.render(); - }, - component: PluginComponent, - }, - ], - location: import.meta.url, - }, + basicPlugin, nestedPlugin, + hackyRemotePlugin as Plugin, ], }); diff --git a/tests/fixture_tailwind_remote_classes/hackyRemotePlugin.tsx b/tests/fixture_tailwind_remote_classes/hackyRemotePlugin.tsx deleted file mode 100644 index a2c95968033..00000000000 --- a/tests/fixture_tailwind_remote_classes/hackyRemotePlugin.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import type { Plugin } from "../../src/server/types.ts"; -import HackyRemoteComponent from "./components/HackyRemoteComponent.tsx"; - -export const hackyRemotePlugin = { - name: "hackyRemotePlugin", - routes: [ - { - path: "remotePluginRoute", - handler: (_req, ctx) => { - return ctx.render(); - }, - component: HackyRemoteComponent, - }, - ], - location: import.meta.url, -} satisfies Plugin; diff --git a/tests/tailwind_test.ts b/tests/tailwind_test.ts index 4135cc71dc0..1f621265410 100644 --- a/tests/tailwind_test.ts +++ b/tests/tailwind_test.ts @@ -132,6 +132,7 @@ Deno.test("TailwindCSS remote classes", async () => { assertStringIncludes(content, ".text-purple-500"); assertStringIncludes(content, ".text-amber-500"); assertStringIncludes(content, ".text-slate-500"); + assertStringIncludes(content, ".text-lime-500"); }, { loadConfig: true }, ); From d3cf08ac2d303afb87b91eae8ceda4157c853560 Mon Sep 17 00:00:00 2001 From: Reed von Redwitz Date: Thu, 25 Jan 2024 16:49:16 +0100 Subject: [PATCH 10/19] fix nesting hack, support jsx, add tests for both, standardize testsing structure --- plugins/tailwind/compiler.ts | 8 ++--- .../components/AtPluginComponent.tsx | 4 +-- .../components/JsxPluginComponent.jsx | 3 ++ .../components/NestedPluginComponent.tsx | 2 +- .../components/VeryNestedPluginComponent.tsx | 3 ++ .../fresh.config.ts | 6 +++- .../jsxPlugin.ts | 16 ++++++++++ .../nested/nested/nested/veryNestedPlugin.ts | 19 ++++++++++++ .../nestedPlugin.ts | 0 tests/tailwind_test.ts | 30 +++++++++++++++---- 10 files changed, 77 insertions(+), 14 deletions(-) create mode 100644 tests/fixture_tailwind_remote_classes/components/JsxPluginComponent.jsx create mode 100644 tests/fixture_tailwind_remote_classes/components/VeryNestedPluginComponent.tsx create mode 100644 tests/fixture_tailwind_remote_classes/jsxPlugin.ts create mode 100644 tests/fixture_tailwind_remote_classes/nestedPlugins/nested/nested/nested/veryNestedPlugin.ts rename tests/fixture_tailwind_remote_classes/{plugins => nestedPlugins}/nestedPlugin.ts (100%) diff --git a/plugins/tailwind/compiler.ts b/plugins/tailwind/compiler.ts index 5465ee7ab43..a1090c62fb5 100644 --- a/plugins/tailwind/compiler.ts +++ b/plugins/tailwind/compiler.ts @@ -118,7 +118,8 @@ export async function initTailwind( function extractSpecifiers(graph: ModuleGraphJson, projectLocation: string) { return graph.modules .filter((module) => - module.specifier.endsWith(".tsx") && + (module.specifier.endsWith(".tsx") || + module.specifier.endsWith(".jsx")) && module.specifier.startsWith(path.dirname(projectLocation)) ) .map((module) => module.specifier); @@ -129,10 +130,7 @@ function createCustomResolver( baseURL: URL, ) { return (specifier: string, referrer: string) => { - if ( - specifier.startsWith("./") || specifier.startsWith("../") || - specifier.startsWith("../../") - ) { + if (/^(?:\.\.\/)+|^\.\//.test(specifier)) { return path.join(path.dirname(referrer), specifier); } return resolveModuleSpecifier(specifier, imports, baseURL); diff --git a/tests/fixture_tailwind_remote_classes/components/AtPluginComponent.tsx b/tests/fixture_tailwind_remote_classes/components/AtPluginComponent.tsx index 2bc1893c860..e954b6774b2 100644 --- a/tests/fixture_tailwind_remote_classes/components/AtPluginComponent.tsx +++ b/tests/fixture_tailwind_remote_classes/components/AtPluginComponent.tsx @@ -1,3 +1,3 @@ -export default function PluginComponent() { - return
PluginComponent
; +export default function AtPluginComponent() { + return
AtPluginComponent
; } diff --git a/tests/fixture_tailwind_remote_classes/components/JsxPluginComponent.jsx b/tests/fixture_tailwind_remote_classes/components/JsxPluginComponent.jsx new file mode 100644 index 00000000000..0152746f146 --- /dev/null +++ b/tests/fixture_tailwind_remote_classes/components/JsxPluginComponent.jsx @@ -0,0 +1,3 @@ +export default function JsxPluginComponent() { + return
JsxPluginComponent
; +} diff --git a/tests/fixture_tailwind_remote_classes/components/NestedPluginComponent.tsx b/tests/fixture_tailwind_remote_classes/components/NestedPluginComponent.tsx index 6b3f10a572c..2d22b070432 100644 --- a/tests/fixture_tailwind_remote_classes/components/NestedPluginComponent.tsx +++ b/tests/fixture_tailwind_remote_classes/components/NestedPluginComponent.tsx @@ -1,3 +1,3 @@ export default function NestedPluginComponent() { - return
PluginComponent
; + return
NestedPluginComponent
; } diff --git a/tests/fixture_tailwind_remote_classes/components/VeryNestedPluginComponent.tsx b/tests/fixture_tailwind_remote_classes/components/VeryNestedPluginComponent.tsx new file mode 100644 index 00000000000..f3407e830ba --- /dev/null +++ b/tests/fixture_tailwind_remote_classes/components/VeryNestedPluginComponent.tsx @@ -0,0 +1,3 @@ +export default function VeryNestedPluginComponent() { + return
VeryNestedPluginComponent
; +} diff --git a/tests/fixture_tailwind_remote_classes/fresh.config.ts b/tests/fixture_tailwind_remote_classes/fresh.config.ts index c850c8a5bc5..53f9f1da0ff 100644 --- a/tests/fixture_tailwind_remote_classes/fresh.config.ts +++ b/tests/fixture_tailwind_remote_classes/fresh.config.ts @@ -1,8 +1,10 @@ import { defineConfig, Plugin } from "$fresh/server.ts"; import tailwind from "$fresh/plugins/tailwind.ts"; import { basicPlugin } from "./basicPlugin.ts"; -import { nestedPlugin } from "./plugins/nestedPlugin.ts"; +import { nestedPlugin } from "./nestedPlugins/nestedPlugin.ts"; import { hackyRemotePlugin } from "https://raw.githubusercontent.com/denoland/fresh/727d0e729e154323b99b319c04f9805f382949f0/tests/fixture_tailwind_remote_classes/hackyRemotePlugin.tsx"; +import { veryNestedPlugin } from "./nestedPlugins/nested/nested/nested/veryNestedPlugin.ts"; +import { jsxPlugin } from "./jsxPlugin.ts"; export default defineConfig({ plugins: [ @@ -10,5 +12,7 @@ export default defineConfig({ basicPlugin, nestedPlugin, hackyRemotePlugin as Plugin, + veryNestedPlugin, + jsxPlugin, ], }); diff --git a/tests/fixture_tailwind_remote_classes/jsxPlugin.ts b/tests/fixture_tailwind_remote_classes/jsxPlugin.ts new file mode 100644 index 00000000000..10123903d1a --- /dev/null +++ b/tests/fixture_tailwind_remote_classes/jsxPlugin.ts @@ -0,0 +1,16 @@ +import type { Plugin } from "../../src/server/types.ts"; +import JsxPluginComponent from "./components/JsxPluginComponent.jsx"; + +export const jsxPlugin = { + name: "jsx plugin", + routes: [ + { + path: "routeFromJsxPlugin", + handler: (_req, ctx) => { + return ctx.render(); + }, + component: JsxPluginComponent, + }, + ], + location: import.meta.url, +} satisfies Plugin; diff --git a/tests/fixture_tailwind_remote_classes/nestedPlugins/nested/nested/nested/veryNestedPlugin.ts b/tests/fixture_tailwind_remote_classes/nestedPlugins/nested/nested/nested/veryNestedPlugin.ts new file mode 100644 index 00000000000..5e218c605eb --- /dev/null +++ b/tests/fixture_tailwind_remote_classes/nestedPlugins/nested/nested/nested/veryNestedPlugin.ts @@ -0,0 +1,19 @@ +import type { Plugin } from "../../../../../../src/server/types.ts"; +import VeryNestedPluginComponent from "../../../../components/VeryNestedPluginComponent.tsx"; + +const currentUrl = new URL(import.meta.url); +currentUrl.pathname = currentUrl.pathname.split("/").slice(0, -5).join("/") + + "/"; + +export const veryNestedPlugin = { + name: "very nested plugin", + location: import.meta.url, + projectLocation: currentUrl.href, + routes: [{ + path: "routeFromVeryNestedPlugin", + handler: (_req, ctx) => { + return ctx.render(); + }, + component: VeryNestedPluginComponent, + }], +} satisfies Plugin; diff --git a/tests/fixture_tailwind_remote_classes/plugins/nestedPlugin.ts b/tests/fixture_tailwind_remote_classes/nestedPlugins/nestedPlugin.ts similarity index 100% rename from tests/fixture_tailwind_remote_classes/plugins/nestedPlugin.ts rename to tests/fixture_tailwind_remote_classes/nestedPlugins/nestedPlugin.ts diff --git a/tests/tailwind_test.ts b/tests/tailwind_test.ts index 1f621265410..d8691b8d42b 100644 --- a/tests/tailwind_test.ts +++ b/tests/tailwind_test.ts @@ -123,16 +123,36 @@ Deno.test("TailwindCSS - missing snapshot on Deno Deploy", async () => { ); }); -Deno.test("TailwindCSS remote classes", async () => { +Deno.test("TailwindCSS remote classes - dev mode", async () => { await withFakeServe( "./tests/fixture_tailwind_remote_classes/dev.ts", async (server) => { const res = await server.get("/styles.css"); const content = await res.text(); - assertStringIncludes(content, ".text-purple-500"); - assertStringIncludes(content, ".text-amber-500"); - assertStringIncludes(content, ".text-slate-500"); - assertStringIncludes(content, ".text-lime-500"); + assertStringIncludes(content, ".text-purple-500"); //PluginComponent + assertStringIncludes(content, ".text-amber-500"); //NestedPluginComponent + assertStringIncludes(content, ".text-slate-500"); //AtPluginComponent + assertStringIncludes(content, ".text-lime-500"); //HackyPluginComponent + assertStringIncludes(content, ".text-cyan-500"); //VeryNestedPluginComponent + assertStringIncludes(content, ".text-emerald-500"); //JsxComponent + }, + { loadConfig: true }, + ); +}); + +Deno.test("TailwindCSS remote classes - build mode", async () => { + await runBuild("./tests/fixture_tailwind_remote_classes/dev.ts"); + await withFakeServe( + "./tests/fixture_tailwind_remote_classes/main.ts", + async (server) => { + const res = await server.get("/styles.css"); + const content = await res.text(); + assertStringIncludes(content, ".text-purple-500"); //PluginComponent + assertStringIncludes(content, ".text-amber-500"); //NestedPluginComponent + assertStringIncludes(content, ".text-slate-500"); //AtPluginComponent + assertStringIncludes(content, ".text-lime-500"); //HackyPluginComponent + assertStringIncludes(content, ".text-cyan-500"); //VeryNestedPluginComponent + assertStringIncludes(content, ".text-emerald-500"); //JsxComponent }, { loadConfig: true }, ); From 98014250efc997083b4558339782c8f5d176e101 Mon Sep 17 00:00:00 2001 From: Reed von Redwitz Date: Fri, 26 Jan 2024 13:43:15 +0100 Subject: [PATCH 11/19] further simplifications --- plugins/tailwind/compiler.ts | 31 ++++++++++--------------------- 1 file changed, 10 insertions(+), 21 deletions(-) diff --git a/plugins/tailwind/compiler.ts b/plugins/tailwind/compiler.ts index a1090c62fb5..a044771608b 100644 --- a/plugins/tailwind/compiler.ts +++ b/plugins/tailwind/compiler.ts @@ -10,10 +10,9 @@ import { type ModuleGraphJson, } from "https://deno.land/x/deno_graph@0.63.5/mod.ts"; import { - type ImportMap, - resolveImportMap, - resolveModuleSpecifier, -} from "https://deno.land/x/importmap@0.2.1/mod.ts"; + ImportMap, + parseFromJson, +} from "https://deno.land/x/import_map@v0.15.0/mod.ts"; const CONFIG_EXTENSIONS = ["ts", "js", "mjs"]; @@ -73,24 +72,20 @@ export async function initTailwind( const imports = (await import(path.toFileUrl(config.denoJsonPath).href, { with: { type: "json" }, - })) - .default.imports as Record; + })).default; for (const plugin of config.plugins ?? []) { if (!plugin.location) continue; // if the plugin is declared in a separate place than the project, the plugin developer should have specified a projectLocation // otherwise, we assume the plugin is in the same directory as the project const projectLocation = plugin.projectLocation ?? path.dirname(plugin.location); - const resolvedImports = resolveImportMap( - { imports }, + const resolvedImports = await parseFromJson( path.toFileUrl(config.denoJsonPath), + imports, ); const moduleGraph = await createGraph(plugin.location, { - resolve: createCustomResolver( - resolvedImports, - new URL(plugin.location), - ), + resolve: createCustomResolver(resolvedImports), }); for (const file of extractSpecifiers(moduleGraph, projectLocation)) { @@ -120,19 +115,13 @@ function extractSpecifiers(graph: ModuleGraphJson, projectLocation: string) { .filter((module) => (module.specifier.endsWith(".tsx") || module.specifier.endsWith(".jsx")) && - module.specifier.startsWith(path.dirname(projectLocation)) + module.specifier.startsWith(projectLocation) ) .map((module) => module.specifier); } -function createCustomResolver( - imports: ImportMap, - baseURL: URL, -) { +function createCustomResolver(imports: ImportMap) { return (specifier: string, referrer: string) => { - if (/^(?:\.\.\/)+|^\.\//.test(specifier)) { - return path.join(path.dirname(referrer), specifier); - } - return resolveModuleSpecifier(specifier, imports, baseURL); + return imports.resolve(specifier, referrer); }; } From ddbfb2e2d5e31540b15348a7b2ad605803b5c090 Mon Sep 17 00:00:00 2001 From: Reed von Redwitz Date: Sun, 28 Jan 2024 08:38:22 +0100 Subject: [PATCH 12/19] remove handler from plugins --- plugins/tailwind/compiler.ts | 2 +- tests/fixture_tailwind_remote_classes/basicPlugin.ts | 3 --- tests/fixture_tailwind_remote_classes/deno.json | 1 - tests/fixture_tailwind_remote_classes/jsxPlugin.ts | 3 --- .../nestedPlugins/nested/nested/nested/veryNestedPlugin.ts | 3 --- .../nestedPlugins/nestedPlugin.ts | 6 ------ 6 files changed, 1 insertion(+), 17 deletions(-) diff --git a/plugins/tailwind/compiler.ts b/plugins/tailwind/compiler.ts index a044771608b..c015d208f17 100644 --- a/plugins/tailwind/compiler.ts +++ b/plugins/tailwind/compiler.ts @@ -74,7 +74,7 @@ export async function initTailwind( with: { type: "json" }, })).default; for (const plugin of config.plugins ?? []) { - if (!plugin.location) continue; + if (plugin.location === undefined) continue; // if the plugin is declared in a separate place than the project, the plugin developer should have specified a projectLocation // otherwise, we assume the plugin is in the same directory as the project const projectLocation = plugin.projectLocation ?? diff --git a/tests/fixture_tailwind_remote_classes/basicPlugin.ts b/tests/fixture_tailwind_remote_classes/basicPlugin.ts index ae22702fc99..416b264f64f 100644 --- a/tests/fixture_tailwind_remote_classes/basicPlugin.ts +++ b/tests/fixture_tailwind_remote_classes/basicPlugin.ts @@ -6,9 +6,6 @@ export const basicPlugin = { routes: [ { path: "routeFromPlugin", - handler: (_req, ctx) => { - return ctx.render(); - }, component: PluginComponent, }, ], diff --git a/tests/fixture_tailwind_remote_classes/deno.json b/tests/fixture_tailwind_remote_classes/deno.json index 36098ad7206..230a217c39b 100644 --- a/tests/fixture_tailwind_remote_classes/deno.json +++ b/tests/fixture_tailwind_remote_classes/deno.json @@ -5,7 +5,6 @@ "preact": "https://esm.sh/preact@10.15.1", "preact/": "https://esm.sh/preact@10.15.1/", "tailwindcss": "npm:tailwindcss@3.3.5", - "@/": "./", "@vscode_787_hack/": "./" }, "compilerOptions": { diff --git a/tests/fixture_tailwind_remote_classes/jsxPlugin.ts b/tests/fixture_tailwind_remote_classes/jsxPlugin.ts index 10123903d1a..95fd2a02643 100644 --- a/tests/fixture_tailwind_remote_classes/jsxPlugin.ts +++ b/tests/fixture_tailwind_remote_classes/jsxPlugin.ts @@ -6,9 +6,6 @@ export const jsxPlugin = { routes: [ { path: "routeFromJsxPlugin", - handler: (_req, ctx) => { - return ctx.render(); - }, component: JsxPluginComponent, }, ], diff --git a/tests/fixture_tailwind_remote_classes/nestedPlugins/nested/nested/nested/veryNestedPlugin.ts b/tests/fixture_tailwind_remote_classes/nestedPlugins/nested/nested/nested/veryNestedPlugin.ts index 5e218c605eb..1bfc67dd4f1 100644 --- a/tests/fixture_tailwind_remote_classes/nestedPlugins/nested/nested/nested/veryNestedPlugin.ts +++ b/tests/fixture_tailwind_remote_classes/nestedPlugins/nested/nested/nested/veryNestedPlugin.ts @@ -11,9 +11,6 @@ export const veryNestedPlugin = { projectLocation: currentUrl.href, routes: [{ path: "routeFromVeryNestedPlugin", - handler: (_req, ctx) => { - return ctx.render(); - }, component: VeryNestedPluginComponent, }], } satisfies Plugin; diff --git a/tests/fixture_tailwind_remote_classes/nestedPlugins/nestedPlugin.ts b/tests/fixture_tailwind_remote_classes/nestedPlugins/nestedPlugin.ts index 5cdce421f00..f41ca2f4bb8 100644 --- a/tests/fixture_tailwind_remote_classes/nestedPlugins/nestedPlugin.ts +++ b/tests/fixture_tailwind_remote_classes/nestedPlugins/nestedPlugin.ts @@ -12,15 +12,9 @@ export const nestedPlugin = { projectLocation: currentUrl.href, routes: [{ path: "routeFromNestedPlugin", - handler: (_req, ctx) => { - return ctx.render(); - }, component: NestedPluginComponent, }, { path: "atRouteFromNestedPlugin", - handler: (_req, ctx) => { - return ctx.render(); - }, component: AtPluginComponent, }], } satisfies Plugin; From 50bb190afbb09b83946b7c9da4d2dfd981ebe0cc Mon Sep 17 00:00:00 2001 From: Reed von Redwitz Date: Mon, 29 Jan 2024 04:29:48 +0100 Subject: [PATCH 13/19] remove createCustomResolver --- plugins/tailwind/compiler.ts | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/plugins/tailwind/compiler.ts b/plugins/tailwind/compiler.ts index c015d208f17..00859ef8b5d 100644 --- a/plugins/tailwind/compiler.ts +++ b/plugins/tailwind/compiler.ts @@ -9,10 +9,7 @@ import { createGraph, type ModuleGraphJson, } from "https://deno.land/x/deno_graph@0.63.5/mod.ts"; -import { - ImportMap, - parseFromJson, -} from "https://deno.land/x/import_map@v0.15.0/mod.ts"; +import { parseFromJson } from "https://deno.land/x/import_map@v0.15.0/mod.ts"; const CONFIG_EXTENSIONS = ["ts", "js", "mjs"]; @@ -85,7 +82,7 @@ export async function initTailwind( ); const moduleGraph = await createGraph(plugin.location, { - resolve: createCustomResolver(resolvedImports), + resolve: resolvedImports.resolve.bind(resolvedImports), }); for (const file of extractSpecifiers(moduleGraph, projectLocation)) { @@ -119,9 +116,3 @@ function extractSpecifiers(graph: ModuleGraphJson, projectLocation: string) { ) .map((module) => module.specifier); } - -function createCustomResolver(imports: ImportMap) { - return (specifier: string, referrer: string) => { - return imports.resolve(specifier, referrer); - }; -} From 8466dcaa34e7361c147a39606901bd98c7bbd77d Mon Sep 17 00:00:00 2001 From: Reed von Redwitz Date: Mon, 29 Jan 2024 18:19:29 +0100 Subject: [PATCH 14/19] uptake latest import_map --- plugins/tailwind/compiler.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/tailwind/compiler.ts b/plugins/tailwind/compiler.ts index a7b623c9a17..223b926ff20 100644 --- a/plugins/tailwind/compiler.ts +++ b/plugins/tailwind/compiler.ts @@ -9,7 +9,7 @@ import { createGraph, type ModuleGraphJson, } from "https://deno.land/x/deno_graph@0.63.5/mod.ts"; -import { parseFromJson } from "https://deno.land/x/import_map@v0.15.0/mod.ts"; +import { parseFromJson } from "https://deno.land/x/import_map@v0.18.3/mod.ts"; const CONFIG_EXTENSIONS = ["ts", "js", "mjs"]; From 844370cadd1ed28fd76f796c2afc1e2411bfc425 Mon Sep 17 00:00:00 2001 From: Reed von Redwitz Date: Tue, 30 Jan 2024 15:23:22 +0100 Subject: [PATCH 15/19] support deno.jsonc files --- plugins/tailwind/compiler.ts | 15 ++++++++++++--- tests/tailwind_test.ts | 26 ++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/plugins/tailwind/compiler.ts b/plugins/tailwind/compiler.ts index 223b926ff20..9633a1ff01c 100644 --- a/plugins/tailwind/compiler.ts +++ b/plugins/tailwind/compiler.ts @@ -10,6 +10,7 @@ import { type ModuleGraphJson, } from "https://deno.land/x/deno_graph@0.63.5/mod.ts"; import { parseFromJson } from "https://deno.land/x/import_map@v0.18.3/mod.ts"; +import { parse as jsoncParse } from "https://deno.land/std@0.213.0/jsonc/mod.ts"; const CONFIG_EXTENSIONS = ["ts", "js", "mjs"]; @@ -67,9 +68,17 @@ export async function initTailwind( return pattern; }); - const imports = (await import(path.toFileUrl(config.denoJsonPath).href, { - with: { type: "json" }, - })).default; + let imports; + if (path.extname(config.denoJsonPath) === ".json") { + imports = (await import(path.toFileUrl(config.denoJsonPath).href, { + with: { type: "json" }, + })).default; + } else if (path.extname(config.denoJsonPath) === ".jsonc") { + const fileContents = Deno.readTextFileSync(config.denoJsonPath); + imports = jsoncParse(fileContents); + } else { + throw Error("deno config must be either .json or .jsonc"); + } for (const plugin of config.plugins ?? []) { if (plugin.location === undefined) continue; // if the plugin is declared in a separate place than the project, the plugin developer should have specified a projectLocation diff --git a/tests/tailwind_test.ts b/tests/tailwind_test.ts index d8691b8d42b..33b1012260e 100644 --- a/tests/tailwind_test.ts +++ b/tests/tailwind_test.ts @@ -140,6 +140,32 @@ Deno.test("TailwindCSS remote classes - dev mode", async () => { ); }); +Deno.test("TailwindCSS remote classes - dev mode jsonc", async () => { + const originalPath = "./tests/fixture_tailwind_remote_classes/deno.json"; + const newPath = "./tests/fixture_tailwind_remote_classes/deno.jsonc"; + + await Deno.rename(originalPath, newPath); + + try { + await withFakeServe( + "./tests/fixture_tailwind_remote_classes/dev.ts", + async (server) => { + const res = await server.get("/styles.css"); + const content = await res.text(); + assertStringIncludes(content, ".text-purple-500"); // PluginComponent + assertStringIncludes(content, ".text-amber-500"); // NestedPluginComponent + assertStringIncludes(content, ".text-slate-500"); // AtPluginComponent + assertStringIncludes(content, ".text-lime-500"); // HackyPluginComponent + assertStringIncludes(content, ".text-cyan-500"); // VeryNestedPluginComponent + assertStringIncludes(content, ".text-emerald-500"); // JsxComponent + }, + { loadConfig: true }, + ); + } finally { + await Deno.rename(newPath, originalPath); + } +}); + Deno.test("TailwindCSS remote classes - build mode", async () => { await runBuild("./tests/fixture_tailwind_remote_classes/dev.ts"); await withFakeServe( From 3b1fc08689c123b08849c21b8ebba0745bec601f Mon Sep 17 00:00:00 2001 From: Reed von Redwitz Date: Wed, 31 Jan 2024 09:16:39 +0100 Subject: [PATCH 16/19] rename imports to importMap --- plugins/tailwind/compiler.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/plugins/tailwind/compiler.ts b/plugins/tailwind/compiler.ts index 9633a1ff01c..aa0f81e1d89 100644 --- a/plugins/tailwind/compiler.ts +++ b/plugins/tailwind/compiler.ts @@ -68,14 +68,14 @@ export async function initTailwind( return pattern; }); - let imports; + let importMap; if (path.extname(config.denoJsonPath) === ".json") { - imports = (await import(path.toFileUrl(config.denoJsonPath).href, { + importMap = (await import(path.toFileUrl(config.denoJsonPath).href, { with: { type: "json" }, })).default; } else if (path.extname(config.denoJsonPath) === ".jsonc") { const fileContents = Deno.readTextFileSync(config.denoJsonPath); - imports = jsoncParse(fileContents); + importMap = jsoncParse(fileContents); } else { throw Error("deno config must be either .json or .jsonc"); } @@ -85,13 +85,13 @@ export async function initTailwind( // otherwise, we assume the plugin is in the same directory as the project const projectLocation = plugin.projectLocation ?? path.dirname(plugin.location); - const resolvedImports = await parseFromJson( + const resolvedImportMap = await parseFromJson( path.toFileUrl(config.denoJsonPath), - imports, + importMap, ); const moduleGraph = await createGraph(plugin.location, { - resolve: resolvedImports.resolve.bind(resolvedImports), + resolve: resolvedImportMap.resolve.bind(resolvedImportMap), }); for (const file of extractSpecifiers(moduleGraph, projectLocation)) { From 235ee88ba1cf26062775a6bcb0904991abe8e608 Mon Sep 17 00:00:00 2001 From: Reed von Redwitz Date: Thu, 1 Feb 2024 15:54:16 +0100 Subject: [PATCH 17/19] refactor how to determine project location and add documentation --- plugins/tailwind.ts | 17 +++++++++++++++++ src/server/types.ts | 9 +++++++++ .../nested/nested/nested/veryNestedPlugin.ts | 7 ++----- .../nestedPlugins/nestedPlugin.ts | 7 ++----- 4 files changed, 30 insertions(+), 10 deletions(-) diff --git a/plugins/tailwind.ts b/plugins/tailwind.ts index 8383d7debed..cfcfe379a4a 100644 --- a/plugins/tailwind.ts +++ b/plugins/tailwind.ts @@ -127,3 +127,20 @@ export default function tailwind( }, }; } + +export function upNLevels(url: string | URL, levels: number) { + const inputUrl = (typeof url === "string") ? new URL(url) : url; + + const segments = inputUrl.pathname.split(path.SEP); + + if (levels >= segments.length) { + throw new Error("Cannot go up more levels than the current depth"); + } + + const upperPathSegments = segments.slice(0, -levels); + const newPath = path.join(...upperPathSegments); + + inputUrl.pathname = newPath; + + return inputUrl.href; +} diff --git a/src/server/types.ts b/src/server/types.ts index eb2167b79fa..227ae8c993f 100644 --- a/src/server/types.ts +++ b/src/server/types.ts @@ -497,8 +497,17 @@ export interface Plugin> { islands?: PluginIslands; + /** + * This should always be set to `import.meta.url`. + * Required if you want tailwind to scan your routes for classes. + */ location?: string; + /** + * If the plugin is declared in a separate place than the project root, specify the root here. + * This is necessary if your plugin is declared in a `src/` folder. + * Required if you want tailwind to scan your routes for classes, and your plugin is not in the root. + */ projectLocation?: string; } diff --git a/tests/fixture_tailwind_remote_classes/nestedPlugins/nested/nested/nested/veryNestedPlugin.ts b/tests/fixture_tailwind_remote_classes/nestedPlugins/nested/nested/nested/veryNestedPlugin.ts index 1bfc67dd4f1..e840464707f 100644 --- a/tests/fixture_tailwind_remote_classes/nestedPlugins/nested/nested/nested/veryNestedPlugin.ts +++ b/tests/fixture_tailwind_remote_classes/nestedPlugins/nested/nested/nested/veryNestedPlugin.ts @@ -1,14 +1,11 @@ +import { upNLevels } from "$fresh/plugins/tailwind.ts"; import type { Plugin } from "../../../../../../src/server/types.ts"; import VeryNestedPluginComponent from "../../../../components/VeryNestedPluginComponent.tsx"; -const currentUrl = new URL(import.meta.url); -currentUrl.pathname = currentUrl.pathname.split("/").slice(0, -5).join("/") + - "/"; - export const veryNestedPlugin = { name: "very nested plugin", location: import.meta.url, - projectLocation: currentUrl.href, + projectLocation: upNLevels(import.meta.url, 5), routes: [{ path: "routeFromVeryNestedPlugin", component: VeryNestedPluginComponent, diff --git a/tests/fixture_tailwind_remote_classes/nestedPlugins/nestedPlugin.ts b/tests/fixture_tailwind_remote_classes/nestedPlugins/nestedPlugin.ts index f41ca2f4bb8..2a7279e9128 100644 --- a/tests/fixture_tailwind_remote_classes/nestedPlugins/nestedPlugin.ts +++ b/tests/fixture_tailwind_remote_classes/nestedPlugins/nestedPlugin.ts @@ -1,15 +1,12 @@ +import { upNLevels } from "$fresh/plugins/tailwind.ts"; import type { Plugin } from "../../../src/server/types.ts"; import NestedPluginComponent from "../components/NestedPluginComponent.tsx"; import AtPluginComponent from "@vscode_787_hack/components/AtPluginComponent.tsx"; -const currentUrl = new URL(import.meta.url); -currentUrl.pathname = currentUrl.pathname.split("/").slice(0, -2).join("/") + - "/"; - export const nestedPlugin = { name: "nested plugin", location: import.meta.url, - projectLocation: currentUrl.href, + projectLocation: upNLevels(import.meta.url, 2), routes: [{ path: "routeFromNestedPlugin", component: NestedPluginComponent, From c953b1595618afe10a1f6ad0bdbb46c8fb2c78fd Mon Sep 17 00:00:00 2001 From: Reed von Redwitz Date: Thu, 1 Feb 2024 16:23:40 +0100 Subject: [PATCH 18/19] fix windows --- plugins/tailwind.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/tailwind.ts b/plugins/tailwind.ts index cfcfe379a4a..1f63e873dd8 100644 --- a/plugins/tailwind.ts +++ b/plugins/tailwind.ts @@ -131,7 +131,7 @@ export default function tailwind( export function upNLevels(url: string | URL, levels: number) { const inputUrl = (typeof url === "string") ? new URL(url) : url; - const segments = inputUrl.pathname.split(path.SEP); + const segments = inputUrl.pathname.split("/"); if (levels >= segments.length) { throw new Error("Cannot go up more levels than the current depth"); From 60220dd33b5b0f6b5c72927c933dbc32a3c4734e Mon Sep 17 00:00:00 2001 From: Reed von Redwitz Date: Sun, 25 Feb 2024 07:04:14 +0100 Subject: [PATCH 19/19] remove upNLevels --- plugins/tailwind.ts | 17 ----------------- tests/fixture_tailwind_remote_classes/deno.json | 4 ++++ .../nested/nested/nested/veryNestedPlugin.ts | 4 ++-- .../nestedPlugins/nestedPlugin.ts | 4 ++-- 4 files changed, 8 insertions(+), 21 deletions(-) diff --git a/plugins/tailwind.ts b/plugins/tailwind.ts index a4201defd6b..8668bbace77 100644 --- a/plugins/tailwind.ts +++ b/plugins/tailwind.ts @@ -127,20 +127,3 @@ export default function tailwind( }, }; } - -export function upNLevels(url: string | URL, levels: number) { - const inputUrl = (typeof url === "string") ? new URL(url) : url; - - const segments = inputUrl.pathname.split("/"); - - if (levels >= segments.length) { - throw new Error("Cannot go up more levels than the current depth"); - } - - const upperPathSegments = segments.slice(0, -levels); - const newPath = path.join(...upperPathSegments); - - inputUrl.pathname = newPath; - - return inputUrl.href; -} diff --git a/tests/fixture_tailwind_remote_classes/deno.json b/tests/fixture_tailwind_remote_classes/deno.json index 230a217c39b..893c73e74f7 100644 --- a/tests/fixture_tailwind_remote_classes/deno.json +++ b/tests/fixture_tailwind_remote_classes/deno.json @@ -1,10 +1,14 @@ { "lock": false, + "tasks": { + "start": "deno run -A --watch=static/,routes/ dev.ts" + }, "imports": { "$fresh/": "../../", "preact": "https://esm.sh/preact@10.15.1", "preact/": "https://esm.sh/preact@10.15.1/", "tailwindcss": "npm:tailwindcss@3.3.5", + "$std/": "https://deno.land/std@0.216.0/", "@vscode_787_hack/": "./" }, "compilerOptions": { diff --git a/tests/fixture_tailwind_remote_classes/nestedPlugins/nested/nested/nested/veryNestedPlugin.ts b/tests/fixture_tailwind_remote_classes/nestedPlugins/nested/nested/nested/veryNestedPlugin.ts index e840464707f..fdf10606bb7 100644 --- a/tests/fixture_tailwind_remote_classes/nestedPlugins/nested/nested/nested/veryNestedPlugin.ts +++ b/tests/fixture_tailwind_remote_classes/nestedPlugins/nested/nested/nested/veryNestedPlugin.ts @@ -1,11 +1,11 @@ -import { upNLevels } from "$fresh/plugins/tailwind.ts"; +import { normalize } from "$std/url/normalize.ts"; import type { Plugin } from "../../../../../../src/server/types.ts"; import VeryNestedPluginComponent from "../../../../components/VeryNestedPluginComponent.tsx"; export const veryNestedPlugin = { name: "very nested plugin", location: import.meta.url, - projectLocation: upNLevels(import.meta.url, 5), + projectLocation: normalize(import.meta.url + "../../../../../../").href, routes: [{ path: "routeFromVeryNestedPlugin", component: VeryNestedPluginComponent, diff --git a/tests/fixture_tailwind_remote_classes/nestedPlugins/nestedPlugin.ts b/tests/fixture_tailwind_remote_classes/nestedPlugins/nestedPlugin.ts index 2a7279e9128..1c87312cbd6 100644 --- a/tests/fixture_tailwind_remote_classes/nestedPlugins/nestedPlugin.ts +++ b/tests/fixture_tailwind_remote_classes/nestedPlugins/nestedPlugin.ts @@ -1,4 +1,4 @@ -import { upNLevels } from "$fresh/plugins/tailwind.ts"; +import { normalize } from "$std/url/normalize.ts"; import type { Plugin } from "../../../src/server/types.ts"; import NestedPluginComponent from "../components/NestedPluginComponent.tsx"; import AtPluginComponent from "@vscode_787_hack/components/AtPluginComponent.tsx"; @@ -6,7 +6,7 @@ import AtPluginComponent from "@vscode_787_hack/components/AtPluginComponent.tsx export const nestedPlugin = { name: "nested plugin", location: import.meta.url, - projectLocation: upNLevels(import.meta.url, 2), + projectLocation: normalize(import.meta.url + "../../../").href, routes: [{ path: "routeFromNestedPlugin", component: NestedPluginComponent,