saltyshiomix / nextron

⚡ Next.js + Electron ⚡
https://npm.im/nextron
MIT License
3.91k stars 226 forks source link

ModuleNotFoundError: Module not found: Error: Can't resolve 'fs' in node_modules/electron #78

Closed xxczaki closed 3 years ago

xxczaki commented 4 years ago

Description

When I try to build the app, a build error occurs:

> nextron build --all

[nextron] Clearing previous builds
[nextron] Building renderer process
Warning: You have enabled experimental feature(s).
Experimental features are not covered by semver, and may cause unexpected or broken application behavior. Use them at your own risk.

> Using external babel configuration
> Location: "/home/akepinski/dev/desktop/renderer/babel.config.js"

> Build error occurred
ModuleNotFoundError: Module not found: Error: Can't resolve 'fs' in '/home/akepinski/dev/desktop/node_modules/electron'
    at /home/akepinski/dev/desktop/node_modules/webpack/lib/Compilation.js:925:10
    at /home/akepinski/dev/desktop/node_modules/webpack/lib/NormalModuleFactory.js:401:22
    at /home/akepinski/dev/desktop/node_modules/webpack/lib/NormalModuleFactory.js:130:21
    at /home/akepinski/dev/desktop/node_modules/webpack/lib/NormalModuleFactory.js:224:22
    at /home/akepinski/dev/desktop/node_modules/neo-async/async.js:2830:7
    at /home/akepinski/dev/desktop/node_modules/neo-async/async.js:6877:13
    at /home/akepinski/dev/desktop/node_modules/webpack/lib/NormalModuleFactory.js:214:25
    at /home/akepinski/dev/desktop/node_modules/enhanced-resolve/lib/Resolver.js:213:14
    at /home/akepinski/dev/desktop/node_modules/enhanced-resolve/lib/Resolver.js:285:5
    at eval (eval at create (/home/akepinski/dev/desktop/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:13:1)
resolve 'fs' in '/home/akepinski/dev/desktop/node_modules/electron'
  Parsed request is a module
  using description file: /home/akepinski/dev/desktop/node_modules/electron/package.json (relative path: .)
    Field 'browser' doesn't contain a valid alias configuration
    resolve as module
      /home/akepinski/dev/desktop/node_modules/node_modules doesn't exist or is not a directory
      /home/akepinski/dev/node_modules doesn't exist or is not a directory
      /home/akepinski/node_modules doesn't exist or is not a directory
      /home/node_modules doesn't exist or is not a directory
      /node_modules doesn't exist or is not a directory
      looking for modules in /home/akepinski/dev/desktop/node_modules/electron/node_modules
        using description file: /home/akepinski/dev/desktop/node_modules/electron/package.json (relative path: ./node_modules)
          Field 'browser' doesn't contain a valid alias configuration
      looking for modules in /home/akepinski/dev/desktop/node_modules
        using description file: /home/akepinski/dev/desktop/package.json (relative path: ./node_modules)
          Field 'browser' doesn't contain a valid alias configuration
          using description file: /home/akepinski/dev/desktop/node_modules/electron/package.json (relative path: ./node_modules/fs)
            no extension
              Field 'browser' doesn't contain a valid alias configuration
          using description file: /home/akepinski/dev/desktop/package.json (relative path: ./node_modules/fs)
            no extension
              Field 'browser' doesn't contain a valid alias configuration
              /home/akepinski/dev/desktop/node_modules/electron/node_modules/fs doesn't exist
            .tsx
              Field 'browser' doesn't contain a valid alias configuration
              /home/akepinski/dev/desktop/node_modules/fs doesn't exist
            .tsx
              Field 'browser' doesn't contain a valid alias configuration
              /home/akepinski/dev/desktop/node_modules/electron/node_modules/fs.tsx doesn't exist
            .ts
              Field 'browser' doesn't contain a valid alias configuration
              /home/akepinski/dev/desktop/node_modules/fs.tsx doesn't exist
            .ts
              Field 'browser' doesn't contain a valid alias configuration
              /home/akepinski/dev/desktop/node_modules/electron/node_modules/fs.ts doesn't exist
            .mjs
              Field 'browser' doesn't contain a valid alias configuration
              /home/akepinski/dev/desktop/node_modules/fs.ts doesn't exist
            .mjs
              Field 'browser' doesn't contain a valid alias configuration
              /home/akepinski/dev/desktop/node_modules/electron/node_modules/fs.mjs doesn't exist
            .js
              Field 'browser' doesn't contain a valid alias configuration
              /home/akepinski/dev/desktop/node_modules/fs.mjs doesn't exist
            .js
              Field 'browser' doesn't contain a valid alias configuration
              /home/akepinski/dev/desktop/node_modules/electron/node_modules/fs.js doesn't exist
            .jsx
              Field 'browser' doesn't contain a valid alias configuration
              /home/akepinski/dev/desktop/node_modules/fs.js doesn't exist
            .jsx
              Field 'browser' doesn't contain a valid alias configuration
              /home/akepinski/dev/desktop/node_modules/electron/node_modules/fs.jsx doesn't exist
            .json
              Field 'browser' doesn't contain a valid alias configuration
              /home/akepinski/dev/desktop/node_modules/fs.jsx doesn't exist
            .json
              Field 'browser' doesn't contain a valid alias configuration
              /home/akepinski/dev/desktop/node_modules/electron/node_modules/fs.json doesn't exist
            .wasm
              Field 'browser' doesn't contain a valid alias configuration
              /home/akepinski/dev/desktop/node_modules/fs.json doesn't exist
            .wasm
              Field 'browser' doesn't contain a valid alias configuration
              /home/akepinski/dev/desktop/node_modules/electron/node_modules/fs.wasm doesn't exist
              /home/akepinski/dev/desktop/node_modules/fs.wasm doesn't exist
            as directory
              /home/akepinski/dev/desktop/node_modules/electron/node_modules/fs doesn't exist
            as directory
              /home/akepinski/dev/desktop/node_modules/fs doesn't exist
Creating an optimized production build .Warning: You have enabled experimental feature(s).
Experimental features are not covered by semver, and may cause unexpected or broken application behavior. Use them at your own risk.

> using build directory: /home/akepinski/dev/desktop/renderer/.next
Error: ENOENT: no such file or directory, open '/home/akepinski/dev/desktop/renderer/.next/BUILD_ID'
    at Object.openSync (fs.js:457:3)
    at readFileSync (fs.js:359:35)
    at _default (/home/akepinski/dev/desktop/node_modules/next/dist/export/index.js:1:3531) {
  errno: -2,
  syscall: 'open',
  code: 'ENOENT',
  path: '/home/akepinski/dev/desktop/renderer/.next/BUILD_ID'
}

Cannot build electron packages:
Error: ENOENT: no such file or directory, stat '/home/akepinski/dev/desktop/renderer/out'

Debug information

What I already tried

  1. Clearing npm cache, deleting .next and node_modules and reinstalling dependencies.
  2. Downgrading next to 9.3.0
  3. Deleting custom babel config:
    
    const presets = [
    ['next/babel', {
        'preset-env': {
            targets: {
                esmodules: true
            },
            corejs: 3,
            useBuiltIns: 'usage'
        }
    }]
    ];

const plugins = [ ['babel-plugin-styled-components', { ssr: true, pure: true }] ];

module.exports = {presets, plugins};

4. Removing experimental options from `next.config.js`:
```js
const withFonts = require('next-fonts');

module.exports = withFonts({
    webpack: config => Object.assign(config, {
        target: 'electron-renderer'
    }),
    reactStrictMode: true,
    experimental: {
        modern: true
    }
});

Nothing worked :cry:

lacymorrow commented 4 years ago

Are you using one of the examples? Is there a repo that I can clone?

xxczaki commented 4 years ago

@lacymorrow The app is based on the with-typescript example. Here is the repo: https://github.com/parsify-dev/desktop

xxczaki commented 4 years ago

@lacymorrow After I remove import {ipcRenderer} from 'electron'; everything works fine. Doing:

import electron from 'electron';

// Prevent SSR webpacking
const ipcRenderer = electron.ipcRenderer || false;

doesn't fix this issue.

lacymorrow commented 4 years ago

@xxczaki Can you try something like

import electron, { ipcRenderer } from 'electron'
if ( ipcRenderer ) {
    // ipcRenderer.on( key, fn )
}
xxczaki commented 4 years ago

@lacymorrow Unfortunately this does not fix the issue :cry:

lacymorrow commented 4 years ago

Are you able to build the with typescript example properly?

xxczaki commented 4 years ago

@lacymorrow Sorry for the late reply. Yes, I'm able to build it.

xxczaki commented 4 years ago

After removing all instances of ipcRenderer from the renderer directory, build finishes successfully.

xxczaki commented 4 years ago

Now the build succeeds, but electron is removed completely from it (so I can't use ipcRenderer) :cry:

Solved it. I modified the next.config.js:

    webpack: (config, {isServer}) => {
        if (!isServer) {
            config.module.rules.push({
                test: /electron/,
                use: "null-loader"
            })
        }

        return Object.assign(config, {target: 'electron-renderer'});
    },

Inspiration: https://github.com/zeit/next.js/issues/2069#issuecomment-593847441

That way, I make sure electron won't get bundled with the client. I don't know why it was doing so in my case.

lacymorrow commented 4 years ago

Is there an up-to-date repo I can take a look at? I'd like to get these imports figured out for folks in the future.

Glad you got a workaround in place!

xxczaki commented 4 years ago

I dug even more into this issue and I finally found a workaround, which makes the build succeed and also doesn't break the ipc communication:

// Instead of:
import {ipcRenderer} from 'electron';

// Do:
const {ipcRenderer} = eval('require(\'electron\')');

This was also inspired by one of the comments in Next.js' repo. This is just a workaround - as we all know the usage of eval is not really recommended, but it works.

@lacymorrow the repo itself is private, but I will try to make a separate repository for reproduction tomorrow :smile:

codewaseem commented 4 years ago

Any updates @xxczaki ?

xxczaki commented 4 years ago

Sorry for a late reply. Here is the repo: https://github.com/xxczaki/nextron-ipc-bug/

xxczaki commented 3 years ago

It looks like this issue does no longer occur with Nextron v6 and higher.