1

I have a server.js file that includes the module puppeteer.

const puppeteer = require('puppeteer');

I want to run a function inside routes.js that uses that module.

async function getPic(arg) {
    const browser = await puppeteer.launch(/*{headless: false}*/);
    const page = await browser.newPage();
    await page.goto(arg);
    await page.setViewport({width: 1000, height: 500})
    await page.screenshot({path: 'pic.png'});

    await broswer.close();
}

When i attempt to run this then it doesn't work because "puppeteer is not defined".

So what is the most optimal way to solve this? Obvisouly i cannot reinclude the puppeteer module in routes.js So do i include the server.js file in routes.js? Or this might cause modules and variables and functions to be instantiated twice? (one time when server.js ran - as it is the starting point, and one time when routes.js ran and reruns server.js)

user1584421
  • 3,499
  • 11
  • 46
  • 86
  • 3
    *“Obvisouly i cannot reinclude the puppeteer module in routes.js”* You can, and that’s the correct way to do it. – Ry- Apr 18 '18 at 14:07
  • `puppeteer`, if it's a reasonably-designed module, ought to be able to be `require`d from multiple files. The only risk here would be if the module, upon being `require`d, did something with side-effects, which a reasonable module wouldn't. – Ahmed Fasih Apr 18 '18 at 14:09
  • 1
    @AhmedFasih - what do you mean by "reasonable module"? The require is always done only once, no matter what you write inside. – libik Apr 18 '18 at 14:14
  • I meant, if puppeteer is a module you found on npmjs ([which it is](https://www.npmjs.com/package/puppeteer)), it will be designed to be `require`'d from multiple places in your application, so go right ahead and `require` it in routes.js and server.js both, like @Ry said. – Ahmed Fasih Apr 18 '18 at 14:16
  • @AhmedFasih - I am more interested about how can you write module that is not designed to be required from multiple places? You have no control about how Node.js is handling the require. Every module (basically every file) can be required from multiple places, noa matter what you write inside. – libik Apr 18 '18 at 14:18
  • @libik, aha, you have taught me something new about Node! I thought if you `require`'d a module that did something like `fs.writeFileSync('example.txt', Math.random())` in multiple parts of your app, then the file would be overwritten multiple times but that's not happening—as you say, Node loads it into memory only once and the file is written only once. Thank you! (Note, this is different than how Python `import`s work :P!) – Ahmed Fasih Apr 18 '18 at 14:23

1 Answers1

4

Write const puppeteer = require('puppeteer'); inside routes.js, this is how Node.js work. Every single module is behaving like singleton, it is executed on first require and then saved into memory. Next require just returns the pointer to this memory (so requiring puppeteer from server.js and routes.js will point to the same object).

libik
  • 22,239
  • 9
  • 44
  • 87
  • Thanks! But aside from simply including a module... If you want to do some configuration on the module you included... Is it advisable to do so in the first require as well? Or you do it on the .js file, on which this module will come into play? – user1584421 May 10 '18 at 14:43
  • @user1584421 - I have folder "components" for modules that needs some init and configuration. So in that components folder, I have folder with name like "myMongoose", which require mongoose, set it up and it also returns the original (and configured) mongoose module. In rest of the application, I am requiring "myMongoose", which guarantee me it has right configurations and also it allows me to Mock the components easily (just based on some config I can return mongoose or I can return mock that looks like mongoose) – libik May 10 '18 at 14:47
  • Thanks! And you expose it via module.exports? – user1584421 May 10 '18 at 22:53
  • @user1584421 - yes – libik May 11 '18 at 07:45
  • But the require statement goes inside the module.exports? – user1584421 May 11 '18 at 14:54
  • it would be like this - in your app you would require some custom `../components/myPuppeteer`, in that component you would`require('puppeteer')`, do some configurations and then `module.exports.puppeteer = puppeteer` – libik May 11 '18 at 15:43