Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
Masaki Nakano authored and Masaki Nakano committed Jul 3, 2024
1 parent 9b1526b commit 164daa8
Show file tree
Hide file tree
Showing 17 changed files with 538 additions and 24 deletions.
Binary file modified bun.lockb
Binary file not shown.
6 changes: 6 additions & 0 deletions packages/qwik-web/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,9 @@ The production build will generate client and server modules by running both cli
```shell
bun build # or `bun build`
```

## Static Site Generator (Node.js)

```shell
bun build.server
```
19 changes: 19 additions & 0 deletions packages/qwik-web/adapters/static/vite.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { staticAdapter } from "@builder.io/qwik-city/adapters/static/vite";
import { extendConfig } from "@builder.io/qwik-city/vite";
import baseConfig from "../../vite.config";

export default extendConfig(baseConfig, () => {
return {
build: {
ssr: true,
rollupOptions: {
input: ["@qwik-city-plan"],
},
},
plugins: [
staticAdapter({
origin: "https://yoursite.qwik.dev",
}),
],
};
});
Binary file added packages/qwik-web/bun.lockb
Binary file not shown.
20 changes: 16 additions & 4 deletions packages/qwik-web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,25 +15,28 @@
"build": "qwik build",
"build.client": "vite build",
"build.preview": "vite build --ssr src/entry.preview.tsx",
"build.server": "vite build -c adapters/static/vite.config.ts",
"build.types": "tsc --incremental --noEmit",
"build.velite": "velite build",
"deploy": "echo 'Run \"npm run qwik add\" to install a server adapter'",
"dev": "vite --mode ssr",
"dev.debug": "node --inspect-brk ./node_modules/vite/bin/vite.js --mode ssr --force",
"dev.velite": "bunx --bun velite dev",
"fmt": "prettier --write .",
"fmt.check": "prettier --check .",
"lint": "eslint \"src/**/*.ts*\"",
"preview": "qwik build preview && vite preview --open",
"start": "vite --open --mode ssr",
"qwik": "qwik",
"dev.velite": "bunx --bun velite dev"
"qwik": "qwik"
},
"devDependencies": {
"@builder.io/qwik": "^1.6.0",
"@builder.io/qwik-city": "^1.6.0",
"@builder.io/qwik": "^1.5.7",
"@builder.io/qwik-city": "^1.5.7",
"@types/eslint": "^8.56.10",
"@types/node": "^20.12.7",
"@typescript-eslint/eslint-plugin": "^7.7.1",
"@typescript-eslint/parser": "^7.7.1",
"@types/remark-sectionize": "workspace:../remark-sectionize",
"eslint": "^8.57.0",
"eslint-plugin-qwik": "^1.6.0",
"prettier": "^3.2.5",
Expand All @@ -43,6 +46,15 @@
"vite-tsconfig-paths": "^4.2.1"
},
"dependencies": {
"@types/mdast": "^4.0.4",
"rehype-pretty-code": "^0.13.2",
"remark-gemoji": "^8.0.0",
"remark-gfm": "^4.0.0",
"remark-math": "^6.0.0",
"remark-parse": "^11.0.0",
"remark-sectionize": "^2.0.0",
"shiki": "^1.10.1",
"unified": "^11.0.5",
"velite": "^0.1.0"
}
}
38 changes: 38 additions & 0 deletions packages/qwik-web/src/components/md/code-block.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { Resource, component$, useResource$ } from "@builder.io/qwik";
import {
type BundledLanguage,
codeToHtml,
type StringLiteralUnion,
type SpecialLanguage,
} from "shiki";

export interface Props {
lang?: StringLiteralUnion<BundledLanguage | SpecialLanguage>;
text: string;
}

export default component$((props: Props) => {
const codeResource = useResource$<string>(async () => {
if (props.lang) {
return codeToHtml(props.text, {
lang: props.lang,
themes: {
dark: "github-dark-dimmed",
light: "github-light",
},
});
} else {
return `<code>${props.text}</code>`;
}
});
return (
<figure>
<Resource
value={codeResource}
onPending={() => <pre></pre>}
onResolved={(text) => <div dangerouslySetInnerHTML={text} />}
onRejected={(err) => <div>{JSON.stringify(err)}</div>}
></Resource>
</figure>
);
});
21 changes: 21 additions & 0 deletions packages/qwik-web/src/components/md/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { component$ } from "@builder.io/qwik";
import type * as MdAst from "mdast";
import RootContent from "~/components/md/root-content";

export interface Props {
root: MdAst.Root;
}

function key(base: unknown): string {
return JSON.stringify(base);
}

export default component$((props: Props) => {
return (
<article>
{props.root.children.map((node) => (
<RootContent key={key(node.position)} node={node} />
))}
</article>
);
});
114 changes: 114 additions & 0 deletions packages/qwik-web/src/components/md/root-content.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import { Link } from "@builder.io/qwik-city";
import type * as MdAst from "mdast";
import CodeBlock from "./code-block";

export function key(node: MdAst.RootContent): string {
return JSON.stringify(node.position);
}

const RootContent = (props: { node: MdAst.RootContent }) => {
switch (props.node.type) {
case "blockquote":
return (
<blockquote>
{props.node.children.map((node) => (
<RootContent key={key(node)} node={node} />
))}
</blockquote>
);
case "paragraph":
return (
<p>
{props.node.children.map((node) => (
<RootContent key={key(node)} node={node} />
))}
</p>
);
case "section":
return (
<section>
{props.node.children.map((node) => (
<RootContent key={key(node)} node={node} />
))}
</section>
);
case "text":
return props.node.value;
case "inlineCode":
return <code>{props.node.value}</code>;
case "heading":
const inner = props.node.children.map((node) => (
<RootContent key={key(node)} node={node} />
));
switch (props.node.depth) {
case 1:
return <h1>{inner}</h1>;
case 2:
return <h2>{inner}</h2>;
case 3:
return <h3>{inner}</h3>;
case 4:
return <h4>{inner}</h4>;
case 5:
return <h5>{inner}</h5>;
case 6:
return <h6>{inner}</h6>;
}
return null;
case "break":
return <br />;
case "link":
return (
<Link href={props.node.url}>
{props.node.children.map((node) => (
<RootContent key={key(node)} node={node} />
))}
</Link>
);
case "code":
return (
<CodeBlock
text={props.node.value}
lang={props.node.lang || undefined}
/>
);
case "list":
if (props.node.ordered) {
return (
<ol>
{props.node.children.map((node) => (
<RootContent node={node} key={key(node)} />
))}
</ol>
);
} else {
return (
<ul>
{props.node.children.map((node) => (
<RootContent node={node} key={key(node)} />
))}
</ul>
);
}
case "listItem":
return (
<li>
{props.node.children.map((node) => (
<RootContent node={node} key={key(node)} />
))}
</li>
);
case "strong":
return (
<strong>
{props.node.children.map((node) => (
<RootContent node={node} key={key(node)} />
))}
</strong>
);
default:
return JSON.stringify(props.node);
}
};

export default RootContent;
Empty file.
20 changes: 13 additions & 7 deletions packages/qwik-web/src/routes/index.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@
import { component$ } from "@builder.io/qwik";
import type { DocumentHead } from "@builder.io/qwik-city";
import {post} from "#site/content";
console.log(post);
import { post as posts } from "#site/content";
import { Link } from "@builder.io/qwik-city";

export default component$(() => {
return (
<>
<h1>Hi 👋</h1>
<div>
Can't wait to see what you build with qwik!
<br />
Happy coding.
</div>
<nav>
<ul>
{posts.map((post) => (
<li key={post.slug}>
<Link href={`/post/${post.slug}`} key={post.slug}>
{post.title}
</Link>
</li>
))}
</ul>
</nav>
</>
);
});
Expand Down
28 changes: 28 additions & 0 deletions packages/qwik-web/src/routes/post/[...slug]/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { component$ } from "@builder.io/qwik";
import {
routeLoader$,
type StaticGenerateHandler,
} from "@builder.io/qwik-city";
import { post as posts } from "#site/content";
import Markdown from "~/components/md";

export const usePost = routeLoader$(async (event) => {
return posts.find((post) => post.slug === event.params.slug);
});

export default component$(() => {
const post = usePost();
if (post.value) {
return <Markdown root={post.value.content} />;
} else {
return <article></article>;
}
});

export const onStaticSiteGenerate: StaticGenerateHandler = async () => {
return {
params: posts.map((post) => ({
slug: post.slug,
})),
};
};
51 changes: 38 additions & 13 deletions packages/qwik-web/velite.config.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,47 @@
// @ts-check

import { defineConfig,s } from "velite";
import rehypePrettyCode from "rehype-pretty-code";
import remarkGemoji from "remark-gemoji";
import remarkGfm from "remark-gfm";
import remarkMath from "remark-math";
import remarkParse from "remark-parse";
import remarkSectionize from "remark-sectionize";
import { unified } from "unified";
import { defineConfig, s } from "velite";

const parser = unified()
.use(remarkParse)
.use(remarkGfm)
.use(remarkMath)
.use(remarkGemoji)
.use(rehypePrettyCode)
.use(remarkSectionize);

export default defineConfig({
collections: {
post: {
name: "post",
pattern: "**/*.md",
schema: s.object({
title: s.string(),
date: s.string(),
modified: s.string().nullish(),
description: s.string(),
publish: s.boolean(),
tags: s.array(s.string()),
content: s.custom().transform((_, {meta}) => meta.content),
excerpt: s.excerpt()
})
}
}
schema: s
.object({
title: s.string(),
date: s.string(),
modified: s.string().nullish(),
description: s.string(),
publish: s.boolean(),
tags: s.array(s.string()),
content: s
.custom()
.transform((_, { meta }) => parser.parse(meta.content)),
excerpt: s.excerpt(),
})
.transform((data, { meta }) => {
const slug = /\d{4}\/.+\.md$/.exec(meta.path)?.[1];
return {
...data,
slug: slug || "",
};
}),
},
},
});
Loading

0 comments on commit 164daa8

Please sign in to comment.