My web app uses Webpack 5.45.1 as a module bundler and the only library - ethereum web3.js 1.4.0.
// webpack configuration file
const NodePolyfillPlugin = require("node-polyfill-webpack-plugin");
const path = require('path');
module.exports = {
mode: 'development',
output: {
path: path.resolve(__dirname, 'dist/dev'),
filename: '[name].bundle.js',
},
entry: {
index: './src/index.js'
},
module: {
rules: [
{
test: /\.css$/,
use: ['css-loader'],
}
]
},
plugins: [
new NodePolyfillPlugin()
]
}
The entry point contains one single statement: import Web3 from 'web3';
Executing of the resulting bundle with a browser ends in the following error:
assertion_error.js:486 Uncaught TypeError: Cannot read property 'custom' of undefined
at eval (assertion_error.js:486)
at eval (assertion_error.js:500)
at Object../node_modules/assert/build/internal/assert/assertion_error.js (index.bundle.js:1063)
at __webpack_require__ (index.bundle.js:6721)
at eval (assert.js:38)
at Object../node_modules/assert/build/assert.js (index.bundle.js:1052)
at __webpack_require__ (index.bundle.js:6721)
at eval (index.js:3)
at Object../node_modules/console-browserify/index.js (index.bundle.js:1624)
at __webpack_require__ (index.bundle.js:6721)
I found it out, undefined is a value of this expression: require('util/').inspect.
Can anyone provide a hint on how it can be fixed?
This is because when you want to use web3 in the browser or in a client environment you have to manually include the prebuilt "node_modules/web3/dist/web3.min.js" in to your html with a script tag. That's the way it described in the documentation or you just get it from a cdn.
You should only do this:
import web3 from "web3";
if you want to run it in the nodejs runtime (Server side code or in the Command line).
If you insist on building this yourself then you have to clone the web3.js git repository and run npm run build, then get the /dist/web3.min.js file, and include it in a html script tag of your page, which is still pretty much the same thing and unnecessary.
Read the documentation carefully and see for your self.
web3.js github repo
As it turned out, in my case the problem was in NodePolyfillPlugin, which has a bug related to a circular dependency. I opened the issue on github.
Related
I'm using webpack, and I'm getting this error in the browser:
Uncaught TypeError: Cannot read properties of undefined (reading 'split')
at eval (validator.js:15)
at Object../node_modules/axios/lib/helpers/validator.js (main.bundle.js:1225)
at __webpack_require__ (main.bundle.js:1673)
at eval (Axios.js:8)
at Object../node_modules/axios/lib/core/Axios.js (main.bundle.js:1005)
at __webpack_require__ (main.bundle.js:1673)
at eval (axios.js:5)
at Object../node_modules/axios/lib/axios.js (main.bundle.js:961)
at __webpack_require__ (main.bundle.js:1673)
at eval (index.js:1)
There are no errors or warnings at compilation-time.
Line 15 of validator.js looks like this:
var currentVerArr = pkg.version.split('.');
There is this line at the top of the file:
var pkg = __webpack_require__(/*! ./../../package.json */ "./package.json");
So it looks like that __webpack_require is not working?
How can I fix this?
I also encountered the same problem.
My axios version is 0.21.3
I tried many methods but it didn’t work.
Finally, back to 0.21.1(no validator.js in this version , so I think this is a bug)
npm i --save axios#0.21.1
Apparently axios depends on the "version" property being defined in package.json.
I don't know why, though...
But the solution is to add a "version" property to package.json. Any version.
I encountered the same issue today. It was because I changed the default loader for json files to file-loader like this:
{
type: 'javascript/auto',
test: /\.(geo)?json$/,
use: 'file-loader'
},
If you look at the code for axios/lib/helpers/validators.js in axios v0.21.4, you see it imports package.json like this: var pkg = require('./../../package.json');.
The above config causes the file gets loaded as a string that points to its URL, but the code assumes a JS object and when it tries to access its version property, it fails.
I fixed the error by excluding axios/package.json from that rule:
{
type: 'javascript/auto',
test: /\.(geo)?json$/,
exclude: [path.resolve(__dirname, 'node_modules/axios/package.json')],
use: 'file-loader'
},
It's possible your issue was due to something similar in your webpack config. Check out your rules and other parts of your config to see what loaders you're using and how you're resolving files and objects.
So I have managed to share UI between websites. However, this worked only once by deleting the corrupt .next and node_modules folders. After that I got the error:
> next build
info - Using external babel configuration from D:\Code\Project\next\siteName\.babelrc
info - Creating an optimized production build
info - Compiled successfully
info - Collecting page data
[ ==] info - Generating static pages (0/3)
Error occurred prerendering page "/". Read more: https://err.sh/next.js/prerender-error
Error: Minified React error #321; visit https://reactjs.org/docs/error-decoder.html?invariant=321 for the full message or use the non-minified dev environment for full errors and additional helpful warnings.
at S (D:\Code\Project\next\siteName\.next\server\pages\index.js:11266:327)
at Object.module.exports.hLw4.exports.useContext (D:\Code\Project\next\siteName\.next\server\pages\index.js:11270:269)
at D:\Code\Project\next\siteName\.next\server\pages\index.js:10999:13829
at Object.styled.div [as render] (D:\Code\Project\next\siteName\.next\server\pages\index.js:10999:14417)
at a.b.render (D:\Code\Project\next\siteName\node_modules\react-dom\cjs\react-dom-server.node.production.min.js:43:194)
at a.b.read (D:\Code\Project\next\siteName\node_modules\react-dom\cjs\react-dom-server.node.production.min.js:41:83)
at exports.renderToString (D:\Code\Project\next\siteName\node_modules\react-dom\cjs\react-dom-server.node.production.min.js:52:138)
at Object.renderPage (D:\Code\Project\next\siteName\node_modules\next\dist\next-server\server\render.js:54:851)
at Function.getInitialProps (D:\Code\Project\next\siteName\.next\server\pages\_document.js:734:19)
at loadGetInitialProps (D:\Code\Project\next\siteName\node_modules\next\dist\next-server\lib\utils.js:5:101)
I fixed that by adding in the config.externals seen here in the example project
Now the issue is that by compiling the theme object is not read out at build time.
But the theme object is loggable at build time.
To understand better please look at the index.tsx of app1 or app2 from the example code
The following will be logged in my console by running npm run build
> next build
info - Using external babel configuration from D:\Code\nextjs.shared-ui\next\app1\.babelrc
info - Creating an optimized production build
info - Compiled successfully
info - Collecting page data
[ ==] info - Generating static pages (0/3)
=> logging app1 lowlight: #051923
Error occurred prerendering page "/". Read more: https://err.sh/next.js/prerender-error
TypeError: Cannot read property 'lowlight' of undefined
at module.exports.23aj.Container.children.children (D:\Code\nextjs.shared-ui\next\app1\.next\server\pages\index.js:547:51)
at me (D:\Code\nextjs.shared-ui\next\app1\.next\server\pages\index.js:12049:11223)
at e.generateAndInjectStyles (D:\Code\nextjs.shared-ui\next\app1\.next\server\pages\index.js:12049:8295)
at D:\Code\nextjs.shared-ui\next\app1\.next\server\pages\index.js:12049:13946
at D:\Code\nextjs.shared-ui\next\app1\.next\server\pages\index.js:12049:14013
at Object.styled.div [as render] (D:\Code\nextjs.shared-ui\next\app1\.next\server\pages\index.js:12049:14417)
at a.b.render (D:\Code\nextjs.shared-ui\next\app1\node_modules\react-dom\cjs\react-dom-server.node.production.min.js:43:194)
at a.b.read (D:\Code\nextjs.shared-ui\next\app1\node_modules\react-dom\cjs\react-dom-server.node.production.min.js:41:83)
at exports.renderToString (D:\Code\nextjs.shared-ui\next\app1\node_modules\react-dom\cjs\react-dom-server.node.production.min.js:52:138)
at Object.renderPage (D:\Code\nextjs.shared-ui\next\app1\node_modules\next\dist\next-server\server\render.js:54:851)
info - Generating static pages (3/3)
> Build error occurred
Error: Export encountered errors on following paths:
/
at D:\Code\nextjs.shared-ui\next\app1\node_modules\next\dist\export\index.js:30:1103
at async D:\Code\nextjs.shared-ui\next\app1\node_modules\next\dist\build\tracer.js:3:470
at async D:\Code\nextjs.shared-ui\next\app1\node_modules\next\dist\build\index.js:41:69
at async D:\Code\nextjs.shared-ui\next\app1\node_modules\next\dist\build\tracer.js:3:470
at async D:\Code\nextjs.shared-ui\next\app1\node_modules\next\dist\build\index.js:21:1225
at async D:\Code\nextjs.shared-ui\next\app1\node_modules\next\dist\build\tracer.js:3:470
The command line says that we can not access the lowlight of undefined.
Even though we logged the same lowlight just moments before the error.
For me, that ^ is unexpected behavior since we can log the value before it.
next.config.js:
const path = require('path')
const aliasPathsToResolve = [
{ name: '#react', path: path.resolve(__dirname, '../../react') },
{ name: '#utils', path: path.resolve(__dirname, '../../utils') },
]
module.exports = {
webpack: (config, { defaultLoaders }) => {
config.externals = {
react: {
root: 'React',
commonjs2: 'react',
commonjs: 'react',
amd: 'react',
},
'react-dom': {
root: 'ReactDOM',
commonjs2: 'react-dom',
commonjs: 'react-dom',
amd: 'react-dom',
},
}
config.module.rules.push({
test: /\.(js|jsx|ts|tsx)$/,
include: [
path.resolve(__dirname, '../../react/'),
path.resolve(__dirname, '../../utils/'),
],
use: [defaultLoaders.babel],
})
/** Resolve aliases */
aliasPathsToResolve.forEach((mod) => {
config.resolve.alias[mod.name] = mod.path
})
return config
},
};
Folder structure:
nextjs.shared-ui (root)
├/next
│├/app1 (next project)
│└/app2 (next project)
├/react (shared ui components)
├/sites (custom express servers for next)
├/utils
├ [config files]
└ index.js (end point for both next apps)
How can I resolve this build issue?
The full example project can be found here: https://github.com/TessavWalstijn/nextjs.shared-ui
I have added a branch without sharing UI.
This to show that the react components work fine
and that the theme object does not becomes undefined at other build processes.
Branch without sharing UI: https://github.com/TessavWalstijn/nextjs.shared-ui/tree/working-not-shared-ui-version
I am trying to add additional Gatsby Plug-ins to a Gatsby Project. I want to add 'gatsby-plugin-styled-components' to the gatsby-config.js file. Any help would be appreciated. Newbie to React and learning a lot fast.
added already and threw errors all over the place after running npm run build
/**
* Configure your Gatsby site with this file.
*
* See: https://www.gatsbyjs.org/docs/gatsby-config/
*/
module.exports = {
plugins: [`gatsby-plugin-emotion`],
}
gatsby-starter-hello-world#0.1.0 build /Users/jappleman/code/hello-world/tutorial-part-two
gatsby build
error We encountered an error while trying to load your site's gatsby-config.
Please fix the error and try again.
Error: /Users/jappleman/code/hello-world/tutorial-part-two/gatsby-config.js:8
plugins: ['`gatsby-plugin-emotion`],['`gatsby-plugin-styled-components'],
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
SyntaxError: Unterminated template literal
- v8-compile-cache.js:226 NativeCompileCache._moduleCompile
[tutorial-part-two]/[v8-compile-cache]/v8-compile-cache.js:226:18
- v8-compile-cache.js:172 Module._compile
[tutorial-part-two]/[v8-compile-cache]/v8-compile-cache.js:172:36
- loader.js:712 Object.Module._extensions..js
internal/modules/cjs/loader.js:712:10
- loader.js:600 Module.load
internal/modules/cjs/loader.js:600:32
- loader.js:539 tryModuleLoad
internal/modules/cjs/loader.js:539:12
- loader.js:531 Function.Module._load
internal/modules/cjs/loader.js:531:3
- loader.js:637 Module.require
internal/modules/cjs/loader.js:637:17
- v8-compile-cache.js:159 require
[tutorial-part-two]/[v8-compile-cache]/v8-compile-cache.js:159:20
- get-config-file.js:33
[tutorial-part-two]/[gatsby]/dist/bootstrap/get-config-file.js:33:22
- Generator.next
- new Promise
gatsby-config.js exports an object
module.exports = {}
and within that object, the plugins you want to use on your project are specified as an array of plugin names (strings) that you have already installed as dependencies to your project (for example by typing npm install gatsby-plugin-react-helmet or yarn add gatsby-plugin-react-helmet into your terminal).
module.exports = {
plugins: [
`gatsby-plugin-react-helmet`
]
}
However, some of the plugins you will install might need some options to be set in order to work correctly. So these plugins should each be specified as an object within the same plugins array. And in this case, the value of each object's resolve property is the name of the plugin, usually followed by an object for their own options.
module.exports = {
plugins: [
`gatsby-plugin-react-helmet`,
`gatsby-transformer-remark`,
{
resolve: `gatsby-source-filesystem`,
options: {
name: `src`,
path: `${__dirname}/src/data/`
}
}
]
}
For more information see Using a Plugin in Your Site
Also, given that your error is caused by a SyntaxError, please see MDN - Template_literals for information on backticks vs regular quotes, the differences between:
`gatsby-plugin-styled-components` & 'gatsby-plugin-styled-components'
& why the following line might be causing the Unterminated string literal SyntaxError:
plugins: ['`gatsby-plugin-emotion`],['`gatsby-plugin-styled-components']
After that, if the solution is not obvious, try changing your plugins to either of the following:
plugins: [`gatsby-plugin-emotion`],[`gatsby-plugin-styled-components`]
or
plugins: ['gatsby-plugin-emotion'],['gatsby-plugin-styled-components']
My question is very close to others which' answers I believe still require another WebPack-step which I want to avoid. But here is the story first:
I have a Node module (let's call it libfoo) which provides some functionality and requires some third party modules,
and a small script main.js which provides the main entry point and requires libfoo:
main.js:
const foo = require('foo');
function main() {
foo.bar();
}
main();
I now want to turn libfoo and main.js into browser executable deliverables using WebPack. And I want libfoo (which is quite large) to reside statically on the target systems while main.js is very small and changes quickly (just imagine a test scenario where libfoo is a module I want to test and main.js contains changing code snippets)
I managed to create two packages - let's call them foo.browser.js and main.browser.js - which contain all the needed functionality, but I can't manage to make main.browser.js correctly import foo.browser.js.
I'm not very into WebPack yet - and up to now I couldn't figure out what's happening. My current approach looks like this: I build foo.browser.js by running the following command:
webpack --output-filename foo.browser.js foo.js
And I have a webpack.config.js for main.js which looks like this:
module.exports = {
externals: {'foo': 'foo'}, // don't know what I'm doing here - added `commonjs` and `root` randomly
}
I turn main.js into main.browser.js with a very similar command: webpack --output-filename main.browser.js main.js
Now I try to use those both files in file called foo.html containing these lines:
<script src="dist/foo.browser.js"></script>
<script src="dist/main.browser.js"></script>
But when I now open foo.html in a browser I get
external "foo":1 Uncaught ReferenceError: foo is not defined
at Object.foo (external "foo":1)
at __webpack_require__ (bootstrap:19)
at Object../main.js (main.js:3)
at __webpack_require__ (bootstrap:19)
at bootstrap:83
at bootstrap:83
I fiddled around a little but (only randomly I'm afraid) but with no luck.
There is one constraint in my scenario which might be a difference to the other (working) examples I found: I need foo.browser.js and main.browser.js to be "final" i.E. they must run on the target system without any further postprocessing (like running WebPack again to turn them into a single bundle).
You can do it with this type of configuration:
module.exports = [{
resolve: {
modules: ["."],
},
entry: {
"foo": "foo.js",
},
output: {
path: `${__dirname}/build`,
filename: "[name].js",
sourceMapFilename: "[name].js.map",
library: "foo",
// libraryTarget: "umd",
}
},{
resolve: {
modules: ["."],
},
entry: {
"main": "main.js",
},
externals: {
"foo": "foo",
},
output: {
path: `${__dirname}/build`,
filename: "[name].js",
sourceMapFilename: "[name].js.map",
}
}];
This will produce two bundles in the build/ subdirectory. The key to get main to use foo is:
The "foo": "foo" entry in externals for creating the main bundle. Whenever main requests foo it looks for it externally in a "module" named foo. I've put "module" into quotes because when you have bundles in the UMD format and you load them with script, there's no module system. Instead of looking for an actual module, the code will look for a global variable named foo.
The foo bundle exports itself into the global space as the variable foo, which allows it to be used by main.
Here's my webpack.config.js
"use strict";
module.exports = {
entry: ['./main.js'],
output: { path: __dirname, filename: 'bundle.js' },
module: {
loaders: [
{
test: /.js?$/,
loader: 'babel-loader',
exclude: /node_modules/,
query: {
presets: ['es2015', 'react']
}
},
{test: /\.json$/, loader: "json"},
]
},
externals: {
React: 'react',
},
target: "node",
};
And Main.js
import React from 'react';
import ReactDOM from 'react-dom';
import {Table, Column, Cell} from 'fixed-data-table';
import Chart from 'chartjs';
import jQuery from 'jquery';
import vis from 'vis';
import babel from 'babel-core';
The Bundle.js is inserted in my Index.html. The browser then gives the error:
Uncaught ReferenceError: process is not defined
at Object.measureMethods (bundle.js:1297)
at Object.<anonymous> (bundle.js:530)
at __webpack_require__ (bundle.js:20)
at Object.<anonymous> (bundle.js:288)
at __webpack_require__ (bundle.js:20)
at Object.<anonymous> (bundle.js:158)
at __webpack_require__ (bundle.js:20)
at Object.<anonymous> (bundle.js:110)
at __webpack_require__ (bundle.js:20)
at Object.<anonymous> (bundle.js:90)
What should I change in the webpack.config.js to make this error go away?
For Webpack 5, you can reference process/browser from the appropriate plugins part of webpack.config.js:
// webpack needs to be explicitly required
const webpack = require('webpack')
// import webpack from 'webpack' // (if you're using ESM)
module.exports = {
/* ... rest of the config here ... */
plugins: [
// fix "process is not defined" error:
new webpack.ProvidePlugin({
process: 'process/browser',
}),
]
}
Then run
npm install process
before building.
For namespaced environment variables (more secure) check lines 10 - 28 on this StackBlitz page.
With dotenv package:
Install dotenv:
yarn add -D dotenv or npm i -D dotenv
Add .env file in your project root with the required variables:
NODE_ENV=development
apiKey=w23io222929kdjfk
domain=example.domain.org
Define these variables with webpack.DefinePlugin:
// webpack.config.js
const webpack = require('webpack')
const dotenv = require('dotenv')
// this will update the process.env with environment variables in .env file
dotenv.config();
module.exports = {
//...
plugins: [
// ...
new webpack.DefinePlugin({
'process.env': JSON.stringify(process.env)
})
// ...
]
//...
}
Access environment variables in your source code:
// src/index.js
alert(process.env.NODE_ENV)
alert(process.env.apiKey)
StackBlitz example: https://stackblitz.com/edit/node-kdfi4z?file=index.js
You need to add a plugin to define your env (in webpack config):
plugins: [
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify('development')
})
],
This is how i resolved the
ReferenceError: process is not defined
error with Webpack 5
npm i --save-dev process
Delete the "node_modules" folder
Add const webpack = require('webpack'); at the top of your config file
In your webpack config file, plugin section, add below:
plugins: [
new webpack.ProvidePlugin({
process: 'process/browser',
}),
Also in the webpack add the alias like below:
resolve: {
alias: {
process: "process/browser"
},
Now do npm i
...and when you build your application the error will disappear.
you can read about webpck migration [here]
Webpack 5 removes the ability to access environment variables using the notation process.env.MY_ENV_VAR. I had this same problem because I was getting a Uncaught ReferenceError: process is not defined error in my browser console. From the documentation of porting from v4 to v5 of Webpack, they mention the following:
1. Before upgrading to v5, verify that you can easily do it
Try to set the following options in your webpack 4 configuration and
check if build still works correctly.
module.exports = {
// ...
node: {
Buffer: false,
process: false
}
};
webpack 5 removes these options from the configuration schema and will always use false.
You have to remove these options again when upgrading your
configuration for webpack 5.
2. Handling env vars because process was removed
Regarding Runtime Errors:
process is not defined.
webpack 5 does no longer include a polyfill for this Node.js variable. Avoid using it in the frontend code.
Want to support frontend and browser usage? Use the exports or imports package.json field to use different code depending on the
environment.
Also use the browser field to support older bundlers,.
Alternative: Wrap code blocks with the typeof process checks. Note that this will have a negative impact on the bundle size.
Want to use environment variables with process.env.VARIABLE? You need to use the DefinePlugin or EnvironmentPlugin to define these
variables in the configuration.
Consider using VARIABLE instead and make sure to check typeof VARIABLE !== 'undefined' too. process.env is Node.js specific
and should be avoided in frontend code.
Therefore, given the above information, it is possible to use environment variables using one of the two plugins below.
const webpack = require("webpack");
module.exports = {
...
plugins: [
new webpack.DefinePlugin({
"process.env.MY_ENV_VAR": JSON.stringify(process.env.MY_ENV_VAR)
}),
new webpack.EnvironmentPlugin(['MY_ENV_VAR']); // <--This is shorthand, does the same thing as the DefinePlugin
],
};
Then in your production code it's still feasable to refer to the environment variable in the same way, example:
console.log(process.env.MY_ENV_VAR);
However, as they said in the documentation included above, using process.env is NOT the recommended way since that is Node.js specific.
Webpack 5, the easiest solution for me...
npm install dotenv-webpack --save-dev
// webpack.config.js
const Dotenv = require('dotenv-webpack');
module.exports = {
...
plugins: [
new Dotenv()
]
...
};
To avoid error like denoted in the question I had have provide in webpack.config.js the next configuration (note defining variable level: process.env):
new webpack.DefinePlugin({
"process.env": JSON.stringify(process.env)
})
Now it works fine. I'm using webpack 5.30.0, Vue 2.6.12 and vuelidate 0.7.6.
Error I had before in browser console:
Uncaught ReferenceError: process is not defined
at Object.../node_modules/vuelidate/lib/withParams.js
It is not good thing, that browser client library "vuelidate" requires Node.js specific env variables. Confused build and runtime areas in library.
Works for me to allow reading env variables inside React, using "webpack": "^5.1.3",
webpack.config.js
const webpackConfig = {
plugins: [
new webpack.ProvidePlugin({
process: 'process/browser',
}),
new webpack.DefinePlugin({
'process.env': JSON.stringify(process.env)
})
],
};
:)
Having dotenv-webpack/dotenv in your webpack and still doesn't work on Angular? Most probably you're trying to access process.env when running the Angular app on the browser (without Angular Universal), e.g. by ng serve.
Run npm i -S process and then in polyfills.ts paste the code below
import * as process from "process";
window["process"] = process;
Alternatively, if that's not the case and you're looking for webpack to obtain environmental variables then (I don't know why no one suggested yet) dotenv-webpack is the simplest one.
const dotenv = require("dotenv-webpack");
const webpackConfig = {
plugins: [new dotenv()]
};
module.exports = webpackConfig; // Export all custom Webpack configs.
Of course you need to have them defined in .env file at the root of your project.
If it is useful for someone:
I tried almost every approach in this thread unsuccessfully.
When I went deeper into the problem I realized that what was causing this error on my application was the usage of assert lib:
import * as assert from 'assert';
...
assert(myVariable !== undefined, "Try to update undefined myVariable ");
BTW: I'm using Angular#~11.2.7
My problem was process is undefined error on internet explorer 11 using webpack 5.
This is how I solved my problem with process.env.MY_ENV_VAR thanks to #ArianPopalyar.
Ref. Answer
In addition to her solution, I added EnvironmentPlugin in webpack.config.js:
...
plugins: [
new webpack.ProvidePlugin({
process: 'process/browser'
}),
new webpack.EnvironmentPlugin({
PATH_MODERN: 'dist/modern/domready.min.js',
PATH_LEGACY: 'dist/legacy/domready.min.js',
DEBUG: false
}),
...
]
and using it in index.js
if (process.env.PATH_LEGACY) {
// ...
}
Easy way: prepend the variable "NODE_ENV" when you call webpack i.e. NODE_ENV=production webpack --watch