Skip to content

Commit

Permalink
Merge pull request #71 from rkostrzewski/feature/webpack-ssr
Browse files Browse the repository at this point in the history
feature: Prerender using webpack
  • Loading branch information
hassanbazzi authored Jun 28, 2017
2 parents 9c9edc1 + 5ffc9fc commit aaebfaf
Show file tree
Hide file tree
Showing 25 changed files with 420 additions and 292 deletions.
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@
"devDependencies": {
"babel-cli": "^6.24.0",
"babel-eslint": "^7.2.1",
"babel-plugin-transform-runtime": "^6.23.0",
"chrome-launcher": "^0.1.1",
"chrome-remote-interface": "^0.23.2",
"eslint": "^3.19.0",
Expand All @@ -81,6 +82,8 @@
"html-webpack-exclude-assets-plugin": "0.0.5",
"lodash": "^4.17.4",
"ncp": "^2.0.0",
"node-sass": "^4.5.3",
"sass-loader": "^6.0.6",
"tap-diff": "^0.1.1",
"tape": "^4.6.3",
"uuid": "^3.0.1"
Expand Down Expand Up @@ -134,7 +137,7 @@
"rimraf": "^2.6.1",
"script-ext-html-webpack-plugin": "^1.8.0",
"simplehttp2server": "^2.0.0",
"sw-precache-webpack-plugin": "^0.11.0",
"sw-precache-webpack-plugin": "^0.11.2",
"tmp": "0.0.31",
"unfetch": "^3.0.0",
"url-loader": "^0.5.8",
Expand Down
9 changes: 2 additions & 7 deletions src/commands/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@ import { resolve } from 'path';
import promisify from 'es6-promisify';
import rimraf from 'rimraf';
import asyncCommand from '../lib/async-command';
import webpackConfig from '../lib/webpack-config';
import transformConfig from '../lib/transform-config';
import runWebpack, { showStats, writeJsonStats } from '../lib/run-webpack';
import runWebpack, { showStats, writeJsonStats } from '../lib/webpack/run-webpack';

export default asyncCommand({
command: 'build [src] [dest]',
Expand Down Expand Up @@ -47,15 +45,12 @@ export default asyncCommand({
},

async handler(argv) {
let config = webpackConfig(argv);
await transformConfig(argv, config);

if (argv.clean) {
let dest = resolve(argv.cwd || process.cwd(), argv.dest || 'build');
await promisify(rimraf)(dest);
}

let stats = await runWebpack(false, config);
let stats = await runWebpack(false, argv);
showStats(stats);

if (argv.json) {
Expand Down
9 changes: 2 additions & 7 deletions src/commands/watch.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import asyncCommand from '../lib/async-command';
import webpackConfig from '../lib/webpack-config';
import transformConfig from '../lib/transform-config';
import getSslCert from '../lib/ssl-cert';
import runWebpack, { showStats } from '../lib/run-webpack';
import runWebpack, { showStats } from '../lib/webpack/run-webpack';

export default asyncCommand({
command: 'watch [src]',
Expand Down Expand Up @@ -54,10 +52,7 @@ export default asyncCommand({
argv.https = ssl;
}

let config = webpackConfig(argv);
await transformConfig(argv, config);

let stats = await runWebpack(true, config, showStats);
let stats = await runWebpack(true, argv, showStats);
showStats(stats);
}
});
55 changes: 0 additions & 55 deletions src/lib/prerender.js

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ module.exports.pitch = function(remainingRequest) {
}

return `
import async from ${JSON.stringify(path.resolve(__dirname, '../components/async'))};
import async from ${JSON.stringify(path.resolve(__dirname, '../../components/async'))};
function load(cb) {
require.ensure([], function(require) {
Expand Down
3 changes: 3 additions & 0 deletions src/lib/webpack/dummy-loader.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = function(source, map) {
this.callback(null, source, map);
};
File renamed without changes.
File renamed without changes.
27 changes: 27 additions & 0 deletions src/lib/webpack/prerender.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { resolve } from 'path';

export default function prerender(outputDir, params) {
params = params || {};

let entry = resolve(outputDir, './ssr-build/ssr-bundle.js'),
url = params.url || '/';

global.location = { href:url, pathname:url };
global.history = {};

let m = require(entry),
app = m && m.default || m;

if (typeof app!=='function') {
// eslint-disable-next-line no-console
console.warn('Entry does not export a Component function/class, aborting prerendering.');
return '';
}

let preact = require('preact'),
renderToString = require('preact-render-to-string');

let html = renderToString(preact.h(app, { url }));

return html;
}
File renamed without changes.
68 changes: 47 additions & 21 deletions src/lib/run-webpack.js → src/lib/webpack/run-webpack.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,26 @@
import { resolve } from 'path';
import path from 'path';
import fs from 'fs.promised';
import webpack from 'webpack';
import WebpackDevServer from 'webpack-dev-server';
import chalk from 'chalk';
import clientConfig from './webpack-client-config';
import serverConfig from './webpack-server-config';
import transformConfig from './transform-config';

export default (watch=false, config, onprogress) => new Promise( (resolve, reject) => {
let compiler = webpack(config);
export default async (watch=false, env, onprogress) => {
if (watch) {
return await devBuild(env, onprogress);
}

let done = (err, stats) => {
if (err || stats.hasErrors()) {
reject(err || stats.toJson().errors.join('\n'));
}
else {
// Timeout for plugins that work on `after-emit` event of webpack
setTimeout(()=>{
resolve(stats);
},20);
}
};
return await prodBuild(env);
};

if (watch) {
const devBuild = async (env, onprogress) => {
let config = clientConfig(env);
await transformConfig(env, config);

let compiler = webpack(config);
return await new Promise((resolve, reject) => {
let first = true;
compiler.plugin('done', stats => {
if (first) {
Expand All @@ -34,11 +35,34 @@ export default (watch=false, config, onprogress) => new Promise( (resolve, rejec

let server = new WebpackDevServer(compiler, config.devServer);
server.listen(config.devServer.port);
});
};

const prodBuild = async (env) => {
let compiler, client = clientConfig(env);

await transformConfig(env, client);

if (env.prerender) {
let ssrConfig = serverConfig(env);
await transformConfig(env, ssrConfig, true);
compiler = webpack([client, ssrConfig]);
} else {
compiler = webpack(client);
}
else {
compiler.run(done);
}
});

return await new Promise((resolve, reject) => {
compiler.run((err, stats) => {
if (err || stats.hasErrors()) {
reject(err || stats.toJson().errors.join('\n'));
}
else {
// Timeout for plugins that work on `after-emit` event of webpack
setTimeout(()=> resolve(stats), 20);
}
});
});
};

export function showStats(stats) {
let info = stats.toJson();
Expand All @@ -59,13 +83,15 @@ export function showStats(stats) {
}

export function writeJsonStats(stats) {
const outputPath = resolve(process.cwd(), 'stats.json');
const jsonStats = stats.toJson({
let outputPath = path.resolve(process.cwd(), 'stats.json');
let jsonStats = stats.toJson({
json: true,
chunkModules: true,
source: false,
});

jsonStats = (jsonStats.children && jsonStats.children[0]) || jsonStats;

jsonStats.modules.forEach(normalizeModule);
jsonStats.chunks.forEach(c => c.modules.forEach(normalizeModule));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {
webpack,
} from '@webpack-blocks/webpack2';

export default async function (env, config) {
export default async function (env, config, ssr = false) {
let transformerPath = path.resolve(env.cwd, env.config || './preact.config.js');

try {
Expand All @@ -22,7 +22,7 @@ export default async function (env, config) {
const m = require(transformerPath);
const transformer = m && m.default || m;
try {
await transformer(config, Object.assign({}, env), new WebpackConfigHelpers(env.cwd));
await transformer(config, Object.assign({}, env, { ssr }), new WebpackConfigHelpers(env.cwd));
} catch (err) {
throw new Error(`Error at ${transformerPath}: \n` + err);
}
Expand Down
Loading

0 comments on commit aaebfaf

Please sign in to comment.