javascriptnode.jsmoduleelectronrequires

Electron -- requiring module in Chromium script


I'm trying to work on an Electron app and have been having a problem with trying to require a module from another script running within the Chromium browser window. No matter what I do to specify the relative path, I'm always coming across the same error about being unable to find a module.

My project is set up like this:

    index.html
    scripts
        controllers
            controller.js
        models
            game.js
        tests
            spec
                gameSpec.js

My index.html, which is the page brought up by default when electron launches, loads controller.js as a normal script at the end of the body tag.

<script src="scripts/controllers/controller.js"></script>

controller.js has the following code at the top:

var Game = require("../models/game.js");
.... some other code .....
var game = new Game();

Upon launching the electron Chromium window, I instantly run into this problem:

Uncaught Error: Cannot find module '../models/game.js'

My assumption is that I need a relative path from the controller.js file to the game.js file that it is importing, but no matter what kind of tweaking I do I'm always getting that error. I don't think it's a mere syntax error since I have the spec under the tests folder all running and passing which successfully uses a require like this:

var Game = require("../../models/game.js");
describe("Game", function () { ... });

Am I making an incorrect assumption about how require relative pathing is done when executed from the Chromium browser? Any help is appreciated!


Solution

  • Perhaps more of a workaround than an answer, but if you swap your script inclusion from this:

    <script src="scripts/controllers/controller.js"></script>
    

    To this:

    <script>require('./scripts/controllers/controller.js')</script>
    

    Then the relative paths should work as you are expecting.


    I think that when you include scripts with the src attribute, then the internal context of the current working directory in that file is the root of the application.

    Why? I'm not 100% sure, to be honest. Limitation on how the files have to be loaded when included as script src? If you really want to continue using the src attribute, these would technically work in controller.js.

    var Game = require(__dirname + '/scripts/models/game.js');
    // or
    var Game = require('./scripts/models/game.js');
    

    I can't whole-heartedly suggest either of those options, though. Seems fragile.

    To be honest, I've never even noticed this before, because I typically include a javascript "entry" point to my application in the same location as my index.html.