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 PlaygroundExample = {
useHtml?: string
entryFilePath: string
outDir: string
}
type Groups = { type Groups = {
[group: string]: { [group: string]: {
[module: string]: { [module: string]: PlaygroundExample
entryDir: string
outDir: string
}
} }
} }
@ -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] => {
entryDir: path.join(groupDir, moduleDirName), const entryKey = path.basename(moduleDirName)
outDir: path.join( const entryFilePath = path.join(
buildDir, groupDir,
path.basename(groupDir), moduleDirName,
moduleDirName, 'index.tsx',
), )
},
]), if (!tryOrUndefined(() => statSync(entryFilePath).isFile()))
return [entryKey, undefined]
return [
entryKey,
{
// 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(
buildDir,
path.basename(groupDir),
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
}
}