dev: Playground enable custom html landing page

This commit is contained in:
Cole Lawrence 2022-06-24 08:13:58 -04:00
parent bbf7ee9244
commit f70eea1c48

View file

@ -1,4 +1,4 @@
import {readdirSync} from 'fs' import {readdirSync, readFileSync, statSync} from 'fs'
import {writeFile, readFile} from 'fs/promises' import {writeFile, readFile} from 'fs/promises'
import path from 'path' import path from 'path'
import type {BuildOptions} from 'esbuild' import type {BuildOptions} from 'esbuild'
@ -18,6 +18,7 @@ import {createServerForceClose} from './createServerForceClose'
const playgroundDir = (folder: string) => path.join(__dirname, '..', folder) const playgroundDir = (folder: string) => path.join(__dirname, '..', folder)
const buildDir = playgroundDir('build') const buildDir = playgroundDir('build')
const srcDir = playgroundDir('src')
const sharedDir = playgroundDir('src/shared') const sharedDir = playgroundDir('src/shared')
const personalDir = playgroundDir('src/personal') const personalDir = playgroundDir('src/personal')
const testDir = playgroundDir('src/tests') const testDir = playgroundDir('src/tests')
@ -34,12 +35,15 @@ export async function start(options: {
const liveReload = options.dev ? createEsbuildLiveReloadTools() : undefined const liveReload = options.dev ? createEsbuildLiveReloadTools() : undefined
type Groups = { type PlaygroundExample = {
[group: string]: { useHtml?: string
[module: string]: { entryFilePath: string
entryDir: string
outDir: string outDir: string
} }
type Groups = {
[group: string]: {
[module: string]: PlaygroundExample
} }
} }
@ -51,17 +55,45 @@ export async function start(options: {
return [ return [
path.basename(groupDir), path.basename(groupDir),
Object.fromEntries( Object.fromEntries(
readdirSync(groupDir).map((moduleDirName) => [ readdirSync(groupDir)
path.basename(moduleDirName), .map(
(moduleDirName): [string, PlaygroundExample | undefined] => {
const entryKey = path.basename(moduleDirName)
const entryFilePath = path.join(
groupDir,
moduleDirName,
'index.tsx',
)
if (!tryOrUndefined(() => statSync(entryFilePath).isFile()))
return [entryKey, undefined]
return [
entryKey,
{ {
entryDir: path.join(groupDir, moduleDirName), // Including your own html file for playground is an experimental feature,
// it's not quite ready for "prime time" and advertising to the masses until
// it properly handles file watching.
// It's good for now, since we can use it for some demos, just make sure that
// you add a comment to the custom index.html file saying that you have to
// restart playground server entirely to see changes.
useHtml: tryOrUndefined(() =>
readFileSync(
path.join(groupDir, moduleDirName, 'index.html'),
'utf-8',
),
),
entryFilePath,
outDir: path.join( outDir: path.join(
buildDir, buildDir,
path.basename(groupDir), path.basename(groupDir),
moduleDirName, moduleDirName,
), ),
}, },
]), ]
},
)
.filter((entry) => entry[1] !== undefined),
), ),
] ]
} catch (e) { } catch (e) {
@ -76,11 +108,11 @@ export async function start(options: {
// Collect all entry files // Collect all entry files
const entryPoints = Object.values(groups) const entryPoints = Object.values(groups)
.flatMap((group) => Object.values(group)) .flatMap((group) => Object.values(group))
.map((module) => path.join(module.entryDir, 'index.tsx')) .map((module) => module.entryFilePath)
// Collect all output directories // Collect all output directories
const outDirs = Object.values(groups).flatMap((group) => const outModules = Object.values(groups).flatMap((group) =>
Object.values(group).map((module) => module.outDir), Object.values(group),
) )
// Render home page contents // Render home page contents
@ -158,15 +190,15 @@ export async function start(options: {
'utf-8', 'utf-8',
), ),
// Write module pages // Write module pages
...outDirs.map((outDir) => ...outModules.map((outModule) =>
writeFile( writeFile(
path.join(outDir, 'index.html'), path.join(outModule.outDir, 'index.html'),
// Insert the script // Insert the script
index.replace( (outModule.useHtml ?? index).replace(
/<\/body>/, /<\/body>/,
`<script src="${path.join( `<script src="${path.join(
'/', '/',
path.relative(buildDir, outDir), path.relative(buildDir, outModule.outDir),
'index.js', 'index.js',
)}"></script></body>`, )}"></script></body>`,
), ),
@ -226,3 +258,11 @@ export async function start(options: {
}, },
} }
} }
function tryOrUndefined<T>(fn: () => T): T | undefined {
try {
return fn()
} catch (err) {
return undefined
}
}