Once I set nodeIntegration:false -> “Uncaught ReferenceError: require is not defined at Object.url (external ”url“:1) ” Electron-React-Typescript

Once I set nodeIntegration:false I get this error:
"Uncaught ReferenceError: require is not defined at Object.url (external “url”:1) "

Clicking on “external ‘url’: 1” I get this line of code: module.exports = require(“url”)

tsconfig.json :

{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "lib": [
      "dom",
      "es2015",
      "es2016",
      "es2017"
    ],
    "allowJs": true,
    "jsx": "react",
    "sourceMap": true,
    "outDir": "./dist",
    "strict": true ,
    "esModuleInterop": true,
  }
}

webpack.electron.config.js :

const path = require("path");
module.exports = {
  resolve: {
    extensions: [".tsx", ".ts", ".js"],
  },
  devtool: "source-map",
  entry: "./electron/src/main.ts",
  target: "electron-main",
  module: {
    rules: [
      {
        test: /\.(js|ts|tsx)$/,
        exclude: /node_modules/,
        use: {
          loader: "babel-loader",
        },
      },
    ],
  },
  node: {
    __dirname: false,
  },
  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "[name].js",
  },
};

webpack.react.config.js :

const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");

module.exports = {
  resolve: {
    extensions: [".tsx", ".ts", ".js"],
    mainFields: ["main", "module", "browser"],
  },
  entry: "./electron/src/app.tsx",
  target: "electron-renderer",
  devtool: "source-map",
  module: {
    rules: [
      {
        test: /\.(js|ts|tsx)$/,
        exclude: /node_modules/,
        use: {
          loader: "babel-loader",
        },
      },
    ],
  },
  devServer: {
    contentBase: path.join(__dirname, "../dist/renderer"),
    historyApiFallback: true,
    compress: true,
    hot: true,
    port: 4000,
    publicPath: "/",
  },
  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "js/[name].js",
  },
  plugins: [new HtmlWebpackPlugin()],
};

/electron/src/main.ts :

import { app, BrowserWindow } from "electron";
import * as path from "path";
import * as url from "url";

let mainWindow: Electron.BrowserWindow | null;

function createWindow() {
  mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      nodeIntegration: false,
      contextIsolation: true,
      preload: '../preload/preload-app.ts',
      worldSafeExecuteJavaScript: true
    },
  });

  if (process.env.NODE_ENV === "development") {
    mainWindow.loadURL(`http://localhost:4000`);
    mainWindow.webContents.openDevTools();
  } else {
    mainWindow.loadURL(
      url.format({
        pathname: path.join(__dirname, "index.html"),
        protocol: "file:",
        slashes: true,
      })
    );
  }

  mainWindow.on("closed", () => {
    mainWindow = null;
  });
}

app.on("ready", createWindow);
app.allowRendererProcessReuse = true;

/src/preload/preload-app.ts :

window.addEventListener('DOMContentLoaded', () => {
  const replaceText = (selector, text) => {
    const element = document.getElementById(selector)
    if (element) element.innerText = text
  }

  for (const type of ['chrome', 'node', 'electron']) {
    replaceText(`${type}-version`, process.versions[type])
  }
})
  • node version: v.14.5.0
  • electron version: 10.1.3
  • webpack version: 4.44.2
  • webpack-cli version: 3.3.12
  • webpack-dev-server version: 3.11.0
  • react version: 16.13.1
  • typescript version: 4.0.3
  • OS: Ubuntu 18.04.4 Desktop

How to solve the problem, while keeping nodeIntegration:false + contextIsolation:true for strict security reasons?

If you disable node integration you can’t use any electron/node in your render process (browser window). As your code for displaying your app in the browser window uses a load of electron/node stuff it won’t work.

I solved. Keeping nodeIntegration:false