Search code examples
javascriptelectron

Trying to import a variable from file but console say's file doesn't exist


when i try to import a variable from a JavaScript file into another one, my console return's an error that the file doesn't exist. Here is my file that is causing the problem my console log, and the file i want to import the variable in.

Button.js

var MONEY = 0;

const element = document.getElementById("moneyButton");

element.addEventListener("click", function moneyHandle() {
    MONEY++
    document.getElementById("moneycount").innerHTML = `You have: ` + MONEY + `$`;
});

module.exports = { MONEY };

Clicker.js

const { MONEY } = require('../misc/button')

const element = document.getElementById("clicker")

if (MONEY === 15) {
    console.log('User has enetered stage.')
    element.style.opacity = "1";
}

Console Log Console Log


Solution

  • By the looks of your code, all the logic is being conducted on the Electron render side.

    Whilst this is not a problem, it does introduce some issues such as how to regularly check for when MONEY === 15. To do this, you would need to use a function such as setInterval which will slow down this particular render process.

    As an alternative, keeping count of MONEY in your main process via the use of Inter-Process Communication would be the recommended way.

    That said, as your question is based around render side import and export functionality, we will stay in the render thread only and not introduce you to IPC.

    • Use of module.exports and require is CommonJS syntax, which is used by NodeJS (server-side).

    • Use of import and export is ECMAScript (ES module) syntax, which is used in browser-side Javascript.

    As your Javascript is render process (browser-side) Javascript, we must use the import and export statements.

    For additional explanation from the MDN Web Docs website:

    Import

    The static import declaration is used to import read-only live bindings which are exported by another module. The imported bindings are called live bindings because they are updated by the module that exported the binding, but cannot be re-assigned by the importing module.

    In order to use the import declaration in a source file, the file must be interpreted by the runtime as a module. In HTML, this is done by adding type="module" to the <script> tag. Modules are automatically interpreted in strict mode.

    Export

    The export declaration is used to export values from a JavaScript module. Exported values can then be imported into other programs with the import declaration or dynamic import. The value of an imported binding is subject to change in the module that exports it — when a module updates the value of a binding that it exports, the update will be visible in its imported value.

    In order to use the export declaration in a source file, the file must be interpreted by the runtime as a module. In HTML, this is done by adding type="module" to the <script> tag, or by being imported by another module. Modules are automatically interpreted in strict mode.


    NOTE: The below minimum reproducible example does not take into account your current directory structure. For simplicity, I have coded the below using a flat directory structure as folder hierarchy is not causing your current issue.


    index.html (render process)

    To get your current code working, we need to add the below lines of code to your index.html file.

    <script type="module" src="button.js"></script>
    <script type="module" src="clicker.js"></script>
    

    This allows the Javascript runtime to interpret these files as modules.

    <!DOCTYPE html>
    <html lang="en">
        <head>
            <meta charset="UTF-8">
            <title>Electron Test</title>
            <meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';"/>
        </head>
    
        <body>
            <input type="button" id="moneyButton" value="Show me the money">
    
            <p id="moneyCount">&nbsp;</p>
    
            <hr>
    
            <div id="clicker" style="border: 1px solid #000; padding: 1em; opacity: 0;">Clicker</div>
        </body>
    
        <script type="module" src="button.js"></script>
        <script type="module" src="clicker.js"></script>
    </html>
    

    button.js (render process)

    Next, we need to change module.exports = { MONEY }; to export {MONEY};

    let money = 0;
    
    document.getElementById("moneyButton").addEventListener("click", () => {
        money++;
        document.getElementById("moneyCount").innerHTML = 'You have: $' + money;
    });
    
    export {money};
    

    clicker.js (render process)

    Lastly, to import the live binding MONEY, let's change const { MONEY } = require('button') to import {money} from './button.js';.

    import {money} from './button.js';
    
    // setInterval used to regularly check for changes in the live binding variable 'money'
    setInterval(() => {
        if (money >= 15) {
            console.log('User has entered stage.')
            document.getElementById("clicker").style.opacity = "1";
        }
    }, 250); // Check every 250ms