koa-parcel-middleware
v1.0.3
Published
parcel bundler koa middleware
Downloads
23
Maintainers
Readme
koa-parcel-middleware
parcel middleware for koa
why
parcel middleware enables you to:
- wire in advanced features, such as server-side-rendering. isomorphic js in compact form
- serve your ui application from your server application
- combine the parcel dev server functionality with an existing server application, rather than an extra process
install
yarn add koa-parcel-middleware koa koa-static
koa and koa-static are required peerDependencies
. koa-static is required such that
non-js assets (e.g. css, images, etc) may be served gracefully as requested by your ui.
usage
import { createMiddleware } from 'koa-parcel-middleware'
const middleware = createMiddleware({
bundler: `parcelBundlerInstance`,
renderHtmlMiddleware?: `<optionally-own-serving-your-entrypoint>`,
staticMiddleware: `koaStaticInstance` // serving parcel's built assets
})
the following is a rich, complete example of using the middleware api.
import { createMiddleware } from 'koa-parcel-middleware' // :)
import { App } from './app' // e.g. a react <App /> component
import { promises as fs } from 'fs'
import * as path from 'path'
import * as ReactDOMServer from 'react-dom/server'
import Bundler from 'parcel-bundler'
import CombinedStream from 'combined-stream'
import Koa from 'koa'
import serveStatic from 'koa-static'
// your parcel application's _unbuilt_ entry point!
const ENTRY_FILENAME = path.resolve(__dirname, 'index.html')
const isDev = process.env.NODE_ENV === 'development'
async function start () {
const app = new Koa()
// your parcel application's _built_ entry point!
const outFile = path.resolve(__dirname, 'dist', 'index.html')
const outDir = path.resolve(__dirname, 'dist')
const options = {
outDir,
outFile,
watch: isDev,
minify: !isDev,
scopeHoist: false,
hmr: isDev,
detailedReport: isDev
}
const bundler = new Bundler(ENTRY_FILENAME, options)
bundler.bundle()
const staticMiddleware = serveStatic(outDir)
const parcelMiddleware = createMiddleware({
bundler,
renderHtmlMiddleware: async (ctx, next) => {
// optionally wire in SSR!
// index.html
//
// <html>
// <div id="app"><!-- ssr-content --></div>
// <script src="app.tsx"></script>
// </html>
const outFileBuffer = await fs.readFile(outFile)
const [preAppEntry, postAppEntry] = outFileBuffer.toString()
.split(/<!--.*ssr.*-->/)
ctx.status = 200
const htmlStream = new CombinedStream()
;[
preAppEntry,
ReactDOMServer.renderToNodeStream(App()),
postAppEntry
].map(content => htmlStream.append(content))
ctx.body = htmlStream
ctx.type = 'html'
await next()
},
staticMiddleware
})
app.use((ctx, next) => parcelMiddleware(ctx, next))
app.listen(3000)
}
start()