This repository has been archived by the owner on Sep 22, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 3
support minimal mdx cases and add test fixture #159
Draft
deer
wants to merge
1
commit into
netzo:main
Choose a base branch
from
deer:mdx
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
{ | ||
"lock": false, | ||
"compilerOptions": { | ||
"jsx": "react-jsx", | ||
"jsxImportSource": "preact" | ||
}, | ||
"tasks": { | ||
"check:types": "deno check **/*.ts && deno check **/*.tsx", | ||
"coverage": "rm -rf coverage && deno test -A --parallel --no-check --coverage && deno coverage --html", | ||
"fixture": "deno run -A --watch=static/,routes/ tests/fixture/dev.ts", | ||
"ok": "deno fmt --check && deno lint && deno task check:types && deno task test", | ||
"test": "deno test -A --parallel --no-check" | ||
}, | ||
"importMap": "./.vscode/import_map.json" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,8 +2,9 @@ import type { Plugin, PluginRoute } from "../../deps/$fresh/server.ts"; | |
import type { NetzoState } from "../../mod.ts"; | ||
import { mdxPathsToRoutes, scanForMDXFiles } from "./utils.ts"; | ||
|
||
// deno-lint-ignore ban-types | ||
export type MdxConfig = {}; | ||
export type MdxConfig = { | ||
configLocation: string; | ||
}; | ||
|
||
// deno-lint-ignore ban-types | ||
export type MdxState = {}; | ||
|
@@ -14,14 +15,13 @@ export type MdxState = {}; | |
* @param {MdxConfig} - configuration options for the plugin | ||
* @returns {Plugin} - a Plugin for Deno Fresh | ||
*/ | ||
export const mdx = async (_config: MdxConfig): Promise< | ||
Plugin<NetzoState> | ||
> => { | ||
const mdxFiles = await scanForMDXFiles("routes"); | ||
const routes: PluginRoute[] = await mdxPathsToRoutes(mdxFiles); | ||
export async function mdx(config: MdxConfig): Promise<Plugin<NetzoState>> { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Minor nit here, maybe keep arrow syntax here for consistency with the other plugins.
|
||
const routesDir = new URL("./routes", config.configLocation).pathname; | ||
const mdxFiles = await scanForMDXFiles(routesDir); | ||
const routes: PluginRoute[] = await mdxPathsToRoutes(mdxFiles, routesDir); | ||
|
||
return { | ||
name: "mdx", | ||
routes, | ||
}; | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export default function Bar() { | ||
return <div>Bar</div>; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
{ | ||
"lock": false, | ||
"tasks": { | ||
"check": "deno fmt --check && deno lint && deno check **/*.ts && deno check **/*.tsx", | ||
"cli": "echo \"import '\\$fresh/src/dev/cli.ts'\" | deno run --unstable -A -", | ||
"manifest": "deno task cli manifest $(pwd)", | ||
"start": "deno run -A --watch=static/,routes/ dev.ts", | ||
"build": "deno run -A dev.ts build", | ||
"preview": "deno run -A main.ts", | ||
"update": "deno run -A -r https://fresh.deno.dev/update ." | ||
}, | ||
"lint": { | ||
"rules": { | ||
"tags": [ | ||
"fresh", | ||
"recommended" | ||
] | ||
} | ||
}, | ||
"exclude": [ | ||
"**/_fresh/*" | ||
], | ||
"imports": { | ||
"$fresh/": "https://deno.land/x/[email protected]/", | ||
"preact": "https://esm.sh/[email protected]", | ||
"preact/": "https://esm.sh/[email protected]/", | ||
"@preact/signals": "https://esm.sh/*@preact/[email protected]", | ||
"@preact/signals-core": "https://esm.sh/*@preact/[email protected]", | ||
"tailwindcss": "npm:[email protected]", | ||
"tailwindcss/": "npm:/[email protected]/", | ||
"tailwindcss/plugin": "npm:/[email protected]/plugin.js", | ||
"$std/": "https://deno.land/[email protected]/" | ||
}, | ||
"compilerOptions": { | ||
"jsx": "react-jsx", | ||
"jsxImportSource": "preact" | ||
}, | ||
"nodeModulesDir": true | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
#!/usr/bin/env -S deno run -A --watch=static/,routes/ | ||
|
||
import dev from "$fresh/dev.ts"; | ||
import config from "./fresh.config.ts"; | ||
|
||
import "$std/dotenv/load.ts"; | ||
|
||
await dev(import.meta.url, "./main.ts", config); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import { defineConfig } from "$fresh/server.ts"; | ||
import tailwind from "$fresh/plugins/tailwind.ts"; | ||
import { mdx } from "../../mod.ts"; | ||
|
||
export default defineConfig({ | ||
plugins: [await mdx({ configLocation: import.meta.url }), tailwind()], | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
// 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 $Counter from "./islands/Counter.tsx"; | ||
import { type Manifest } from "$fresh/server.ts"; | ||
|
||
const manifest = { | ||
routes: { | ||
"./routes/_app.tsx": $_app, | ||
}, | ||
islands: { | ||
"./islands/Counter.tsx": $Counter, | ||
}, | ||
baseUrl: import.meta.url, | ||
} satisfies Manifest; | ||
|
||
export default manifest; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import { Signal } from "@preact/signals"; | ||
import { IS_BROWSER } from "$fresh/runtime.ts"; | ||
|
||
interface CounterProps { | ||
count: Signal<number>; | ||
} | ||
|
||
export default function Counter({ count }: CounterProps) { | ||
return ( | ||
<div> | ||
<p>{count}</p> | ||
<button onClick={() => count.value -= 1} disabled={!IS_BROWSER}> | ||
-1 | ||
</button> | ||
<button onClick={() => count.value += 1} disabled={!IS_BROWSER}> | ||
+1 | ||
</button> | ||
</div> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
/// <reference no-default-lib="true" /> | ||
/// <reference lib="dom" /> | ||
/// <reference lib="dom.iterable" /> | ||
/// <reference lib="dom.asynciterable" /> | ||
/// <reference lib="deno.ns" /> | ||
|
||
import "$std/dotenv/load.ts"; | ||
|
||
import { start } from "$fresh/server.ts"; | ||
import manifest from "./fresh.gen.ts"; | ||
import config from "./fresh.config.ts"; | ||
|
||
await start(manifest, config); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import { type PageProps } from "$fresh/server.ts"; | ||
export default function App({ Component }: PageProps) { | ||
return ( | ||
<html> | ||
<head> | ||
<meta charset="utf-8" /> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||
<title>fixture</title> | ||
{/* <link rel="stylesheet" href="/styles.css" /> */} | ||
</head> | ||
<body> | ||
<Component /> | ||
</body> | ||
</html> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
--- | ||
title: foobar | ||
--- | ||
|
||
import Foo from "../components/Bar.tsx" | ||
import { useSignal } from "https://esm.sh/*@preact/[email protected]"; | ||
import Counter from "../islands/Counter.tsx"; | ||
|
||
# Hello | ||
|
||
This is rendered from mdx! | ||
|
||
* one | ||
* two | ||
* three | ||
|
||
<Foo /> | ||
<Counter count={useSignal(3)} /> |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
@tailwind base; | ||
@tailwind components; | ||
@tailwind utilities; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import { type Config } from "tailwindcss"; | ||
|
||
export default { | ||
content: [ | ||
"{routes,islands,components}/**/*.{ts,tsx}", | ||
], | ||
} satisfies Config; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,36 +1,105 @@ | ||
import { compile } from "npm:@mdx-js/mdx"; | ||
import { type MdxjsEsm } from "npm:[email protected]"; | ||
import { default as remarkFrontmatter } from "npm:[email protected]"; | ||
import { default as remarkGfm } from "npm:[email protected]"; | ||
import { type PluginRoute } from "../../deps/$fresh/server.ts"; | ||
import { walk } from "../../deps/std/fs/walk.ts"; | ||
import { visit } from "npm:[email protected]"; | ||
import { Root } from "npm:@types/[email protected]"; | ||
import { Project } from "npm:[email protected]"; | ||
import { join, toFileUrl } from "../../deps/std/path/mod.ts"; | ||
import { ImportDeclaration } from "npm:@types/[email protected]"; | ||
|
||
export async function scanForMDXFiles(_directory: string): Promise<string[]> { | ||
export async function scanForMDXFiles(directory: string): Promise<string[]> { | ||
const files: string[] = []; | ||
for await ( | ||
const entry of walk( | ||
"/home/mrk/repos/netzo/templates/minimal/routes", | ||
{ includeDirs: false, exts: [".mdx"] }, | ||
) | ||
const entry of walk(directory, { includeDirs: false, exts: [".mdx"] }) | ||
) { | ||
files.push(entry.path); | ||
} | ||
return files; | ||
} | ||
|
||
export function mdxPathsToRoutes(mdxPaths: string[]): Promise<PluginRoute[]> { | ||
export function mdxPathsToRoutes( | ||
mdxPaths: string[], | ||
routesDir: string, | ||
): Promise<PluginRoute[]> { | ||
return Promise.all(mdxPaths.map(async (path: string) => { | ||
const routePath = path.split("/routes/").pop()!.replace(".mdx", ""); | ||
|
||
const file = Deno.readTextFileSync(path); | ||
const compiled = await compile(file, { | ||
remarkPlugins: [remarkGfm, remarkFrontmatter], | ||
rehypePlugins: [rehypeLogger], | ||
remarkPlugins: [remarkGfm, remarkFrontmatter, [ | ||
remarkAbsoluteImportPaths, | ||
{ basePath: routesDir }, | ||
], remarkLogger], | ||
jsxImportSource: "preact", | ||
}); | ||
|
||
const result = compiled.toString(); | ||
// console.log({ file, result }); | ||
const code = await import("data:text/javascript," + result); | ||
const comp = code.default; | ||
|
||
return { path: routePath, component: comp } satisfies PluginRoute; | ||
})); | ||
} | ||
|
||
type RemarkAbsoluteImportPathsOptions = { | ||
basePath?: string; | ||
}; | ||
|
||
function remarkAbsoluteImportPaths( | ||
options: Readonly<RemarkAbsoluteImportPathsOptions>, | ||
): (tree: Root) => void { | ||
const basePath = options.basePath || ""; | ||
|
||
return function (tree: Root) { | ||
visit(tree, "mdxjsEsm", (node: MdxjsEsm) => { | ||
const project = new Project({ | ||
useInMemoryFileSystem: true, | ||
}); | ||
|
||
const sourceFile = project.createSourceFile("tempFile.ts", node.value); | ||
const imports = sourceFile.getImportDeclarations(); | ||
|
||
imports.forEach((importDeclaration) => { | ||
const originalSpecifier = importDeclaration.getModuleSpecifierValue(); | ||
if (originalSpecifier.startsWith("http")) return; | ||
const updatedPath = join(basePath, originalSpecifier); | ||
|
||
const newSpecifier = toFileUrl(updatedPath).href; | ||
|
||
if (node.data?.estree) { | ||
const estreeBody = node.data.estree.body as ImportDeclaration[]; | ||
const importNode = estreeBody.find((n) => | ||
n.type === "ImportDeclaration" && | ||
n.source.type === "Literal" && | ||
n.source.value === originalSpecifier | ||
); | ||
if (importNode) { | ||
importNode.source.value = newSpecifier; | ||
importNode.source.raw = `"${newSpecifier}"`; | ||
} | ||
} | ||
}); | ||
}); | ||
}; | ||
} | ||
|
||
function remarkLogger(): (tree: Root) => undefined { | ||
return function (tree: Root) { | ||
visit(tree, "root", (node: Root) => { | ||
// console.log(node); | ||
}); | ||
}; | ||
} | ||
|
||
function rehypeLogger(): (tree: Root) => undefined { | ||
return function (tree: Root) { | ||
visit(tree, "root", (node: Element) => { | ||
// console.log(node); | ||
}); | ||
}; | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should look into using the same property across plugins. The
unocss
plugin usesurl
for this same value which should also be set toimport.meta.url
).I have no preference really, but I think URL is more indicative than location (matches the
url
inimport.meta.url
). MaybeconfigURL
would be best of both worlds? And we could change this also for theunocss
plugin