Static Site Generator
$ npm i -S @potato4d/dodai
$ dodai init$ dodai initAs of 0.8.0, @potato4d/dodai is ESM-only. The library, CLI, and temporary
site modules used during builds all run as native ESM.
import { build, dev, init } from '@potato4d/dodai';
import { HotReload } from '@potato4d/dodai/hotreload';Use these public package entry points instead of importing files from dist.
- Replace CommonJS
require()calls with ESMimportstatements. - Set
"type": "module"in the site project'spackage.json. - Use
"module": "NodeNext"and"moduleResolution": "NodeNext"intsconfig.json. - Include the emitted
.jsextension in local TypeScript imports, for exampleimport { value } from './value.js'.
dodai init applies these ESM settings for new projects.
- src/layouts/default.tsx
import * as React from 'react';
type LayoutProps = { head: JSX.Element | null; children?: React.ReactNode };
export const Layout: React.FC<LayoutProps> = ({ head, children }) => {
return (
<html lang="ja">
<head>
<meta charSet="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
{head}
</head>
<body>
{children}
</body>
</html>
)
}import React from 'react'
export const Head: React.FC = () => {
return (
<>
<title>static route page</title>
</>
)
}
export const Page: React.FC = () => {
return (
<div>
static route page
</div>
)
}// src/pages/entry/[single].tsx
import React from 'react'
type EntryProps = {
url: string;
data: {
title: string;
date: string;
body: string;
}
}
export const Head: React.FC<EntryProps> = ({ url, data }) => {
return (
<>
<title>{data.title}</title>
</>
)
}
export const Page: React.FC<EntryProps> = ({ url, data }) => {
return (
<div>
<h2>{data.title}</h2>
<time>{data.date}</time>
<div dangerouslySetInnerHTML={{ __html: data.body }} />
</div>
)
}// src/data/entry/[single].tsx
type Entry = {
url: string;
data: {
title: string;
date: string;
body: string;
}
}
export const data: Entry[] = [
{
url: '/entry/1',
data: {
title: 'first entry',
date: new Date().toISOString(),
body: '<p>hello</p>'
}
}
]$ env NODE_ENV='production' dodai build$ dodai dev- props:
{ dev?: boolean }- dev: default
process.env.NODE_ENV !== 'production'
- dev: default
import * as React from 'react';
import { HotReload } from '@potato4d/dodai/hotreload';
type LayoutProps = { head: JSX.Element | null; children?: React.ReactNode };
export const Layout: React.FC<LayoutProps> = ({ head, children }) => {
return (
<html lang="ja">
<head>
<meta charSet="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
{head}
<HotReload />
</head>
<body>
{children}
</body>
</html>
)
}$ pnpm install --frozen-lockfile
$ pnpm testThe test command builds the native ESM package and runs its package, CLI, site generation, dynamic route, and module-cache integration checks.
Releases are published from GitHub Actions with npm Trusted Publishing. See the release runbook for the automated gates and the one-time npm configuration.