I am using node.js to create a web application. When I run the application (either by opening index.html on the browser or using the command "npm start" on the terminal) I get two errors:
Uncaught ReferenceError: process is not defined
Uncaught ReferenceError: require is not defined
I solved the "require is not defined" error by specifically including in my index.html head tag the link to this script, where the require function is defined.
However, I cannot find something similar for the process function.
My question is doublefold:
Why do built-in node.js modules need to be re-defined? Why are they not recognized as they are, that is "built-in modules"? Doesn't the term "built-in module" mean that a module need not be redefined externaly/second-handedly?
Is there a way to solve this problem? My script is very simple, I am just trying to use a basic function of node.js, so I cannot figure out what errors I might have done.
If anyone has come about this problem and has found a way around it or a reason this happens, you would be of great help.
Node.js code must be run by the node process, not the browser (the code must run in the server).
To run the code, you must run the command:
node server.js
And then you can access your server from a browser by typing "http://localhost:8080", for example. You must have a file server.js (or whatever) with the server code you want (in this case, creating a web server in port 8080).
You can follow this easy example, using express as http server module: http://expressjs.com/starter/hello-world.html
Webpack can inject environment variables into the "client side" .js code (very useful in case of SPA/PWA). You should define them as plugins in webpack.config.js
webpack.config.js
module.exports = {
plugins: [
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
'process.env.MY_ENV': JSON.stringify(process.env.MY_ENV),
... and so on ...
})
],
}
Now you can access it on client side:
app.js
// Something like that
if(process.env.NODE_ENV === 'debug'){
setDebugLevel(1)
}
If you are facing this problem and you are using webpack, you can get the desired process data injected into the client bundle by using DefinePlugin within your webpack.config.js.
In the example below, I show how to add several things to process.env object to make available within the browser:
all the environment variables inside .env using the library
dotenv
the value of NODE_ENV, which is either 'development' or 'production'
Working example
# .env
API_KEY=taco-tues-123
API_SECRET=secret_tacos
// webpack.config.js
const dotenv = require('dotenv').config({ path: __dirname + '/.env' })
const isDevelopment = process.env.NODE_ENV !== 'production'
module.exports = {
plugins: [
new webpack.DefinePlugin({
'process.env': JSON.stringify(dotenv.parsed),
'process.env.NODE_ENV': JSON.stringify(isDevelopment ? 'development' : 'production'),
}),
].filter(Boolean),
}
// Within client side bundle (React)
// src/App.jsx
console.log(process.env) // {API_KEY: "taco-tues-123", API_SECRET: "secret_tacos"}
console.log(process.env.NODE_ENV) // development
Notice that console.log(process.env) only has the values from the .env file, and that NODE_ENV is not a part of the process.env object.
In the example below, I show how I was trying to inject the process.env object which led me to this stack overflow. I also include a highlight from the webpack documentation on why the code below was not working.
Broken example
module.exports = {
plugins: [
new webpack.DefinePlugin({
'process.env': {
...dotenv.parsed,
'NODE_ENV': JSON.stringify(isDevelopment ? 'development' : 'production')
}
}),
].filter(Boolean),
}
// Within client side bundle (React)
// src/App.jsx
console.log(process.env) // Uncaught ReferenceError: taco is not defined
console.log(process.env.NODE_ENV) // development
From the webpack DefinePlugin docs:
Warning When defining values for process prefer
'process.env.NODE_ENV': JSON.stringify('production')
over
process: { env: { NODE_ENV: JSON.stringify('production') } }
Using the latter
will overwrite the process object which can break compatibility with
some modules that expect other values on the process object to be
defined.
!Warning!
Injecting dotenv.parsed into the client bundle as described will expose these secrets to the client. For development purposes, not a big deal, but in a deployed production environment, any passwords or private api keys will be visible to anyone that goes looking for them.
I had the same problem solved it by going into my .eslintrc.js file
to configure my globals variables, adding require and process to the globals variable and setting the corresponding value equal to "writable". Hope it works for you.
this link really helped
https://eslint.org/docs/user-guide/configuring#specifying-globals
I had same problem when I tried to do this node js app: https://www.youtube.com/watch?v=mr9Mtm_TRpw
The require in html was reached from a < script> and was undefined, like
<script> require('./renderer.js');</script>
I changed it to:
<script src="./renderer.js"></script>
The process in html script was also undefined. I included the webPreferences: nodeIntegration in the js file:
win = new BrowserWindow({
width: 800,
height:600,
icon: __dirname+'/img/sysinfo.png',
webPreferences: {
nodeIntegration: true
}
});
I hope it helped.
You can add the following to your package.json file
{
"name": "mypackage",//default
"version": "0.0.1", //default
"eslintConfig": {
"env": {
"browser": true,
"node": true
}
}}
More Explanation
I was just getting this error (Uncaught ReferenceError: process is not defined) in a local hot-reloading Quasar (Vue) app when calling a particular endpoint. The fix for me ended up being to just restart the hot-reloading server (I hadn't reloaded it since adding the process.env.MY_VARIABLE code).
If you are using the npm module dotenv-webpack with Webpack 3, it might be because you are using destructuring, like so:
const { ENV1, ENV2 } = process.env;
This is a known issue.
Ugly workaround is:
const { ENV1 } = process.env;
const { ENV2 } = process.env;
If you followed all answers here but still have same error then try this.
The error is caused by the react-error-overlay package which has dependencies that were updated to support webpack v5 and are not compatible with react-scripts v4.
So to solve the Uncaught ReferenceError: process is not defined in React, open your terminal in your project's root directory and update the version of your react-scripts package by running npm install react-scripts#latest and re-install your dependencies if necessary.
You can find more detailed answers in here
I had this issue, and for some reason no amount of fiddling around with the webpack.config.js using the other suggestions would resolve it. I suspect some packages I'm using are written incorrectly for the browser, or there might be something wrong with my environment.
I ended up "fixing" it by adding the following code to my HTML file above all other <script> file references. .
<script>
// Required by some npm packages
window.process = { browser: true, env: { ENVIRONMENT: 'BROWSER' } };
</script>
Related
Hello I am trying to integrate realm to my electron react application to save data, I apologize since I am new here and I do not know if my question is well formulated but I ask for your help.
I am integrating realm in my electron - react application as the realm documentation says https://docs.mongodb.com/realm/sdk/node/integrations/electron-cra/#std-label-node-electron-cra -client-quick-start
when I run the application I get this error in the console:
Uncaught ReferenceError: require is not defined
at Object.<anonymous> (external "react":1)
at l (index.html:1)
at Module.<anonymous> (main.7f1bb50c.chunk.js:1)
at l (index.html:1)
at r (index.html:1)
at Array.t [as push] (index.html:1)
at main.7f1bb50c.chunk.js:1
It's supposed to show me the Reaction logo spinning and it doesn't
my public/electron.js
const path = require('path');
const app = electron.app;
const BrowserWindow = electron.BrowserWindow;
let mainWindow;
function createWindow() {
// Create the browser window.
mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: { nodeIntegration: true },
});
// and load the index.html of the app.
console.log(__dirname);
mainWindow.loadFile(path.join(__dirname, '../build/index.html'));
}
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.on('ready', createWindow);
my craco.config.js
module.exports = {
webpack: {
configure: {
target: 'electron-renderer',
externals: [
nodeExternals({
allowlist: [/webpack(\/.*)?/, 'electron-devtools-installer'],
}),
],
},
},
};
my package.json
"main": "public/electron.js",
"homepage": "./",
"scripts": {
"build": "craco build",
"start": "electron .",
},
the "build": "craco build" command created some files that I will not share since they are very large, I would greatly appreciate any help friends
I followed the steps on the Realm tutorial exactly and had no issues with the starting template. Double check your package.json homepage and main fields? For what its worth, I remember seeing a similar error but that occurred while I was using electron-forge init with a typescript + react template. Had no idea how to fix that one.
I encountered another issue when I started to use React hooks with the Realm tutorial and since I feel that it can be commonly encountered error, I'm gonna add my solution to that here as well. The error I got was:
Uncaught Error: Must use import to load ES Module: /mnt/bla/test2/node_modules/#babel/runtime/helpers/esm/arrayWithHoles.js
require() of ES modules is not supported.
To resolve this, I looked into how craco works and changed the craco file's externals fields to look like this:
externals: [
nodeExternals({
allowlist: [/babel(\/.*)?/],
}),
],
nodeExternals lists all files in node modules minus anything whitelisted by allowlist. Webpack takes this list and excludes them from bundling (i.e. forcing the code to require those files). Since the error was saying that it can't require the babel file, I figured that importing it might work so i let babel bundle the babel modules and the problem was resolved. I have no idea how this related to the usage of react hooks though.
I am using React.lazy to load some React classes on runtime so that they are not all loaded at once. My code works for production, but crashes when I am in development mode. (UPDATE: My code no longer works in production - see below).
The particular error message is very cryptic so hard to know exactly what the issue is:
Uncaught TypeError: Cannot read property 'call' of undefined at __webpack_require__ (main.js:64)
The above error occurred in one of your React components:
in Unknown
in Suspense
in div (created by Main)
in Main (created by Route)
in Route (created by App)
in Switch (created by App)
in div (created by App)
in Router (created by BrowserRouter)
in BrowserRouter (created by App)
in App
Consider adding an error boundary to your tree to customize error handling behavior.
Uncaught (in promise) TypeError: Cannot read property 'call' of undefined at __webpack_require__ (main.js:64)
Line 64 gives the following code:
modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
I have other React classes that are not having any issues.
The particular class file that I created is called Categories.js. As far as I know I am not loading the class any differently than any of the ones that are working. I have even tried renaming the class/file and have I have also removed most of my data out of it in case something in the file was causing the issue.
Here are the pertinent lines from my code:
import React, {Suspense} from 'react';
....
const Categories = React.lazy(()=> import('./Categories'))
....
return (
<Suspense fallback={<div>Loading...</div>}>
<Categories class_select={class_select} />
</Suspense>
)
If it helps here is my webpack.config.js file:
const HtmlWebPackPlugin = require("html-webpack-plugin");
const CopyPlugin = require('copy-webpack-plugin');
const TerserPlugin = require('terser-webpack-plugin');
module.exports = (env, argv) => {
const isProduction = (argv.mode === "production")
return {
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
options: {
plugins: [
"#babel/plugin-syntax-dynamic-import"
]
}
}
},
{
test: /\.html$/,
use: [
{
loader: "html-loader"
}
]
}
]
},
...(isProduction && {
optimization: {
// minimize: true,
minimizer: [
new TerserPlugin({
terserOptions: {
extractComments: 'all',
compress: {
drop_console: true
},
}
})
],
}
}),
devtool: !isProduction && 'eval-source-map',
plugins: [
new HtmlWebPackPlugin({
template: "./src/index.html",
filename: "./index.html"
}),
new CopyPlugin([
{ from: 'src/css', to: 'css' }
])
]
};
};
Questions
1) What is causing this error?
2) Why is it only being caused in dev mode but not production mode?
Update
My code no longer works in production either. I am getting the following error:
Uncaught (in promise) TypeError: Cannot read property 'call' of undefined at o (main.js:2).
In fact it is even worse in production than dev. In production none of the React lazy classes are working. In dev it is only one of them that isn't working.
Process
In order to find a potential solution to this issue, I had to tinker with the optimization module, which was indeed the issue here, even when not enabled surprisingly.
My best guess is that some parameters are set to default in production mode and not in dev mode and this causes the issues of imports and undefined properties.
I decided to try replicating the deployment environment and check if I could at least "break" the development as well and investigate the issue from here. These are the parameters that are different between production and development and that were suspect in causing the issue at hand (you can try yourself by switching to the opposite value to put your deployment like the development environment for example).
On the link I provided in the comment, the user was explaining that the issue was at deployment level and that the way the vendors chunk were built, were colliding with the main chunks and cuts the entry to one another. One of the solution was to use concatenateModules: false apparently, but to no avail, it didn't solve my issue. So I tried with the others and found the issue bellow.
Potential solution
in module.exports, the optimization object should be edited
optimization: {
minimize: true,
namedModules: true,
namedChunks: true,
removeAvailableModules: true,
flagIncludedChunks: true,
occurrenceOrder: false,
usedExports: true,
concatenateModules: true,
sideEffects: false, // <----- in prod defaults to true if left blank
}
Edit: all of these parameters are set to their opposite between production and development, tweak them at your own leisure, some issues stems from them
Explanation
After switching all the parameters I found that the sideEffects one is the one that breaks things and I see why:
The sideEffects flag will break down imports into separate ones as follow, as per the documentation on sideEffects:
import { a, b } from "big-module-with-flag"
is rewritten to
import { a } from "big-module-with-flag/a";
import { b } from "big-module-with-flag/b";
And will try to optimize imports accordingly across the modules, which can cause issues in production. Normally this should help optimizing the size of the package by reducing the bundles, at the cost of removing some imports but can break things at import.
I hope the explanation was somewhat clear, if somebody has deeper knowledge on WebPack optimization, any documentation and enhancement would be welcome.
I also had the same error, extremely difficult to diagnose the root cause from a minified JavaScript stack trace. In the end, I just upgraded the Webpack version to the latest 4.X stable release (I was using Angular 11, so no Webpack 5 support) and the problem magically went away. Assume there must have been some dependency tree bug in the Webpack 4.2.X version that I was using previously.
Webpack versions reference:
https://www.npmjs.com/package/webpack
Commands
npm uninstall webpack
npm install --save-dev webpack#4.46.0
I had a similar error that would only occur on production.
Production had Cloudflare but Test did not.
It turned out our Cloudflare cache settings were ignoring our cache busting. Cache busting via query parameters /scripts/main.js?v=1080237476. So our code-split Webpack output had mis-matched JavaScript files and threw the error Uncaught TypeError: Cannot read property 'call' of undefined.
The quick fix was to purge our Cloudflare cache after deploy. Long term fix is to configure our Cloudflare settings or use hashed filenames instead of query parameters for cache busting.
In my React Application I am using an API which is provided at runtime as a global variable by the Browser in which the application runs.
To make the Webpack compilation process work I have added this into the webpack config:
externals: {
overwolf : 'overwolf'
}
It is then imported like this
import overwolf from 'overwolf'
This works fine when I built my production application and run it inside the Browser.
However for the webpack development server, as well as my tests I want to be able to run them from a standard browser where the external will not be available. I am not quite sure how to make this work as the dev server will always complain about the import and my attempts to make conditional imports did not work out so far.
What I would like to achieve is to mock the overwolf variable, so that webpack dev server will compile and let me run my code with the mocked version.
My attempt was like this
import overwolf from 'overwolf'
export function overwolfWrapper() {
if(process.env.NODE_ENV !== 'production') {
return false;
}
else {
return overwolf;
}
}
Which results in the following error on the webpack development server
ReferenceError: overwolf is not defined
overwolf
C:/Users/jakob/Documents/private/projects/koreanbuilds-overwolf2/external "overwolf":1
One possible solution is to keep using the overwolf defined as an external (read more here), and use a polyfill for other browsers:
In your index.html include an overwolf.js script which will provide the mock object to use.
Example using HtmlWebpackPlugin and html-webpack-template to generate the index.html as part of the build process. Include in your plugins array:
new HtmlWebpackPlugin({
template: './node_modules/html-webpack-template/index.ejs',
inject: false,
scripts: ['/overwolf.js']
})
And this is an example for the included overwolf.js previously:
if (!window.overwolf) {
window.overwolf = {
foo() {
console.info('overwolf now has foo function!');
}
};
}
Hope this helps!
Check also this webpack-demo project. I think it would help you with some configurations.
I also found a rather simple solution on my own.
Instead of importing the external this also works:
const overwolf = process.env.NODE_ENV === 'production' ? require('overwolf') : new MockedOverwolf();
Webpack will not complain about this in the dev environment and in production require will still give me the real API.
I am having trouble declaring globals in Typescript, using Webpack's DefinePlugin. I was hoping to get some input on what I am doing wrong.
I created an environment variable in my .bash_profile:
export API_KEY_GOOGLE_MAPS=xxxxxxxxxxxxxxxx
In my webpack.config.js, I have the following lines:
...
plugins: [
new webpack.DefinePlugin({
API_KEY_GOOGLE_MAPS: JSON.stringify(process.env.API_KEY_GOOGLE_MAPS),
}),
],
...
Inside index.tsx (I am using React), I do the following:
declare var API_KEY_GOOGLE_MAPS: string;
console.log(API_KEY_GOOGLE_MAPS)
This produces the following error, at the line containing console.log:
ReferenceError: API_KEY_GOOGLE_MAPS is not defined
Does anybody have any leads?
The other answers require create-react-app so I will offer mine.
First, add the plugin to your Webpack configuration:
const webpack = require("webpack");
module.exports = {
// ...
plugins: [
new webpack.DefinePlugin({
MY_ENV_VAR: JSON.stringify(true),
}),
],
};
Next, declare the variable in TypeScript:
declare var MY_ENV_VAR : string | undefined;
Finally, you can access the variable in your code:
console.log(MY_ENV_VAR);
create-react-app environment variables should be prefixed with REACT_APP_:
Note: You must create custom environment variables beginning with REACT_APP_. Any other variables except NODE_ENV will be ignored to avoid accidentally exposing a private key on the machine that could have the same name. Changing any environment variables will require you to restart the development server if it is running.
from the "Adding Custom Environment Variables" documentation.
You should be adding these environment variables to your .env file(s) in place of adding these to your .bash_profile file. The appropriate file will be picked up depending on the build (i.e. start or build), and the application will be easier to share and deploy.
The way I do it is to have a .env file(add it to .gitignore) in the root of my project files.
Within that file I define my project environment variables(additional variables can be separated by adding each to it's own line):
NODE_ENV=development
Then using the dotenv npm module I can access the values in any webpack file(or server side expressJS file for example).
// in the command line
$ npm install --save dotenv
// at the top of the webpack config file
require('dotenv').config();
// in the plugins of the webpack config
plugins: [
new webpack.DefinePlugin({
'NODE_ENV': JSON.stringify(process.env.NODE_ENV)
})
],
Now I can reference it within my app being transpiled by webpack:
console.log(NODE_ENV); // development
Answering my own question: my project was generated using create-react-app, and according to its documentation, environment variables are accessed this way:
console.log(process.env.API_KEY_GOOGLE_MAPS)
webpack.DefinePlugin() is not required.
Before you read this sorry for splitting my code into separate documents, it wat too long for Stackoverflow editor.
I get this error when i run my development environment:
Configuration file found but no entry configured.
Use --help to display the CLI options.
This is my webpack.config.js:
let config;
if (/development/.test(process.env.NODE_ENV.indexOf('development'))) {
config = require('./config/webpack.dev')({env: 'development'});
}
else if (/production|staging/.test(process.env.NODE_ENV)) {
config = require('./config/webpack.prod')({env: 'production'});
}
module.export = config;
This is my config/webpack.dev.js:
https://docs.google.com/document/d/1oudL50sL84FQDGB7vmuYcr2yVll44UlLr5DPPuZ2-kk/edit?usp=sharing
This is my webpack.common.js:
some code that i reuse for production and development environment
https://docs.google.com/document/d/1JMQPxMbLGsOGddohkZyhbvYE1CSXWImxJll3JVQ4rQA/edit?usp=sharing
This is my package.json:
https://docs.google.com/document/d/1uk5yXCjMbBCnhGqKzrQRAEUDewwPWd_UeW3Zld4oV7w/edit?usp=sharing
I print my screen to show the console.log i did for the config inside my webpack.config file when i run the npm run dev:
http://up416.siz.co.il/up3/eqho2ydz2j2t.png
This is my app structure:
http://up416.siz.co.il/up2/y2tni0ny11mt.png
I think Webpacks' error makes sense. It finds the configuration file, webpack.config.js, but there's no 'entry' property on the value that's exported.
Firstly, module.export should be module.exports. In your example, nothing will be exported, hence there being no entry property.
Once that's fixed, I think there's another issue; looks like the below condition is wrong:
/development/.test(process.env.NODE_ENV.indexOf('development'))
Should it be this instead?
/development/.test(process.env.NODE_ENV)
Since no conditions evaluate to true, config will be exported as undefined, which will probably give you the same error.