530

I have a file client.js, which is loaded on the client side. In that file I have code that calls functions from other JavaScript files. My attempt was to use

var m = require('./messages');

in order to load the contents of messages.js (just like I do on the server side) and later on call functions from that file. However, require is not defined on the client side, and it throws an error of the form Uncaught ReferenceError: require is not defined.

These other JavaScript files are also loaded at runtime at the client, because I place the links at the header of the webpage. So the client knows all the functions that are exported from these other files.

How do I call these functions from these other JavaScript files (such as messages.js) in the main client.js file that opens the socket to the server?

MightyMouse
  • 13,208
  • 8
  • 33
  • 43
  • 6
    Why don't you just `` and call them after that? – Sterling Archer Sep 27 '13 at 20:34
  • 3
    Perhaps this can be a solution, but there is another thing that concerns me. I also have a file called "representation.js" for abstracting the representation that is common to the client and the server. In that file I also have require statements and on the server side it should be ok because I am running node. However, on the client side this will be an issue. What do you think? – MightyMouse Sep 27 '13 at 20:45
  • 4
    For newbies like me (who couldn't even spell "npm" a week ago! :-), it may be helpful to understand that browserify's `--require` option causes `require()` to be defined on the client side. See: https://lincolnloop.com/blog/speedy-browserifying-multiple-bundles/ – Hephaestus Mar 12 '16 at 18:34
  • 4
    @Sterling Archer... If there are 100 such files... we can't keep on loading the, in HTML right......... – Baradwaj Aryasomayajula Jun 09 '16 at 18:58
  • "client on node.js" is a confusing title because "client" usually refers to the web browser client, while node.js is a server-side environment. Can we clarify whether this is browser or Node? – ggorlen Sep 21 '22 at 15:17

11 Answers11

587

This is because require() does not exist in the browser/client-side JavaScript.

Now you're going to have to make some choices about your client-side JavaScript script management.

You have three options:

  1. Use the <script> tag.
  2. Use a CommonJS implementation. It has synchronous dependencies like Node.js
  3. Use an asynchronous module definition (AMD) implementation.

CommonJS client side-implementations include (most of them require a build step before you deploy):

  1. Browserify - You can use most Node.js modules in the browser. This is my personal favorite.
  2. Webpack - Does everything (bundles JavaScript code, CSS, etc.). It was made popular by the surge of React, but it is notorious for its difficult learning curve.
  3. Rollup - a new contender. It leverages ES6 modules and includes tree-shaking abilities (removes unused code).

You can read more about my comparison of Browserify vs (deprecated) Component.

AMD implementations include:

  1. RequireJS - Very popular amongst client-side JavaScript developers. It is not my taste because of its asynchronous nature.

Note, in your search for choosing which one to go with, you'll read about Bower. Bower is only for package dependencies and is unopinionated on module definitions like CommonJS and AMD.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
JP Richardson
  • 38,609
  • 36
  • 119
  • 151
  • 2
    Thank you very much. I made a mini test separately, this is why it took me a while to respond. I may come back with some questions in a few minutes just to make sure that I understand how this magic worked. I just want to put everything together. Thanks again. Browserify seems to rock! :) – MightyMouse Sep 27 '13 at 21:18
  • 1
    @JPRichardson Is this answer helpfull for my question? http://stackoverflow.com/questions/31150558/obfuscating-js-files-with-grunt-obfuscator-uncaught-referenceerror-require-is – napstercake Jul 08 '15 at 17:16
  • 1
    can't you just npm i `karma-browserify` and the requires will work? – SuperUberDuper Jan 18 '16 at 14:53
  • 7
    I think JSPM should be added to the list. – Martijn Feb 11 '16 at 09:12
  • 91
    Could I get an example of using the ` – Louie Bertoncin May 12 '16 at 16:50
  • 5
    Anybody know how to use require on the client side with webpack? Still getting "require is not defined error" – user3226932 May 30 '16 at 21:31
  • 2
    SystemJS and JSPM are very notable omissions. – Aluan Haddad May 08 '17 at 05:10
  • 5
    Yeah. Component is now deprecated https://github.com/componentjs/component – i_emmanuel Jul 17 '17 at 12:35
  • 1
    @SuperCow I don't think so (but that was also 3+ years ago). I feel like I ended up using webpack or fixed my existing faulty webpack config – Louie Bertoncin Aug 21 '19 at 16:35
  • **Server** in node are all files related to the `server.js` file that `starts` the node server with e.g. `app.listen(port etc)`? – Timo Apr 07 '21 at 06:19
  • `Even though require might be defined, it might not execute the same functions as server-side Node.js.` – no ai please May 05 '21 at 05:22
  • 10
    how can I do it using – FLAK-ZOSO Oct 10 '21 at 07:20
  • For the people asking how to use the `. and then use JSON.parse to get the JSON object: `var mydata = JSON.parse(data);`. BUT: This method will treat the JSON as if it is Javascript and you'll most likely get an "unexpected token" error, so the correct way is to use fetch: `fetch("test.json") .then(response => response.json()) .then(json => console.log(json));` – hmoore Aug 09 '22 at 15:14
  • how to use script tag with this problem? – Nam Lee Nov 02 '22 at 22:42
88

I am coming from an Electron environment, where I need IPC communication between a renderer process and the main process. The renderer process sits in an HTML file between script tags and generates the same error.

The line

const {ipcRenderer} = require('electron')

throws the Uncaught ReferenceError: require is not defined

I was able to work around that by specifying Node.js integration as true when the browser window (where this HTML file is embedded) was originally created in the main process.

function createAddItemWindow() {

    // Create a new window
    addItemWindown = new BrowserWindow({
        width: 300,
        height: 200,
        title: 'Add Item',

        // The lines below solved the issue
        webPreferences: {
            nodeIntegration: true,
            contextIsolation: false
        }
})}

That solved the issue for me. The solution was proposed here.

David Burson
  • 2,947
  • 7
  • 32
  • 55
Kibonge Murphy
  • 1,140
  • 8
  • 9
  • 2
    Is this solution safe? I've heard you shouldn't set nodeIntegration to true - is that right? I am an Electron newbie so this is a genuine question. – Mike Baxter Mar 23 '21 at 23:46
  • 1
    Well, it depends on how you are going to use your electron application. The comment thread of the original StackOverflow question I referenced gives a brief overview of the security aspects of doing this. You can follow the thread [here](https://stackoverflow.com/questions/44391448/electron-require-is-not-defined/55908510#55908510). But in short: If this is set to true, your application has access to the node runtime, and if you are executing, potentially malicious, remote code, it's just a recipe for disaster. – Kibonge Murphy Mar 25 '21 at 06:22
  • 1
    `This won't work if you don't use Electron. If you don't use Electron, the above code will fail with "Unexpected token '}'".` – no ai please May 05 '21 at 05:23
  • 2
    This is not considered safe and is a discouraged practice now. – Cyril Gupta Nov 11 '21 at 07:15
  • @Kibonge Murphy Does this mean that all Node modules that would actually be useful in Electron are off limits? Such as fs? – HeadCode Jan 26 '22 at 01:21
  • @CyrilGupta I understand that this is bad practice now. But what's the alternative? Or just the whole idea of communication between a renderer process and the main process is against some standards? – Jake_3H Aug 08 '22 at 22:16
64

ES6: In HTML, include the main JavaScript file using attribute type="module" (browser support):

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

And in the script.js file, include another file like this:

import { hello } from './module.js';
...
// alert(hello());

Inside the included file (module.js), you must export the function/class that you will import:

export function hello() {
    return "Hello World";
}

A working example is here. More information is here.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Kamil Kiełczewski
  • 85,173
  • 29
  • 368
  • 345
  • 2
    @Curse Here https://stackoverflow.com/a/44591205/860099 is written "Module creates a scope to avoid name collisions." sou you can "manually" put `val` to window object `window.val = val`. Here is plunker: Plunker: http://plnkr.co/edit/aDyjyMxO1PdNaFh7ctBT?p=preview - this solution works – Kamil Kiełczewski Aug 07 '18 at 14:20
  • 1
    which script.js are you talking about? I couldn't get that.. can you pls tell me – Mrinal Anand Oct 02 '21 at 06:53
  • @MrinalAnand its only example name for file with js code – Kamil Kiełczewski Oct 02 '21 at 08:56
32

Replace all require statements with import statements. Example:

// Before:
const Web3 = require('web3');

// After:
import Web3 from 'web3';

It worked for me.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Noha Abuaesh
  • 535
  • 5
  • 4
  • For reference, it might be helpful to go through [this question](https://stackoverflow.com/questions/46677752/the-difference-between-requirex-and-import-x) regarding the difference between the two. – tripathiakshit Aug 01 '20 at 00:26
  • 3
    `You might need to use type=module, which requires you to export the functions and variable names for them to work.` – no ai please May 05 '21 at 05:24
  • 1
    Those requires are generated automatically from TypeScript. How to avoid that? – Thomas Weller Dec 16 '22 at 19:32
4

In my case I used another solution.

As the project doesn't require CommonJS and it must have ES3 compatibility (modules not supported) all you need is just remove all export and import statements from your code, because your tsconfig doesn't contain

"module": "commonjs"

But use import and export statements in your referenced files

import { Utils } from "./utils"
export interface Actions {}

Final generated code will always have(at least for TypeScript 3.0) such lines

"use strict";
exports.__esModule = true;
var utils_1 = require("./utils");
....
utils_1.Utils.doSomething();
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
ydanila
  • 435
  • 1
  • 5
  • 11
4

This worked for me

  1. Get the latest release from the RequireJS download page
    It is the file for RequestJS which is what we will use.
  2. Load it into your HTML content like this: <script data-main="your-script.js" src="require.js"></script>

Notes!

Use require(['moudle-name']) in your-script.js, not require('moudle-name')

Use const {ipcRenderer} = require(['electron']), not const {ipcRenderer} = require('electron')

Potherca
  • 13,207
  • 5
  • 76
  • 94
eaithy
  • 234
  • 2
  • 6
  • 11
    Never, ever recommend a "click here", ever. Best case, it's a RickRoll, but we have no idea whatsoever what's awaiting us at the end of that link. – ggdx Oct 26 '19 at 15:17
  • this was help me!! but now my problem is that I need manually change the require... that's a problem, exits somethings in tsconfig that do this when I compile? – AntoCode Mar 25 '21 at 12:14
3

Even using this won't work. I think the best solution is Browserify:

module.exports = {
  func1: function () {
   console.log("I am function 1");
  },
  func2: function () {
    console.log("I am function 2");
  }
};

-getFunc1.js-
var common = require('./common');
common.func1();
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Wael Chorfan
  • 686
  • 7
  • 9
3
window = new BrowserWindow({
    webPreferences: {
        nodeIntegration: true,
        contextIsolation: false
    }
});
double-beep
  • 5,031
  • 17
  • 33
  • 41
Abdullah
  • 49
  • 1
  • 2
    Welcome to Stack Overflow and thanks for taking the time to create an answer. However, this very answer has been given numerous times as a solution for this question and thus does not add any value whatsoever. If you could elaborate a bit (by [edit]ing this post) on why and how this solution works, this answer could turn to good advice which is exactly what this site is for. Also, this is an answer purely for the Electron framework, which the OP of the question does not even use -- please consider posting (a more elaborate version) on a more appropriate spot. – Alexander Leithner Mar 29 '21 at 12:57
  • consider updating with details as to how this answer is different from the other answers; does this answer address an issue not addressed by other answers? – markp-fuso Mar 29 '21 at 13:11
  • 1
    although it is not clear but somehow is worked. – Najam Us Saqib May 19 '21 at 14:50
1

I confirm. We must add:

webPreferences: {
    nodeIntegration: true
}

For example:

mainWindow = new BrowserWindow({webPreferences: {
    nodeIntegration: true
}});

For me, the problem has been resolved with that.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
1

People are asking what is the script tag method. Here it is:

<script src='./local.js'></script>. 

Or from network:

<script src='https://mycdn.com/myscript.js'></script>

You need plugin the right url for your script.

us_david
  • 4,431
  • 35
  • 29
0

I was trying to build metronic using webpack. In my package.json I had to remove the "type": "module" section.

enter image description here

Enrico
  • 2,734
  • 1
  • 27
  • 40