Skip to content

Instantly share code, notes, and snippets.

@mikerourke
Last active October 27, 2020 20:26
Show Gist options
  • Save mikerourke/fd07e14344debb654e53be442c9c311f to your computer and use it in GitHub Desktop.
Save mikerourke/fd07e14344debb654e53be442c9c311f to your computer and use it in GitHub Desktop.
Reference webpack configuration for an Electron application that uses TypeScript.
{
"name": "some-name",
"productName": "The Product",
"version": "1.0.0",
"main": "src/main/main.ts",
"author": "Biscuits O'Shea",
"license": "PRIVATE",
"private": true,
"scripts": {
"build": "webpack --mode production --progress",
"start": "webpack-dev-server --port 4000 --mode development"
},
"devDependencies": {
"@babel/core": "^7.11.6",
"@babel/plugin-proposal-class-properties": "^7.10.4",
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.10.4",
"@babel/plugin-proposal-optional-chaining": "^7.11.0",
"@babel/preset-env": "^7.11.5",
"@babel/preset-typescript": "^7.10.4",
"@babel/register": "^7.11.5",
"@tsconfig/svelte": "^1.0.10",
"babel-loader": "^8.1.0",
"babel-register-ts": "^7.0.0",
"cross-env": "^7.0.2",
"css-loader": "^4.3.0",
"electron-nightly": "^12.0.0-nightly.20200903",
"file-loader": "^6.1.0",
"html-webpack-plugin": "^4.5.0",
"monaco-editor-webpack-plugin": "^2.0.0",
"native-ext-loader": "^2.3.0",
"node-addon-api": "^3.0.2",
"style-loader": "^1.3.0",
"svelte": "^3.24.1",
"svelte-check": "^1.0.31",
"svelte-loader": "^2.13.6",
"svelte-preprocess": "^4.2.0",
"typescript": "^4.1.0-beta",
"webpack": "^4.44.2",
"webpack-cli": "^3.3.12",
"webpack-dev-server": "^3.11.0",
"worker-loader": "^3.0.3"
},
"dependencies": {
"monaco-editor": "^0.21.2"
}
}
const { spawn } = require("child_process");
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MonacoWebpackPlugin = require("monaco-editor-webpack-plugin");
const outputPath = path.join(__dirname, "out", "build");
const isDevelopment = (argv) => argv.mode === "development";
const createCommonConfig = (env, argv) => ({
devtool: isDevelopment(argv) ? "inline-source-map" : false,
mode: argv.mode,
module: {
rules: [
{
test: /\.[jt]s?$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
options: {
cacheDirectory: true,
},
},
},
],
},
output: {
filename: "[name].js",
path: outputPath,
},
resolve: {
extensions: [".mjs", ".js", ".ts"],
},
stats: {
all: false,
modules: false,
maxModules: 0,
errors: true,
warnings: true,
moduleTrace: false,
errorDetails: true,
chunks: true,
},
});
const createRendererConfig = (env, argv) => {
const commonConfig = createCommonConfig(env, argv);
return {
...commonConfig,
target: "electron-renderer",
entry: {
renderer: path.join(__dirname, "src", "renderer", "index.ts"),
},
module: {
...commonConfig.module,
rules: [
{
test: /\.worker\.[jt]s?$/,
exclude: /node_modules/,
use: {
loader: "worker-loader",
options: {
filename: "[name].js",
},
},
},
...commonConfig.module.rules,
{
test: /\.svelte$/,
exclude: /node_modules/,
use: {
loader: "svelte-loader",
options: {
emitCss: true,
hotReload: isDevelopment(argv),
preprocess: require("svelte-preprocess")({}),
onwarn: (warning, handleWarning) => {
// Disables the A11y: on:blur must be used instead of on:change,
// unless absolutely necessary and it causes no negative consequences
// for keyboard only or screen reader users error. Everywhere
// we explicitly specify an on change event will behave as
// expected for screen readers and won't cause any issues.
if (warning.code === "a11y-no-onchange") {
return;
}
// process as usual:
handleWarning(warning);
},
},
},
},
{
test: /\.css$/,
use: ["style-loader", "css-loader"],
},
{
test: /\.node$/,
use: ["native-ext-loader"],
},
{
test: /\.(png|jp(e)g|gif|svg)$/i,
use: {
loader: "url-loader",
options: {
limit: 8192,
},
},
},
{
test: /\.(woff(2)?|ttf|eot)$/,
use: ["file-loader"],
},
],
},
resolve: {
alias: {
svelte: path.resolve("node_modules", "svelte"),
},
mainFields: ["svelte", "browser", "module", "main"],
extensions: [...commonConfig.resolve.extensions, ".svelte"],
},
plugins: [
new HtmlWebpackPlugin({
filename: "index.html",
template: path.join(__dirname, "src", "renderer", "index.html"),
}),
new MonacoWebpackPlugin({ languages: [] }),
],
// When exporting multiple configurations only the devServer options for
// the first configuration will be taken into account and used for all the
// configurations in the array.
// @see https://v4.webpack.js.org/configuration/dev-server/
devServer: {
compress: true,
before() {
console.log("Starting main process...");
spawn("npx", ["electron", "-r", "babel-register-ts", "."], {
shell: true,
env: {
...process.env,
NODE_ENV: "development",
ELECTRON_DISABLE_SECURITY_WARNINGS: true,
},
stdio: ["inherit", "inherit", "inherit"],
})
.on("close", (code) => {
process.exit(code);
})
.on("error", (spawnError) => {
console.error(spawnError);
});
},
},
};
};
const createMainConfig = (env, argv) => ({
...createCommonConfig(env, argv),
target: "electron-main",
entry: {
main: path.join(__dirname, "src", "main", "main.ts"),
},
});
module.exports = (env, argv) => {
// Used in `/src/main/main.ts` for hot-module reloading:
if (argv.mode === "development") {
process.env.OCHO_PORT = argv.port || 4000;
}
const rendererConfig = createRendererConfig(env, argv);
const mainConfig = createMainConfig(env, argv);
return [rendererConfig, mainConfig];
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment