diff --git a/connect.js b/connect.js index 7b75d57..c1d2f6f 100644 --- a/connect.js +++ b/connect.js @@ -37,7 +37,8 @@ module.exports = function connect(opts) { return async function(req, res, next) { const url = req.url.replace(/\?.+/, ''); - if (url.startsWith('/client/')) { + if (url === '/service-worker.js' || url.startsWith('/client/')) { + await webpack_compiler.ready; res.set({ 'Content-Type': 'application/javascript' }); @@ -53,21 +54,21 @@ module.exports = function connect(opts) { try { for (const route of routes) { if (route.test(url)) { + await webpack_compiler.ready; + req.params = route.exec(url); - const chunk = await webpack_compiler.get_chunk(route.id); - const mod = require(chunk); + const chunk = webpack_compiler.chunks[route.id]; + const mod = require(path.resolve(dest, 'server', chunk)); if (route.type === 'page') { - const main = await webpack_compiler.client_main; - let data = { params: req.params, query: req.query }; if (mod.default.preload) data = Object.assign(data, await mod.default.preload(data)); const { html, head, css } = mod.default.render(data); const page = templates.render(200, { - main, + main: webpack_compiler.client_main, html, head: `${head}`, styles: (css && css.code ? `` : '') diff --git a/utils/create_webpack_compiler.js b/utils/create_webpack_compiler.js index 282e43f..9e7d8a8 100644 --- a/utils/create_webpack_compiler.js +++ b/utils/create_webpack_compiler.js @@ -1,8 +1,9 @@ const fs = require('fs'); const path = require('path'); +const glob = require('glob'); const webpack = require('webpack'); -module.exports = function create_webpack_compiler(out, routes, dev) { +module.exports = function create_webpack_compiler(dest, routes, dev) { const compiler = {}; const client = webpack( @@ -28,34 +29,52 @@ module.exports = function create_webpack_compiler(out, routes, dev) { // TODO server } else { - compiler.client_main = new Promise((fulfil, reject) => { - client.run((err, stats) => { - console.log(stats.toString({ colors: true })); + compiler.ready = Promise.all([ + new Promise((fulfil, reject) => { + client.run((err, stats) => { + console.log(stats.toString({ colors: true })); - if (err || stats.hasErrors()) { - reject(err || stats.toJson().errors[0]); - } + const info = stats.toJson(); - const filename = stats.toJson().assetsByChunkName.main; - fulfil(`/client/${filename}`); - }); - }); + if (err || stats.hasErrors()) { + reject(err || info.errors[0]); + } - const chunks = new Promise((fulfil, reject) => { - server.run((err, stats) => { - console.log(stats.toString({ colors: true })); + compiler.client_main = `/client/${info.assetsByChunkName.main}`; + compiler.assets = info.assets.map(asset => `/client/${asset.name}`); - if (err || stats.hasErrors()) { - reject(err || stats.toJson().errors[0]); - } + fulfil(); + }); + }), - fulfil(stats.toJson().assetsByChunkName); - }); + new Promise((fulfil, reject) => { + server.run((err, stats) => { + console.log(stats.toString({ colors: true })); + + const info = stats.toJson(); + + if (err || stats.hasErrors()) { + reject(err || info.errors[0]); + } + + compiler.chunks = info.assetsByChunkName; + + fulfil(); + }); + }) + ]).then(() => { + const assets = glob.sync('**', { cwd: 'assets' }); + + const service_worker = fs.readFileSync('templates/service-worker.js', 'utf-8') + .replace('__timestamp__', Date.now()) + .replace('__assets__', JSON.stringify(assets)) + .replace('__javascript__', JSON.stringify(compiler.assets)); + + fs.writeFileSync(path.resolve(dest, 'service-worker.js'), service_worker); }); compiler.get_chunk = async id => { - const assetsByChunkName = await chunks; - return path.resolve(out, 'server', assetsByChunkName[id]); + return path.resolve(dest, 'server', compiler.chunks[id]); }; }