Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(webpack-plugin): upgrade to Webpack 5 #2225

Merged
merged 21 commits into from
May 21, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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"
malept marked this conversation as resolved.
Show resolved Hide resolved
},
"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