Skip to content

Commit

Permalink
refactor(plugin-webpack): use a single webpack compiler for all rende…
Browse files Browse the repository at this point in the history
…rer process's

Shoutout to @mnquintana for proving this was possible :)
  • Loading branch information
MarshallOfSound committed May 14, 2018
1 parent b747c99 commit 674c5f2
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 43 deletions.
45 changes: 44 additions & 1 deletion packages/plugin/webpack/src/Config.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,68 @@
import { Configuration as WebpackConfiguration } from 'webpack';

export interface WebpackPluginEntryPoint {
/**
* Relative or absolute path to the HTML template file for this entry point
*/
html: string;
/**
* Relative or absolute path to the main JS file for this entry point
*/
js: string;
/**
* Human friendly name of your entry point
*/
name: string;
/**
* Additional entries to put in the array of entries for this entry point,
* useful if you need to set up things like error reporting as separate
* entry files into your application.
*/
prefixedEntries?: string[];
/**
* Additional chunks to include in the outputted HTML file, use this if you
* set up some custom chunking. E.g. CommonChunksPlugin
*/
additionalChunks?: string[];
/**
* Information about the preload script for this entry point, if you don't use
* preload scripts you don't need to set this.
*/
preload?: WebpackPreloadEntryPoint;
}

export interface WebpackPreloadEntryPoint {
/**
* Relative or absolute path to the preload JS file
*/
js: string;
/**
* Additional entries to put in the array of entries for this preload script,
* useful if you need to set up things like error reporting as separate
* entry files into your application.
*/
prefixedEntries?: string[];
}

export interface WebpackPluginRendererConfig {
/**
* The webpack config for your renderer process
*/
config: WebpackConfiguration | string;

/**
* Array of entry points, these should map to the windows your app needs to
* open. Each window requires it's own entry point
*/
entryPoints: WebpackPluginEntryPoint[];
}

export interface WebpackPluginConfig {
/**
* The webpack config for your main process
*/
mainConfig: WebpackConfiguration | string;
/**
* Electron Forge webpack configuration for your renderer process
*/
renderer: WebpackPluginRendererConfig;
}
90 changes: 48 additions & 42 deletions packages/plugin/webpack/src/WebpackPlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ export default class WebpackPlugin extends PluginBase<WebpackPluginConfig> {
defines[`${entryPoint.name.toUpperCase().replace(/ /g, '_')}_WEBPACK_ENTRY`] =
this.isProd
? `\`file://\$\{require('path').resolve(__dirname, '../renderer', '${entryPoint.name}', 'index.html')\}\``
: `'http://localhost:${BASE_PORT + index}'`;
: `'http://localhost:${BASE_PORT}/${entryPoint.name}'`;

if (entryPoint.preload) {
defines[`${entryPoint.name.toUpperCase().replace(/ /g, '_')}_PRELOAD_WEBPACK_ENTRY`] =
Expand Down Expand Up @@ -171,29 +171,36 @@ export default class WebpackPlugin extends PluginBase<WebpackPluginConfig> {
}, rendererConfig);
}

getRendererConfig = async (entryPoint: WebpackPluginEntryPoint) => {
getRendererConfig = async (entryPoints: WebpackPluginEntryPoint[]) => {
const rendererConfig = this.resolveConfig(this.config.renderer.config);
const prefixedEntries = entryPoint.prefixedEntries || [];
const entry: webpack.Entry = {};
for (const entryPoint of entryPoints) {
const prefixedEntries = entryPoint.prefixedEntries || [];
entry[entryPoint.name] = prefixedEntries
.concat([entryPoint.js])
.concat(this.isProd ? [] : ['webpack-hot-middleware/client']);
}

return merge.smart({
entry,
devtool: 'inline-source-map',
target: 'electron-renderer',
entry: prefixedEntries.concat([
entryPoint.js,
]).concat(this.isProd ? [] : ['webpack-hot-middleware/client']),
output: {
path: path.resolve(this.baseDir, 'renderer', entryPoint.name),
filename: 'index.js',
path: path.resolve(this.baseDir, 'renderer'),
filename: '[name]/index.js',
},
node: {
__dirname: false,
__filename: false,
},
plugins: [
plugins: entryPoints.map(entryPoint =>
new HtmlWebpackPlugin({
title: entryPoint.name,
template: entryPoint.html,
filename: `${entryPoint.name}/index.html`,
chunks: [entryPoint.name].concat(entryPoint.additionalChunks || []),
}),
].concat(this.isProd ? [] : [new webpack.HotModuleReplacementPlugin()]),
).concat(this.isProd ? [] : [new webpack.HotModuleReplacementPlugin()]),
}, rendererConfig);
}

Expand Down Expand Up @@ -226,51 +233,50 @@ export default class WebpackPlugin extends PluginBase<WebpackPluginConfig> {
}

compileRenderers = async (watch = false) => {
for (const entryPoint of this.config.renderer.entryPoints) {
await asyncOra(`Compiling Renderer Template: ${entryPoint.name}`, async () => {
await new Promise(async (resolve, reject) => {
webpack(await this.getRendererConfig(entryPoint)).run((err, stats) => {
if (err) return reject(err);
resolve();
});
await asyncOra('Compiling Renderer Template', async () => {
await new Promise(async (resolve, reject) => {
webpack(await this.getRendererConfig(this.config.renderer.entryPoints)).run((err, stats) => {
if (err) return reject(err);
resolve();
});
if (entryPoint.preload) {
});
});

for (const entryPoint of this.config.renderer.entryPoints) {
if (entryPoint.preload) {
await asyncOra(`Compiling Renderer Preload: ${entryPoint.name}`, async () => {
await new Promise(async (resolve, reject) => {
webpack(await this.getPreloadRendererConfig(entryPoint, entryPoint.preload!)).run((err, stats) => {
if (err) return reject(err);
resolve();
});
});
}
});
});
}
}
}

launchDevServers = async (logger: Logger) => {
await asyncOra('Launch Dev Servers', async () => {
let index = 0;
for (const entryPoint of this.config.renderer.entryPoints) {
const tab = logger.createTab(entryPoint.name);
const tab = logger.createTab('Renderers');

const config = await this.getRendererConfig(entryPoint);
const compiler = webpack(config);
const server = webpackDevMiddleware(compiler, {
logger: {
log: tab.log.bind(tab),
info: tab.log.bind(tab),
error: tab.log.bind(tab),
warn: tab.log.bind(tab),
},
publicPath: '/',
hot: true,
historyApiFallback: true,
} as any);
const app = express();
app.use(server);
app.use(webpackHotMiddleware(compiler));
this.servers.push(app.listen(BASE_PORT + index));
index += 1;
}
const config = await this.getRendererConfig(this.config.renderer.entryPoints);
const compiler = webpack(config);
const server = webpackDevMiddleware(compiler, {
logger: {
log: tab.log.bind(tab),
info: tab.log.bind(tab),
error: tab.log.bind(tab),
warn: tab.log.bind(tab),
},
publicPath: '/',
hot: true,
historyApiFallback: true,
} as any);
const app = express();
app.use(server);
app.use(webpackHotMiddleware(compiler));
this.servers.push(app.listen(BASE_PORT));
});

await asyncOra('Compile Preload Scripts', async () => {
Expand Down

0 comments on commit 674c5f2

Please sign in to comment.