Skip to content

Commit

Permalink
feat!(webpack-plugin): upgrade to Webpack 5 (#2225)
Browse files Browse the repository at this point in the history
* refactor(plugin-webpack): change express to webpack-dev-server

Remove express/webpack-hot-middleware/webpack-dev-middleware for a simple webpack-dev-server

* chore: bump minimum version of node to 12 in line with webpack-dev-server

BREAKING CHANGE: Drop support for Node < 12.

* test: fast tests can no longer be run in parallel

For some reason the tests keep failing with the following error:

```
  1) Uncaught error outside test suite:
     Uncaught Workerpool Worker terminated Unexpectedly
    exitCode: `0`
    signalCode: `null`
    workerpool.script: `electron-forge/node_modules/mocha/lib/nodejs/worker.js`
    spawnArgs: `electron-forge/node_modules/mocha/lib/nodejs/worker.js`
    spawnfile: `/usr/bin/node`
    stdout: `null`
    stderr: `null`
```

Co-authored-by: Mark Lee <malept@users.noreply.github.com>
  • Loading branch information
YvanGuidoin and malept authored May 21, 2021
1 parent 4dc66df commit 564a445
Show file tree
Hide file tree
Showing 11 changed files with 975 additions and 1,204 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,10 @@ jobs:
- name: Fix git checkout line endings
run: git config --global core.autocrlf input
- uses: actions/checkout@v2.3.4
- name: Use Node.js 10.x
- name: Use Node.js 12.x
uses: actions/setup-node@v2.1.5
with:
node-version: 10.x
node-version: 12.x
- name: Determine Yarn cache
id: yarn-cache
run: echo "::set-output name=dir::$(yarn cache dir)"
Expand Down Expand Up @@ -93,10 +93,10 @@ jobs:
sudo apt-get update
sudo apt-get install -y --no-install-recommends snapcraft flatpak-builder elfutils
ci/install_runtimes.sh
- name: Use Node.js 10.x
- name: Use Node.js 12.x
uses: actions/setup-node@v2.1.5
with:
node-version: 10.x
node-version: 12.x
- name: Determine Yarn cache
id: yarn-cache
run: echo "::set-output name=dir::$(yarn cache dir)"
Expand Down
19 changes: 8 additions & 11 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
"version": "6.0.0-beta.55",
"private": true,
"license": "MIT",
"engines": {
"node": ">= 12.0.0"
},
"bolt": {
"workspaces": [
"packages/api/*",
Expand All @@ -21,7 +24,7 @@
"build:quick": "bolt ws exec -- node_modules/.bin/babel src -d dist --quiet --extensions \".ts\" --config-file ../../../.babelrc",
"postbuild": "ts-node tools/test-dist",
"commit": "git-cz",
"coverage:fast": "cross-env INTEGRATION_TESTS=0 TS_NODE_FILES=true nyc mocha --parallel './tools/test-globber.ts' && nyc report --reporter=text-lcov > coverage.lcov",
"coverage:fast": "cross-env INTEGRATION_TESTS=0 TS_NODE_FILES=true nyc mocha './tools/test-globber.ts' && nyc report --reporter=text-lcov > coverage.lcov",
"coverage:slow": "cross-env TS_NODE_FILES=true nyc mocha './tools/test-globber.ts' --integration && nyc report --reporter=text-lcov > coverage.lcov",
"docs": "bolt docs:generate && bolt docs:position",
"docs:generate": "bolt ws exec -- node_modules/.bin/typedoc --out doc --excludeExternals --ignoreCompilerErrors --mode file --excludePrivate --excludeProtected --hideGenerator",
Expand All @@ -30,7 +33,7 @@
"docs:deploy:ci": "ts-node tools/sync-readmes.ts && bolt docs && ts-node tools/copy-now.ts && cd docs && now --token $NOW_TOKEN && now alias --token $NOW_TOKEN",
"lint": "eslint --ext .ts .",
"test": "cross-env TS_NODE_FILES=true yarn run mocha './tools/test-globber.ts'",
"test:fast": "cross-env TEST_FAST_ONLY=1 TS_NODE_FILES=true yarn run mocha --parallel './tools/test-globber.ts'",
"test:fast": "cross-env TEST_FAST_ONLY=1 TS_NODE_FILES=true yarn run mocha './tools/test-globber.ts'",
"postinstall": "rimraf node_modules/.bin/*.ps1 && ts-node tools/link-ts.ts"
},
"dependencies": {
Expand All @@ -57,7 +60,7 @@
"fs-extra": "^9.0.1",
"glob": "^7.1.5",
"global": "^4.3.2",
"html-webpack-plugin": "^4.4.1",
"html-webpack-plugin": "^5.3.1",
"inquirer": "^8.0.0",
"lodash": "^4.17.20",
"log-symbols": "^4.0.0",
Expand All @@ -73,9 +76,8 @@
"source-map-support": "^0.5.13",
"sudo-prompt": "^9.1.1",
"username": "^5.1.0",
"webpack": "^4.44.2",
"webpack-dev-middleware": "^4.0.2",
"webpack-hot-middleware": "^2.25.0",
"webpack": "^5.37.0",
"webpack-dev-server": "^4.0.0-beta.3",
"webpack-merge": "^5.7.3",
"which": "^2.0.2",
"xterm": "^4.9.0",
Expand All @@ -100,7 +102,6 @@
"@types/fetch-mock": "^7.3.1",
"@types/fs-extra": "^9.0.6",
"@types/glob": "^7.1.3",
"@types/html-minifier-terser": "^5.0.0",
"@types/inquirer": "^7.3.0",
"@types/listr": "^0.14.2",
"@types/lodash": "^4.14.166",
Expand All @@ -114,10 +115,6 @@
"@types/sinon": "^10.0.0",
"@types/sinon-chai": "^3.2.5",
"@types/username": "^5.0.0",
"@types/webpack": "^4.41.21",
"@types/webpack-dev-middleware": "^4.1.0",
"@types/webpack-hot-middleware": "^2.25.0",
"@types/webpack-merge": "^5.0.0",
"@typescript-eslint/eslint-plugin": "^4.11.0",
"@typescript-eslint/parser": "^4.11.0",
"babel-plugin-source-map-support": "^2.1.2",
Expand Down
13 changes: 6 additions & 7 deletions packages/plugin/webpack/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,24 +13,23 @@
"devDependencies": {
"@types/node": "^15.3.0",
"chai": "^4.3.3",
"mocha": "^8.1.3"
"mocha": "^8.1.3",
"sinon": "^10.0.0"
},
"engines": {
"node": ">= 10.0.0"
"node": ">= 12.0.0"
},
"dependencies": {
"@electron-forge/async-ora": "6.0.0-beta.55",
"@electron-forge/plugin-base": "6.0.0-beta.55",
"@electron-forge/shared-types": "6.0.0-beta.55",
"@electron-forge/web-multi-logger": "6.0.0-beta.55",
"debug": "^4.3.1",
"express": "^4.17.1",
"fs-extra": "^9.0.1",
"global": "^4.3.2",
"html-webpack-plugin": "^4.4.1",
"webpack": "^4.44.2",
"webpack-dev-middleware": "^4.0.2",
"webpack-hot-middleware": "^2.25.0",
"html-webpack-plugin": "^5.3.1",
"webpack": "^5.37.0",
"webpack-dev-server": "^4.0.0-beta.3",
"webpack-merge": "^5.7.3"
}
}
17 changes: 9 additions & 8 deletions packages/plugin/webpack/src/WebpackConfig.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import debug from 'debug';
import HtmlWebpackPlugin from 'html-webpack-plugin';
import path from 'path';
import webpack, { Configuration } from 'webpack';
import webpack, { Configuration, WebpackPluginInstance } from 'webpack';
import { merge as webpackMerge } from 'webpack-merge';

import { WebpackPluginConfig, WebpackPluginEntryPoint, WebpackPreloadEntryPoint } from './Config';

type EntryType = string | string[] | Record<string, string | string[]>;
Expand Down Expand Up @@ -121,6 +120,10 @@ export default class WebpackConfigGenerator {
return defines;
}

sourceMapOption() {
return this.isProd ? 'source-map' : 'eval-source-map';
}

getMainConfig() {
const mainConfig = this.resolveConfig(this.pluginConfig.mainConfig);

Expand Down Expand Up @@ -174,7 +177,7 @@ export default class WebpackConfigGenerator {
const prefixedEntries = entryPoint.prefixedEntries || [];

return webpackMerge({
devtool: 'inline-source-map',
devtool: this.sourceMapOption(),
mode: this.mode,
entry: prefixedEntries.concat([
entryPoint.js,
Expand All @@ -198,8 +201,7 @@ export default class WebpackConfigGenerator {
for (const entryPoint of entryPoints) {
const prefixedEntries = entryPoint.prefixedEntries || [];
entry[entryPoint.name] = prefixedEntries
.concat([entryPoint.js])
.concat(this.isProd || !entryPoint.html ? [] : ['webpack-hot-middleware/client']);
.concat([entryPoint.js]);
}

const defines = this.getDefines(false);
Expand All @@ -209,11 +211,10 @@ export default class WebpackConfigGenerator {
template: entryPoint.html,
filename: `${entryPoint.name}/index.html`,
chunks: [entryPoint.name].concat(entryPoint.additionalChunks || []),
}) as webpack.Plugin).concat([new webpack.DefinePlugin(defines)])
.concat(this.isProd ? [] : [new webpack.HotModuleReplacementPlugin()]);
}) as WebpackPluginInstance).concat([new webpack.DefinePlugin(defines)]);
return webpackMerge({
entry,
devtool: 'inline-source-map',
devtool: this.sourceMapOption(),
target: 'electron-renderer',
mode: this.mode,
output: {
Expand Down
78 changes: 39 additions & 39 deletions packages/plugin/webpack/src/WebpackPlugin.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,26 @@
/* eslint "no-console": "off" */
import { asyncOra } from '@electron-forge/async-ora';
import debug from 'debug';
import PluginBase from '@electron-forge/plugin-base';
import { ElectronProcess, ForgeConfig } from '@electron-forge/shared-types';
import express from 'express';
import Logger, { Tab } from '@electron-forge/web-multi-logger';
import debug from 'debug';
import fs from 'fs-extra';
import http from 'http';
import Logger, { Tab } from '@electron-forge/web-multi-logger';
import path from 'path';
import PluginBase from '@electron-forge/plugin-base';
import webpack, { Configuration } from 'webpack';
import webpackDevMiddleware from 'webpack-dev-middleware';
import webpackHotMiddleware from 'webpack-hot-middleware';

import once from './util/once';
import webpack, { Configuration, Watching } from 'webpack';
import WebpackDevServer from 'webpack-dev-server';
import { WebpackPluginConfig } from './Config';
import ElectronForgeLoggingPlugin from './util/ElectronForgeLogging';
import once from './util/once';
import WebpackConfigGenerator from './WebpackConfig';

const d = debug('electron-forge:plugin:webpack');
const DEFAULT_PORT = 3000;
const DEFAULT_LOGGER_PORT = 9000;

type WebpackToJsonOptions = Parameters<webpack.Stats['toJson']>[0];
type WebpackWatchHandler = Parameters<webpack.Compiler['watch']>[1];

export default class WebpackPlugin extends PluginBase<WebpackPluginConfig> {
name = 'webpack';

Expand All @@ -31,7 +32,7 @@ export default class WebpackPlugin extends PluginBase<WebpackPluginConfig> {

private _configGenerator!: WebpackConfigGenerator;

private watchers: webpack.Compiler.Watching[] = [];
private watchers: Watching[] = [];

private servers: http.Server[] = [];

Expand Down Expand Up @@ -69,7 +70,7 @@ export default class WebpackPlugin extends PluginBase<WebpackPluginConfig> {
}
}

private exitHandler = (options: { cleanup?: boolean; exit?: boolean }, err?: Error) => {
exitHandler = (options: { cleanup?: boolean; exit?: boolean }, err?: Error) => {
d('handling process exit with:', options);
if (options.cleanup) {
for (const watcher of this.watchers) {
Expand All @@ -94,21 +95,22 @@ export default class WebpackPlugin extends PluginBase<WebpackPluginConfig> {

async writeJSONStats(
type: string,
stats: webpack.Stats,
statsOptions?: webpack.Stats.ToStringOptions,
stats: webpack.Stats | undefined,
statsOptions: WebpackToJsonOptions,
): Promise<void> {
if (!stats) return;
d(`Writing JSON stats for ${type} config`);
const jsonStats = stats.toJson(statsOptions as webpack.Stats.ToJsonOptions);
const jsonStats = stats.toJson(statsOptions);
const jsonStatsFilename = path.resolve(this.baseDir, type, 'stats.json');
await fs.writeJson(jsonStatsFilename, jsonStats, { spaces: 2 });
}

// eslint-disable-next-line max-len
private runWebpack = async (options: Configuration, isRenderer = false): Promise<webpack.Stats> => new Promise((resolve, reject) => {
private runWebpack = async (options: Configuration, isRenderer = false): Promise<webpack.Stats | undefined> => new Promise((resolve, reject) => {
webpack(options)
.run(async (err, stats) => {
if (isRenderer && this.config.renderer.jsonStats) {
await this.writeJSONStats('renderer', stats, options.stats);
await this.writeJSONStats('renderer', stats, options.stats as WebpackToJsonOptions);
}
if (err) {
return reject(err);
Expand All @@ -133,7 +135,7 @@ export default class WebpackPlugin extends PluginBase<WebpackPluginConfig> {
get configGenerator() {
// eslint-disable-next-line no-underscore-dangle
if (!this._configGenerator) {
// eslint-disable-next-line no-underscore-dangle
// eslint-disable-next-line no-underscore-dangle
this._configGenerator = new WebpackConfigGenerator(
this.config,
this.projectDir,
Expand Down Expand Up @@ -235,22 +237,22 @@ Your packaged app may be larger than expected if you dont ignore everything othe
await new Promise((resolve, reject) => {
const compiler = webpack(mainConfig);
const [onceResolve, onceReject] = once(resolve, reject);
const cb: webpack.ICompiler.Handler = async (err, stats: webpack.Stats) => {
const cb: WebpackWatchHandler = async (err, stats) => {
if (tab && stats) {
tab.log(stats.toString({
colors: true,
}));
}
if (this.config.jsonStats) {
await this.writeJSONStats('main', stats, mainConfig.stats);
await this.writeJSONStats('main', stats, mainConfig.stats as WebpackToJsonOptions);
}

if (err) return onceReject(err);
if (!watch && stats.hasErrors()) {
if (!watch && stats?.hasErrors()) {
return onceReject(new Error(`Compilation errors in the main process: ${stats.toString()}`));
}

return onceResolve();
return onceResolve(undefined);
};
if (watch) {
this.watchers.push(compiler.watch({}, cb));
Expand All @@ -261,13 +263,13 @@ Your packaged app may be larger than expected if you dont ignore everything othe
});
}

compileRenderers = async (watch = false) => { // eslint-disable-line @typescript-eslint/no-unused-vars, max-len
compileRenderers = async (watch = false) => {
await asyncOra('Compiling Renderer Template', async () => {
const stats = await this.runWebpack(
await this.configGenerator.getRendererConfig(this.config.renderer.entryPoints),
true,
);
if (!watch && stats.hasErrors()) {
if (!watch && stats?.hasErrors()) {
throw new Error(`Compilation errors in the renderer: ${stats.toString()}`);
}
});
Expand All @@ -286,26 +288,24 @@ Your packaged app may be larger than expected if you dont ignore everything othe
launchDevServers = async (logger: Logger) => {
await asyncOra('Launch Dev Servers', async () => {
const tab = logger.createTab('Renderers');
const pluginLogs = new ElectronForgeLoggingPlugin(tab);

const config = await this.configGenerator.getRendererConfig(this.config.renderer.entryPoints);
if (!config.plugins) config.plugins = [];
config.plugins.push(pluginLogs);
const compiler = webpack(config);
const server = webpackDevMiddleware(compiler, {
logger: {
debug: tab.log.bind(tab),
log: tab.log.bind(tab),
info: tab.log.bind(tab),
error: tab.log.bind(tab),
warn: tab.log.bind(tab),
},
publicPath: '/',
const webpackDevServer = new WebpackDevServer(compiler, {
hot: true,
port: this.port,
static: path.resolve(this.baseDir, 'renderer'),
devMiddleware: {
writeToDisk: true,
},
setupExitSignals: true,
historyApiFallback: true,
writeToDisk: true,
} as any);
const app = express();
app.use(server);
app.use(webpackHotMiddleware(compiler));
this.servers.push(app.listen(this.port));
});
const server = await webpackDevServer.listen(this.port);
this.servers.push(server);
});

await asyncOra('Compiling Preload Scripts', async () => {
Expand All @@ -327,7 +327,7 @@ Your packaged app may be larger than expected if you dont ignore everything othe
}

if (err) return onceReject(err);
return onceResolve();
return onceResolve(undefined);
}));
});
}
Expand Down
Loading

0 comments on commit 564a445

Please sign in to comment.