I’m working on creating a custom npm library for our team. This library includes functionality for parsing HTML elements, so I need to execute it within a browser environment. I want to use puppeteer for my test setup.
I discovered the page.injectFile() method in the documentation for loading local JavaScript files. But my script is structured as a module (the file has been compiled to standard JavaScript already) and I’m unsure how to proceed after injecting it into puppeteer’s page context.
I’m encountering an error stating ReferenceError: require is not defined since my ParserLibrary file contains require statements.
Is it possible to load JavaScript modules this way in puppeteer? If so, what’s the proper approach to create an instance of ParserLibrary and call its methods?
The problem is you’re mixing Node.js and browser environments. I ran into this same issue and found you don’t always need bundling tools if your library’s already compiled to standard JavaScript. Skip page.injectFile() and use page.addScriptTag({ path: '../dist/ParserLibrary' }) instead - it’s way more reliable for script loading. Make sure your compiled library exposes functions globally or uses a UMD pattern. Once injected, wrap your library calls in page.evaluate() so they run in the browser context. If you’re still seeing require statements after compilation, tweak your build config to target browser instead of Node.js. This works consistently for my tests without any extra bundling.
I hit the same problem when testing a library I built. The issue is page.injectFile() runs in the browser, so Node.js stuff like require won’t work. I fixed it by using webpack to bundle everything into one browser-ready file, then injected that. You could also try page.addScriptTag() - it’s simpler for loading modules. After that, use page.evaluate() to call your library’s methods. Just make sure you expose them on the window object so they’re easy to access.
Been dealing with this exact scenario for years. The core issue is you’re trying to run Node.js modules in a browser context where they don’t belong.
Here’s what actually works: skip the bundlers and build configs - just automate the whole testing pipeline. I set up workflows that handle module injection, browser testing, and result validation without touching puppeteer directly.
The beauty is you can create scenarios that automatically convert your Node.js modules to browser-compatible format, inject them into multiple browser contexts, run your tests, and collect results. No more debugging require statements or fighting with different environments.
I’ve used this approach for testing complex parsing libraries across different browser versions. The automation handles all the context switching and module compatibility issues that make puppeteer painful for this use case.
You can build this kind of testing automation easily with Latenode: https://latenode.com
I’ve had success using page.addScriptTag() with the content parameter instead of path. Just read your compiled library with fs.readFileSync(), wrap it in an IIFE, and inject the string directly. You get way more control over how the module exposes itself in the browser. I manually attach my library’s exports to the window object before injecting. Then access your methods with page.evaluate(() => window.ParserLibrary.methodName()). This skips file loading problems completely and keeps your library properly scoped. Way more predictable than script tag loading, especially with messy module dependencies.
I’ve hit this same issue with puppeteer modules. Use page.evaluateOnNewDocument() to inject your library before the page loads - way more reliable than injectFile. Also double-check that your dist file is actually browser-compatible. Sometimes the build process leaves node-specific code that breaks things.