user1820686
user1820686

Reputation: 2117

Electron and TypeScript: 'fs' can't be resolved

I'm trying to create my first Electron app. I've decided to use following tools/technologies:

Local environment is OS X High Sierra.

The problem is that I can't even build my app and I get error on building with WebPack: "Module not found: Error: Can't resolve 'fs' in '<root>/node_modules/electron' "

I have configuration given below: package.json:

  "dependencies": {
    "electron": "^1.7.11"
  },
  "devDependencies": {
    "ts-loader": "^3.3.1",
    "tslint": "^5.9.1",
    "typescript": "^2.6.2",
    "webpack": "^3.10.0"
  }

tsconfig.json:

{
  "compileOnSave": false,
  "compilerOptions": {
    "allowJs": true,
    "jsx": "react",
    "moduleResolution": "node",
    "noImplicitAny": true,
    "outDir": "./dist/",
    "sourceMap": true,
    "target": "es2015"
  }
}

webpack.config.js:

const path = require('path');

module.exports = {
    entry: './src/index.ts',
    devtool: 'inline-source-map',
    module: {
        rules: [
            {
                test: /\.tsx?$/,
                use: 'ts-loader',
                exclude: /node_modules/
            }
        ]
    },
    // node: {
    //     'fs': 'empty'
    // },
    resolve: {
        extensions: [ '.tsx', '.ts', '.js' ]
    },
    output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'dist')
    }
};

Finally, my only source code file (./src/index.ts) taken from electron tutorial looks like:

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

let win: Electron.BrowserWindow;

function createWindow () {
    // ... common stuff
}

app.on('ready', createWindow);
app.on('window-all-closed', () => { if (process.platform !== 'darwin') { app.quit(); }});
app.on('activate', () => { if (win === null) { createWindow(); }});

I assume that the problem is in the way of TypeScript usage because if I put such code from index.ts to the plain js file, it works correctly (replacing 'import' with 'require').

Thanks for any help in advance!

Update

If set { target: 'node', } in webpack.config.js then there is no error on building step, but if I try to open app I get:

App threw an error during load
Error: Electron failed to install correctly, please delete node_modules/electron and try installing again

reinstalling of node modules doesn't help.

Upvotes: 29

Views: 38305

Answers (6)

Sathishkumar
Sathishkumar

Reputation: 3763

Sometimes adding nodeIntegration:true in webPreferences for mainWindow could solve the problem.

Upvotes: 0

Neil Palethorpe
Neil Palethorpe

Reputation: 389

Feel like I should add an additional answer for anyone who isn't helped by the other answers. I've spent a while attempting to update an older Electron project to new module builds whilst also implementing Typescript and I kept being hit by the:

[0] ERROR in ./node_modules/electron/index.js 1:11-24
[0] Module not found: Error: Can't resolve 'fs' in '<root_dir>/node_modules/electron'

and...

[0] ERROR in ./node_modules/electron/index.js 3:13-28
[0] Module not found: Error: Can't resolve 'path' in '<root_dir>/node_modules/electron'

After a lot of misery and a sh*t tonne of commenting out I finally found that the culprit was a require("electron") statement. I changed this to be window.require("electron") and it sprang to life!

So I hope that helps someone else (or future me)!

Upvotes: 3

user10120031
user10120031

Reputation: 31

try this

module.exports = {
  configureWebpack: {
    externals: {
      './cptable': 'var cptable'
    },
    resolve: {
      fallback: {
        'fs': false,
        'crypto': false
      }
    }
  },
}

Upvotes: 3

katinas
katinas

Reputation: 442

To add to the original answer. If you are using Electron + Next.js, you need to specify the target in next.config.js file. If you do not have one, create it on the root level of your app (where package.json is located). Add the following:

module.exports = {
  webpack: (config, { isServer }) => {
    if (!isServer) {
      config.target = "electron-renderer";
    }
    return config;
  },
};

Upvotes: 4

sadtaco
sadtaco

Reputation: 151

I came across this on a search and I'd offer an improve answer for dealing with errors that only happen on certain build targets:

const config = {
    //basic module.exports rules here
}

module.exports = [
    config,
    {
        ...config,
        target: 'web', //target that needs special rules, then all your other special config rules in this object
        node: {
            fs: 'empty'
        }
    }
]

Upvotes: 3

user1820686
user1820686

Reputation: 2117

Ok, finally I've found the solution worked for me. The 'target' option should be defined in webpack.config.js. And it shouldn't be { target: 'node' }, as I tried before

As it appears, Webpack has specific target settings for electron apps, therefore the correct way is to set it:

{
    // for files that should be compiled for electron main process
    target: 'electron-main'
}

or

{
    // for files that should be compiled for electron renderer process
    target: 'electron-renderer'
}

That's it. Just need to read docs carefully :- (

Upvotes: 50

Related Questions