webpack browserify --ignore equivalent? - javascript

I have some code that doesn't work in the browser unless I "ignore" two packages, I can do this fine with browserify: browserify files.js -i fs-extra -i request --standalone files > files.browserify.js, the resulting code just works, but if I try to do it with webpack the code complains about modules being missing.
...
plugins: [
new webpack.IgnorePlugin(/fs-extra$/),
new webpack.IgnorePlugin(/request$/),
new webpack.IgnorePlugin(/fs$/)
],
...
test.webpack.js:7655 Uncaught Error: Cannot find module "request"
at webpackMissingModule (test.webpack.js:7655)
at Object.exports.byteLength (test.webpack.js:7655)
at __webpack_require__ (test.webpack.js:20)
at Object.<anonymous> (test.webpack.js:17012)
at __webpack_require__ (test.webpack.js:20)
at test.webpack.js:66
at test.webpack.js:69
I suspect that maybe webpack doesn't create an "empty stub" like browserify does: --ignore, -i Replace a file with an empty stub. Files can be globs..
What can I do to fix this?
Resources
https://webpack.github.io/docs/webpack-for-browserify-users.html#ignore
https://webpack.github.io/docs/list-of-plugins.html#ignoreplugin

What you're looking for is null-loader which returns an empty module:
module: {
loaders: [
{
test: /^(fs-extra|fs|request)$/,
loader: "null"
},
...
]
To install:
$ npm i -D null-loader

Related

Webpack bundle error: cannot read property of undefined

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.

Making Kafka.js external dependency using webpack in node as a commonjs module

I'm trying to make kafkajs external dependency (move out from webpack bundle) with this config:
externals: {
kafkajs: 'kafkajs',
redis: 'redis'
}
Dependencies:
dependencies: {
...
"kafkajs": "^1.12.0",
...
}
But I'm getting error "Cannot find module":
{
"error": "Initialization has failed due to: Error: Cannot find module 'kafkajs'\n at Function.Module._resolveFilename (internal/modules/cjs/loader.js:581:15)\n at Function.Module._load (internal/modules/cjs/loader.js:507:25)\n at Module.require (internal/modules/cjs/loader.js:637:17)\n at require (internal/modules/cjs/helpers.js:22:18)\n at Object.<anonymous>"
}
I tried clearing the cache, saving the dependency again and with different externals configuration:
externals: [
"kafkajs",
{
Kafka: {
commonjs: ["kafkajs", "Kafka"],
}
]
Thanks ahead for any guidance
If you are bundling your node.js app, it is better to mark as external all the node_modules, there is a lib for that, webpack-node-externals.
npm install webpack-node-externals --save-dev
//webpack.config.js
const nodeExternals = require('webpack-node-externals');
...
module.exports = {
...
target: 'node', // in order to ignore built-in modules like path, fs, etc.
externals: [nodeExternals()], // in order to ignore all modules in node_modules folder
...
};

How to use tsify with watchify on Ubuntu?

The input directory contains:
a JavaScript file (a jQuery plugin that is not in the DefinitelyTyped repo) and
2 TypeScript files
declarations.d.ts
main.ts
The tsconfig.json file is this (work in progress):
{
"compilerOptions": {
"removeComments": true,
"preserveConstEnums": true,
"sourceMap": true,
"outDir": "wp-content/themes/custom-theme/assets/js",
"watch": true,
"allowJs": true,
"lib": ["ES2016", "DOM"]
},
"include": [
"wp-content/themes/custom-theme/assets/ts"
],
"exclude": [
"node_modules",
"**/*.spec.ts"
]
}
Currently I have this watch.sh script that works well:
tmux \
new-session 'cd html && tsc' \; \
split-window 'cd html/wp-content/themes && scss --watch custom-theme/assets/scss:custom-theme/assets/css' \; \
split-window 'cd html/wp-content/themes && watchify custom-theme/assets/js/main.js -o custom-theme/assets/js/bundle.js'
I want to replace this script with something like a Browserify build.js file (I prefer build.ts if possible), and I want to use Tsify with Watchify (I understood that Watchify build.js file is similar to the Browserify file).
I have seen this example, but I am not sure if I am on the good road.
I have this not-working build.js file:
const browserify = require("browserify");
const tsify = require("tsify");
browserify()
.plugin(tsify, { allowsJs: true })
.add("wp-content/themes/custom-theme/assets/ts/main.ts")
.bundle()
.on('error', function (error) { console.error(error.toString()) })
.pipe(process.stdout);
It does not even start to run: it says there is a syntax error on line 1 near (.
Any advice is greatly appreciated.
Thank you.
Update 1
The new build.js file:
const watchify = require("watchify");
const tsify = require("tsify");
watchify()
.plugin(tsify, { allowsJs: true })
.add("wp-content/themes/custom-theme/assets/ts/main.ts")
.bundle()
.on('error', function (error) { console.error(error.toString()) })
.pipe(process.stdout);
runs but throws this:
$ node build.js
/.../node_modules/watchify/index.js:14
var cache = b._options.cache;
^
TypeError: Cannot read property '_options' of undefined
at watchify (/.../node_modules/watchify/index.js:14:19)
at Object.<anonymous> (/.../build.js:4:1)
at Module._compile (internal/modules/cjs/loader.js:1147:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1167:10)
at Module.load (internal/modules/cjs/loader.js:996:32)
at Function.Module._load (internal/modules/cjs/loader.js:896:14)
at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:71:12)
at internal/main/run_main_module.js:17:47
Update 2
I ended up using this watch.sh shell script file:
tmux \
new-session 'cd html && tsc' \; \
split-window 'cd html/wp-content/themes; scss --watch custom-theme/assets/scss:custom-theme/assets/css' \; \
split-window 'cd html/wp-content/themes; watchify custom-theme/assets/ts/main.ts -p [ tsify ] -o custom-theme/assets/js/bundle.js -v'
From here I understand that it respects the tsconfig.json file. The only issue is that the require call in main.ts does not return something that VS Code understands well, so I do not have autocompletition support. This is where I still need help. In future I would also like to use a build.js script, if there is anyone who can help me with this.
Now I use ES6 syntax for importing modules everywhere I import something. I also use relative paths to files inside the relevant npm packages in node_modules directory when I import from npm packages.
In tsconfig.json I have these lines besides others:
"target": "ES3",
"lib": ["ES2020", "DOM"],
"module": "CommonJS"
The final working test project is here.
I still have problems with some modules that are not prepaired for ES6 import.

Webpack: Bundle.js - Uncaught ReferenceError: process is not defined

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

phantomjs + webpack not working

npm i -g phantom
/
weak#0.4.1 install C:\Users\muzo0\AppData\Roaming\npm\node_modules\phantom\node_modules\dnode\node_modules\weak
node-gyp rebuild
C:\Users\muzo0\AppData\Roaming\npm\node_modules\phantom\node_modules\dnode\node_modules\weak>if
not defined npm_config_n ode_gyp (node
"C:\DevLibs\nodejs\node_modules\npm\bin\node-gyp-bin\....\node_modules\node-gyp\bin\node-gyp.js"
rebuild ) else (rebuild) Building the projects in this solution one
at a time. To enable parallel build, please add the "/m" switch.
weakref.cc
Creating library C:\Users\muzo0\AppData\Roaming\npm\node_modules\phantom\node_modules\dnode\node_modules\weak\buil
d\Release\weakref.lib and object
C:\Users\muzo0\AppData\Roaming\npm\node_modules\phantom\node_modules\dnode\node_modu
les\weak\build\Release\weakref.exp Generating code Finished
generating code weakref.vcxproj ->
C:\Users\muzo0\AppData\Roaming\npm\node_modules\phantom\node_modules\dnode\node_modules\weak\build
\Release\weakref.node phantom#0.7.2
C:\Users\muzo0\AppData\Roaming\npm\node_modules\phantom ├──
win-spawn#2.0.0 ├── traverse#0.6.6 ├── shoe#0.0.15 (sockjs#0.3.7) └──
dnode#1.2.1 (jsonify#0.0.0, dnode-protocol#0.2.2, weak#0.4.1)
webpack.config.js
module.exports = {
entry: './src/main.js',
output: {
filename: 'dist.js'
},
module: {
loaders: [
{ test: /\.js$/, loader: 'babel', exclude: /node_modules/ },
{ test: /\.json$/, loader: 'json'}
]
},
target: "node"
};
webpack --hot
Hash: d94ab9a8045078efe92c Version: webpack 1.10.0 Time: 2807ms
Asset Size Chunks Chunk Names dist.js 1.28 MB
0 [emitted] main
+ 180 hidden modules
WARNING in ./~/phantom/~/dnode/~/weak/~/bindings/bindings.js Critical
dependencies: 76:22-40 the request of a dependency is an expression
76:43-53 the request of a dependency is an expression #
./~/phantom/~/dnode/~/weak/~/bindings/bindings.js 76:22-40 76:43-53
WARNING in ./~/phantom/~/shoe/~/sockjs/lib/utils.js Module not found:
Error: Cannot resolve module 'rbytes' in
c:\Users\muzo0\Desktop\new_tele_bot\node_modules\phantom\node
_modules\shoe\node_modules\sockjs\lib # ./~/phantom/~/shoe/~/sockjs/lib/utils.js 7:13-30
WARNING in ./~/phantom/~/dnode/~/weak/~/bindings/README.md Module
parse failed:
c:\Users\muzo0\Desktop\new_tele_bot\node_modules\phantom\node_modules\dnode\node_modules\weak\node_
modules\bindings\README.md Line 2: Unexpected token === You may need
an appropriate loader to handle this file type. | node-bindings |
============= | ### Helper module for loading your native module's .node file | # ./~/phantom/~/dnode/~/weak/~/bindings ^./.*$
node dest.js
module.js:338
throw err;
^ Error: Cannot find module 'c:\Users\muzo0\Desktop\new_tele_bot\dest.js'
at Function.Module._resolveFilename (module.js:336:15)
at Function.Module._load (module.js:278:25)
at Function.Module.runMain (module.js:501:10)
at startup (node.js:129:16)
at node.js:814:3
c:\Users\muzo0\Desktop\new_tele_bot>phantomjs
'phantomjs' is not recognized as an internal or external command,
operable program or batch file.
main.js
import phantom from 'phantom';
OS: win 10
npm: 2.7.4

Categories

Resources