diego3g / electron-typescript-react

:electron: An Electron boilerplate including TypeScript, React, Jest and ESLint.
1.45k stars 295 forks source link

a suggestion for "require is not defind" #57

Open terralian opened 3 years ago

terralian commented 3 years ago

rules.webpack.js has a problem:

if some module use typeof require to check require is define or not

the boilerplate default webpack rule config will change it , like:

var u = typeof require && require
// compile
var u = true && require

so it will cause a error when app build: ReferenceError: require is not defined

you can change this code in rules.webpack.js below and solve this problem at line 7

- test: /\.(m?js|node)$/,
+ test: /\.(node)$/,

I don't know why, but it‘s useful

A sample:

  1. download the package

  2. yarn add exceljs

  3. use exceljs in App.tsx like

    + import Excel from 'exceljs'
    
    export function App() {
    +  const workbook = new Excel.Workbook()
  4. yarn start, then it's broken

  5. change your rules.webpack.js and restart, back to normal.

timmychan97 commented 2 years ago

I spent a day debugging the error require is not defined. I did not even use require in the renderer.

The culprit is @marshallofsound/webpack-asset-relocator-loader (or @versel/webpack-asset-relocator-loader or @timfish/webpack-asset-relocator-loader ) which adds support for locating node_modules in renderer. According to the current convention, renderer thread should not have access to native node modules. nodeIntegration: false is set by default. (also contextIsolation: true).

If you keep using ipcMain and ipcRenderer for communication, and don't require any modules in renderer, you will have to remove the loader. There error will persist even if you don't require any modules in renderer. This is because the loaders themselves include the __dirname (or require()) into your renderer.

We have two different solutions:

  1. Keep using ipcMain and ipcRenderer for communication in the app, and edit the /webpack/rules.webpack.js and remove the following lines. And create a new rules.webpack.js file for main only, with this loader.

    {
    test: /\.(m?js|node)$/,
    parser: { amd: false },
    use: {
      loader: '@marshallofsound/webpack-asset-relocator-loader',
      options: {
        outputAssetBase: 'native_modules',
      },
    },
    },
  2. Set nodeIntegration: true and contextIsolation: false. You can no longer use ipcMain and ipcRenderer. Doing this will also make the app less secure, as the renderer could be utilize to perform malicious operations on the computer.