dev: Playground enable custom html landing page
This commit is contained in:
parent
bbf7ee9244
commit
f70eea1c48
1 changed files with 63 additions and 23 deletions
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue