Skip to content

Commit

Permalink
refactor(ssg): Removal of Libraries Dependent on Node.js (#2012)
Browse files Browse the repository at this point in the history
* remove Buffer

* fix

* fix

* type Bun

* test import

* fix & rename

* move a ssg test for deno

* import jsx

* console.log

* update CI

* revert toAbcSSG name

* rename

---------

Co-authored-by: Yusuke Wada <yusuke@kamawada.com>
  • Loading branch information
watany-dev and yusukebe committed Jan 19, 2024
1 parent e305103 commit 23d96a9
Show file tree
Hide file tree
Showing 11 changed files with 140 additions and 17 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ jobs:
- uses: denoland/setup-deno@v1
with:
deno-version: v1.x
- run: env NAME=Deno deno test --allow-read --allow-env -c runtime_tests/deno/deno.json runtime_tests/deno
- run: env NAME=Deno deno test --allow-read --allow-env --allow-write -c runtime_tests/deno/deno.json runtime_tests/deno
- run: deno test -c runtime_tests/deno-jsx/deno.precompile.json runtime_tests/deno-jsx
- run: deno test -c runtime_tests/deno-jsx/deno.react-jsx.json runtime_tests/deno-jsx

Expand Down
3 changes: 2 additions & 1 deletion deno_dist/adapter/deno/ssg.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ import type { FileSystemModule, ToSSGAdaptorInterface } from '../../helper/ssg/i
*/
export const denoFileSystemModule: FileSystemModule = {
writeFile: async (path, data) => {
const uint8Data = typeof data === 'string' ? new TextEncoder().encode(data) : data
const uint8Data =
typeof data === 'string' ? new TextEncoder().encode(data) : new Uint8Array(data)
await Deno.writeFile(path, uint8Data)
},
mkdir: async (path, options) => {
Expand Down
6 changes: 3 additions & 3 deletions deno_dist/helper/ssg/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { Buffer } from "node:buffer";
import { replaceUrlParam } from '../../client/utils.ts'
import type { Context } from '../../context.ts'
import { inspectRoutes } from '../../helper/dev/index.ts'
import type { Hono } from '../../hono.ts'
import type { Env, MiddlewareHandler, Schema } from '../../types.ts'
import { bufferToString } from '../../utils/buffer.ts'
import { getExtension } from '../../utils/mime.ts'
import { joinPaths, dirname } from './utils.ts'

Expand All @@ -13,7 +13,7 @@ import { joinPaths, dirname } from './utils.ts'
* The API might be changed.
*/
export interface FileSystemModule {
writeFile(path: string, data: string | Buffer): Promise<void>
writeFile(path: string, data: string | ArrayBuffer | Uint8Array): Promise<void>
mkdir(path: string, options: { recursive: boolean }): Promise<void | string>
}

Expand Down Expand Up @@ -153,7 +153,7 @@ export const saveContentToFiles = async (
if (typeof content === 'string') {
await fsModule.writeFile(filePath, content)
} else if (content instanceof ArrayBuffer) {
await fsModule.writeFile(filePath, Buffer.from(content))
await fsModule.writeFile(filePath, bufferToString(content))
}
files.push(filePath)
}
Expand Down
1 change: 1 addition & 0 deletions deno_dist/middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@ export * from './middleware/timing/index.ts'
export * from './middleware/pretty-json/index.ts'
export * from './middleware/secure-headers/index.ts'
export * from './adapter/deno/serve-static.ts'
export * from './adapter/deno/ssg.ts'
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"scripts": {
"test": "tsc --noEmit && vitest --run && vitest -c .vitest.config/jsx-runtime-default.ts --run && vitest -c .vitest.config/jsx-runtime-dom.ts --run",
"test:watch": "vitest --watch",
"test:deno": "env NAME=Deno deno test --allow-read --allow-env -c runtime_tests/deno/deno.json runtime_tests/deno && deno test --no-lock -c runtime_tests/deno-jsx/deno.precompile.json runtime_tests/deno-jsx && deno test --no-lock -c runtime_tests/deno-jsx/deno.react-jsx.json runtime_tests/deno-jsx",
"test:deno": "env NAME=Deno deno test --allow-read --allow-env --allow-write -c runtime_tests/deno/deno.json runtime_tests/deno && deno test --no-lock -c runtime_tests/deno-jsx/deno.precompile.json runtime_tests/deno-jsx && deno test --no-lock -c runtime_tests/deno-jsx/deno.react-jsx.json runtime_tests/deno-jsx",
"test:bun": "env NAME=Bun bun test --jsx-import-source ../../src/jsx runtime_tests/bun/index.test.tsx",
"test:fastly": "vitest --run --config ./runtime_tests/fastly/vitest.config.ts",
"test:node": "env NAME=Node vitest --run --config ./runtime_tests/node/vitest.config.ts",
Expand Down
65 changes: 63 additions & 2 deletions runtime_tests/bun/index.test.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { describe, it, expect, vi, beforeEach } from 'vitest'
import { serveStatic } from '../../src/adapter/bun'
import { describe, it, expect, vi, beforeEach, afterAll } from 'vitest'
import { serveStatic, toSSG } from '../../src/adapter/bun'
import { Context } from '../../src/context'
import { env, getRuntimeKey } from '../../src/helper/adapter'
import { Hono } from '../../src/index'
Expand Down Expand Up @@ -207,3 +207,64 @@ describe('JSX Middleware', () => {
expect(await res.text()).toBe('<html><p>hello</p></html>')
})
})

describe('toSSG function', () => {
let app: Hono

beforeEach(() => {
app = new Hono()
app.get('/', (c) => c.text('Hello, World!'))
app.get('/about', (c) => c.text('About Page'))
app.get('/about/some', (c) => c.text('About Page 2tier'))
app.post('/about/some/thing', (c) => c.text('About Page 3tier'))
app.get('/bravo', (c) => c.html('Bravo Page'))
app.get('/Charlie', async (c, next) => {
c.setRenderer((content, head) => {
return c.html(
<html>
<head>
<title>{head.title || ''}</title>
</head>
<body>
<p>{content}</p>
</body>
</html>
)
})
await next()
})
app.get('/Charlie', (c) => {
return c.render('Hello!', { title: 'Charlies Page' })
})
})

it('Should correctly generate static HTML files for Hono routes', async () => {
const result = await toSSG(app, { dir: './static' })
expect(result.success).toBeTruly
expect(result.error).toBeUndefined()
expect(result.files).toBeDefined()
afterAll(async () => {
await deleteDirectory('./static')
})
})
})

const fs = require('fs').promises
const path = require('path')

async function deleteDirectory(dirPath) {
if (
await fs
.stat(dirPath)
.then((stat) => stat.isDirectory())
.catch(() => false)
) {
for (const entry of await fs.readdir(dirPath)) {
const entryPath = path.join(dirPath, entry)
await deleteDirectory(entryPath)
}
await fs.rmdir(dirPath)
} else {
await fs.unlink(dirPath)
}
}
57 changes: 57 additions & 0 deletions runtime_tests/deno/ssg.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/** @jsx jsx */
/** @jsxFrag Fragment */

import { toSSG } from '../../deno_dist/middleware.ts'
// eslint-disable-next-line @typescript-eslint/no-unused-vars
import { jsx } from '../../deno_dist/middleware.ts'
import { Hono } from '../../deno_dist/mod.ts'
import { assertEquals } from '../deno/deps.ts'

Deno.test('toSSG function', async () => {
const app = new Hono()
app.get('/', (c) => c.text('Hello, World!'))
app.get('/about', (c) => c.text('About Page'))
app.get('/about/some', (c) => c.text('About Page 2tier'))
app.post('/about/some/thing', (c) => c.text('About Page 3tier'))
app.get('/bravo', (c) => c.html('Bravo Page'))
app.get('/Charlie', async (c, next) => {
c.setRenderer((content) => {
return c.html(
<html>
<body>
<p>{content}</p>
</body>
</html>
)
})
await next()
})
app.get('/Charlie', (c) => {
return c.render('Hello!')
})

const result = await toSSG(app, { dir: './ssg-static' })
assertEquals(result.success, true)
assertEquals(result.error, undefined)
assertEquals(result.files !== undefined, true)

await deleteDirectory('./ssg-static')
})

async function deleteDirectory(dirPath: string): Promise<void> {
try {
const stat = await Deno.stat(dirPath)

if (stat.isDirectory) {
for await (const dirEntry of Deno.readDir(dirPath)) {
const entryPath = `${dirPath}/${dirEntry.name}`
await deleteDirectory(entryPath)
}
await Deno.remove(dirPath)
} else {
await Deno.remove(dirPath)
}
} catch (error) {
console.error(`Error deleting directory: ${error}`)
}
}
12 changes: 6 additions & 6 deletions src/adapter/bun/ssg.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
// @denoify-ignore
/* eslint-disable @typescript-eslint/ban-ts-comment */
import { mkdir, writeFile } from 'fs/promises'
import { toSSG as baseToSSG } from '../../helper/ssg'
import type { FileSystemModule, ToSSGAdaptorInterface } from '../../helper/ssg'

// @ts-ignore
const { write } = Bun

/**
* @experimental
* `bunFileSystemModule` is an experimental feature.
* The API might be changed.
*/
export const bunFileSystemModule: FileSystemModule = {
writeFile: (path, data) => {
return writeFile(path, data)
},
mkdir: async (path, options) => {
await mkdir(path, options)
writeFile: async (path, data) => {
await write(path, data)
},
mkdir: async () => {},
}

/**
Expand Down
3 changes: 2 additions & 1 deletion src/adapter/deno/ssg.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ import type { FileSystemModule, ToSSGAdaptorInterface } from '../../helper/ssg/i
*/
export const denoFileSystemModule: FileSystemModule = {
writeFile: async (path, data) => {
const uint8Data = typeof data === 'string' ? new TextEncoder().encode(data) : data
const uint8Data =
typeof data === 'string' ? new TextEncoder().encode(data) : new Uint8Array(data)
await Deno.writeFile(path, uint8Data)
},
mkdir: async (path, options) => {
Expand Down
5 changes: 3 additions & 2 deletions src/helper/ssg/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import type { Context } from '../../context'
import { inspectRoutes } from '../../helper/dev'
import type { Hono } from '../../hono'
import type { Env, MiddlewareHandler, Schema } from '../../types'
import { bufferToString } from '../../utils/buffer'
import { getExtension } from '../../utils/mime'
import { joinPaths, dirname } from './utils'

Expand All @@ -12,7 +13,7 @@ import { joinPaths, dirname } from './utils'
* The API might be changed.
*/
export interface FileSystemModule {
writeFile(path: string, data: string | Buffer): Promise<void>
writeFile(path: string, data: string | ArrayBuffer | Uint8Array): Promise<void>
mkdir(path: string, options: { recursive: boolean }): Promise<void | string>
}

Expand Down Expand Up @@ -152,7 +153,7 @@ export const saveContentToFiles = async (
if (typeof content === 'string') {
await fsModule.writeFile(filePath, content)
} else if (content instanceof ArrayBuffer) {
await fsModule.writeFile(filePath, Buffer.from(content))
await fsModule.writeFile(filePath, bufferToString(content))
}
files.push(filePath)
}
Expand Down
1 change: 1 addition & 0 deletions src/middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@ export * from './middleware/timing'
export * from './middleware/pretty-json'
export * from './middleware/secure-headers'
export * from './adapter/deno/serve-static'
export * from './adapter/deno/ssg'

0 comments on commit 23d96a9

Please sign in to comment.