0

Problem

I know that ES6 imports and NODE require() use static analysis and do not support dynamic paths. But how do we work around it? What's the solution?

My Electron app, during installation copies shortcuts.js file from development (project) folder [project_dir]/public/resources into the [app_installation_dir]/resources folder.

So the problem is:

  • In development the app should import ../public/resources/shortcuts.js
  • In production the app should import [app_installation_dir]/resources/shortcuts.js

I cannot specify the "non-dynamic" path for production since I don't know in advance what [app_installation_dir] path is going to be.

Code

I tried the following, but expectedly only the else brunch works:

const shortcuts = process.env.NODE_ENV === 'production'
  ? require(`${process.resourcesPath}/shortcuts.js`).data
  : require(../public/resources/shortcuts.js`).data

After installing the app, in production, I'm getting the error:

Uncaught Error: Cannot find module [app_installation_dir]/resources/shortcuts.js

since, I guess, require doesn't see the dynamic path as something it can import (I checked, the file exists at this path).

I then converted the file from module.exports to export default {} and tried the following ES6 method but I get the same error:

if (process.env.NODE_ENV === 'production') {
  const importPath = path.join(process.resourcesPath, 'shortcuts.js')
  import(importPath)
    .then((data) => {
      console.log('IMPORT DATA', data)
    })
}
else if (process.env.NODE_ENV === 'development') {
  import('../public/resources/shortcuts.js')
    .then((data) => {
      console.log('IMPORT DATA', data)
    })
}

babel.config.js

module.exports = {
  presets: [  
    '@vue/cli-plugin-babel/preset',
  ]
}

Project created

vue create app-name
> selected [babel, eslint]


vue add electron-builder
AlekseyHoffman
  • 2,438
  • 1
  • 8
  • 31
  • 1
    Does this answer your question? https://stackoverflow.com/a/46543835/10377254 – Jacob Feb 18 '20 at 11:56
  • @Jacob no, still the same error. I updated the question, showing what I did. Do I need to install some other babel preset for it to work? – AlekseyHoffman Feb 18 '20 at 12:10
  • @Rhayene thanks for the suggestion, but didn't help. I get the same error when I use `process.env.NODE_ENV === 'production'` – AlekseyHoffman Feb 18 '20 at 12:50
  • @Rhayene sorry, I don't udnerstand the question. I never used REPL. But even if it's a problem with node's `require`, I don't understand why the following ES6 method doesn't work either: `import(importPath).then((data) => {})`. As I mentioned I changed the way file exports the data from `module.exports` / `require` to `export default {}` / `import()` – AlekseyHoffman Feb 18 '20 at 13:13

1 Answers1

1

Interesting. I can't see why the require method would not work assuming the path is absolute. If shortcuts.js contained data that could be exported as plain JSON, maybe an idea I would try is convert that file into json and use the file system to read it and parse it.

import fs from 'fs'

const shortcuts = JSON.parse(process.env.NODE_ENV === 'production'
  ? fs.readFileSync(`${process.resourcesPath}/shortcuts.json`).toString())
  : fs.readFileSync(`../public/resources/shortcuts.js`).toString()).data
tin
  • 834
  • 6
  • 16
  • Yeah, I have no idea why it doesn't see it. I literally copy/paste the path from the error into the File Explorer and it opens the file. Maybe it's the way I export it? `shortcuts.js` looks like this `export default { shortcut1: {key1: 'value1'} }` – AlekseyHoffman Feb 18 '20 at 12:49
  • Thank you for the suggestion. I suppose I have no other choice than to use this method – AlekseyHoffman Feb 18 '20 at 12:53