setup webpack config in nextJS (next.config.js) - node.js

I'm working with NextJS and using react-data-export plugin to generate xls files.
in the description it says :
This library uses file-saver and xlsx and using
json-loader will do the magic for you.
///webpack.config.js
vendor: [
.....
'xlsx',
'file-saver'
],
.....
node: {fs: 'empty'},
externals: [
{'./cptable': 'var cptable'},
{'./jszip': 'jszip'}
]
but I have no idea how to implement it and got error like this :
The static directory has been deprecated in favor of the public directory. https://err.sh/vercel/next.js/static-dir-deprecated
Defining routes from exportPathMap
event - compiled successfully
> Ready on http://localhost:80 or http://localhost
> Ready on https://localhost:443 or https://localhost
event - build page: /menu_accounting/ReportGross
wait - compiling...
error - ./node_modules/react-export-excel/node_modules/xlsx/xlsx.js
Module not found: Can't resolve 'fs' in '/home/ahmadb/repos/lorry-erp/node_modules/react-export-excel/node_modules/xlsx'
Could not find files for /menu_accounting/ReportGross in .next/build-manifest.json

I had the same problem, the solution for me was this:
Install this packages (if you installed, ignored this)
npm install file-saver --save
npm install xlsx
npm install --save-dev json-loader
Add this to your nextjs.config.js
const path = require('path')
module.exports = {
...
//Add this lines
webpack: (config, { isServer }) => {
// Fixes npm packages that depend on `fs` module
if (!isServer) {
config.node = {
fs: 'empty'
}
}
return config
}
}

Related

ERR_REQUIRE_ESM from webpack's importing an ESM package

I am building an app using Nx for modularisation and Geckos for the server part. With Nx' default Webpack 5 config for Node I get this error when running the app:
/Users/hgrzeskowiak/hugo-game/fresh-nx-geckos/nx-geckos-test/dist/apps/geckos-server-app/main.js:8
module.exports = require("#geckos.io/server");
^
Error [ERR_REQUIRE_ESM]: require() of ES Module /Users/hgrzeskowiak/hugo-game/fresh-nx-geckos/nx-geckos-test/node_modules/#geckos.io/server/lib/index.js from /Users/hgrzeskowiak/hugo-game/fresh-nx-geckos/nx-geckos-test/dist/apps/geckos-server-app/main.js not supported.
Instead change the require of index.js in /Users/hgrzeskowiak/hugo-game/fresh-nx-geckos/nx-geckos-test/dist/apps/geckos-server-app/main.js to a dynamic import() which is available in all CommonJS modules.
(...)
Here are steps to reproduce:
$ npx create-nx-workspace#latest nx-geckos-test
Need to install the following packages:
create-nx-workspace#latest
Ok to proceed? (y) y
✔ What to create in the new workspace · express
✔ Application name · geckos-server-app
✔ Use Nx Cloud? (It's free and doesn't require registration.) · No
> NX Nx is creating your v13.4.1 workspace.
To make sure the command works reliably in all environments, and that the preset is applied correctly,
Nx will run "npm install" several times. Please wait.
✔ Installing dependencies with npm
✔ Nx has successfully created the workspace.
$ npm run start
> nx-geckos-test#0.0.0 start
> nx serve
> nx run geckos-server-app:serve
chunk (runtime: main) main.js (main) 552 bytes [entry] [rendered]
webpack compiled successfully (26ac6f288b082854)
Debugger listening on ws://localhost:9229/70a1d9b4-af2b-4fc9-90f7-f3502e5fdf2e
Debugger listening on ws://localhost:9229/70a1d9b4-af2b-4fc9-90f7-f3502e5fdf2e
For help, see: https://nodejs.org/en/docs/inspector
Issues checking in progress...
Listening at http://localhost:3333/api
At this stage, the default Express app builds and runs.
Now I replace the contents of apps/geckos-server-app/src/main.ts to the Geckos server example from the README:
import geckos from '#geckos.io/server'
const io = geckos()
io.listen(3000) // default port is 9208
io.onConnection(channel => {
channel.onDisconnect(() => {
console.log(`${channel.id} got disconnected`)
})
channel.on('chat message', data => {
console.log(`got ${data} from "chat message"`)
// emit the "chat message" data to all channels in the same room
io.room(channel.roomId).emit('chat message', data)
})
})
...and install the geckos server package using
$ npm install #geckos.io/server
added 4 packages, and audited 785 packages in 7s
87 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
Ok, time to run it again:
$ npm run start
> nx-geckos-test#0.0.0 start
> nx serve
> nx run geckos-server-app:serve
chunk (runtime: main) main.js (main) 610 bytes [entry] [rendered]
webpack compiled successfully (90920432a9d246ea)
Debugger listening on ws://localhost:9229/dc6d9e1a-1a15-432f-a46c-d2ac83b923ea
Debugger listening on ws://localhost:9229/dc6d9e1a-1a15-432f-a46c-d2ac83b923ea
For help, see: https://nodejs.org/en/docs/inspector
/Users/hgrzeskowiak/hugo-game/fresh-nx-geckos/nx-geckos-test/dist/apps/geckos-server-app/main.js:8
module.exports = require("#geckos.io/server");
^
Error [ERR_REQUIRE_ESM]: require() of ES Module /Users/hgrzeskowiak/hugo-game/fresh-nx-geckos/nx-geckos-test/node_modules/#geckos.io/server/lib/index.js from /Users/hgrzeskowiak/hugo-game/fresh-nx-geckos/nx-geckos-test/dist/apps/geckos-server-app/main.js not supported.
Instead change the require of index.js in /Users/hgrzeskowiak/hugo-game/fresh-nx-geckos/nx-geckos-test/dist/apps/geckos-server-app/main.js to a dynamic import() which is available in all CommonJS modules.
at Object.#geckos.io/server (/Users/hgrzeskowiak/hugo-game/fresh-nx-geckos/nx-geckos-test/dist/apps/geckos-server-app/main.js:8:18)
at __webpack_require__ (/Users/hgrzeskowiak/hugo-game/fresh-nx-geckos/nx-geckos-test/dist/apps/geckos-server-app/main.js:32:41)
at /Users/hgrzeskowiak/hugo-game/fresh-nx-geckos/nx-geckos-test/dist/apps/geckos-server-app/main.js:45:18
at /Users/hgrzeskowiak/hugo-game/fresh-nx-geckos/nx-geckos-test/dist/apps/geckos-server-app/main.js:59:3
at Object.<anonymous> (/Users/hgrzeskowiak/hugo-game/fresh-nx-geckos/nx-geckos-test/dist/apps/geckos-server-app/main.js:64:12)
I tested quite a few Webpack config overrides and using type: "module" in package.json, but to no avail. The output main.js looks mostly the same no matter what webpack settings I change. Things I tried changing in the app's webpack override config:
module.exports = function(webpackConfig, context) {
webpackConfig.target = "async-node16";
webpackConfig.output.libraryTarget = "module";
webpackConfig.output.library = {type: "module"};
webpackConfig.output.chunkFormat = "module";
webpackConfig.experiments.outputModule = true;
console.log("webpack config:");
console.log(webpackConfig);
console.log("module rules:");
console.log(webpackConfig.module.rules);
return webpackConfig;
}
The console logs in the config verify that the script is being run.
The app works when I manually change the require to import in the transpiled output, but that's not a sustainable solution.
I suspect the error has something to do with Geckos being an ESM package, and Webpack only using require instead of import as it should, but I couldn't find any way of changing that behaviour.
Any ideas?
Node version 16.13.0
Nx version 13.4.1
Webpack (transitive dep of Nx): 5.65.0
Here's the cleanest solution I could find that works with Type Script versions older than 4.6 (which should add support for this feature). This is essentially patching ESM support into WebPack with older TypeScript versions (including latest at the time of writing).
A custom Webpack plugin that changes the type of the external module to import.
// TypeScript before version 4.6 does not support transpiling ESM imports to
// `import()`, but uses `require()` instead. NodeJS does not support the use
// of `require() for ECMAScript modules (ESM).
//
// Good reads:
// https://www.typescriptlang.org/docs/handbook/esm-node.html
// https://devblogs.microsoft.com/typescript/announcing-typescript-4-5/#esm-nodejs
/**
* A Webpack 5 plugin that can be passed a list of packages that are of type
* ESM. The typescript compiler will then be instructed to use the `import`
* external type.
*/
class ESMLoader {
static defaultOptions = {
esmPackages: "all"
};
constructor(options = {}) {
this.options = { ...ESMLoader.defaultOptions, ...options };
}
apply(compiler) {
compiler.hooks.compilation.tap(
"ECMAScript Module (ESM) Loader. Turns require() into import()",
(
compilation
) => {
compilation.hooks.buildModule.tap("Hello World Plugin", (module) => {
if (
module.type === "javascript/dynamic" &&
(
this.options.esmPackages === "all" ||
this.options.esmPackages.includes(module.request)
)
) {
// All types documented at
// https://webpack.js.org/configuration/externals/#externalstype
module.externalType = "import";
}
}
)
;
}
);
}
}
module.exports = function(webpackConfig, context) {
// NodeJS supports dynamic imports since version 12.
webpackConfig.target = "node16";
webpackConfig.plugins.push(
// Manually specify the ESM modules or leave blank for using `import()`
// on all packages.
//new ESMLoader()
new ESMLoader({esmPackages: "#geckos.io/server"})
);
return webpackConfig;
};
The custom webpack config can be set on an Nx app through the project.json:
{
"targets": {
"build": {
"executor": "#nrwl/node:build",
"options": {
...
"webpackConfig": "apps/your-app/webpackConfig.js"
},
...
This solution also requires tsconfig.json to have set the module type to something more modern than commonjs, e.g. es2020:
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../../dist/out-tsc",
"module": "es2020",
"types": ["node"],
},
"exclude": ["**/*.spec.ts", "**/*.test.ts"],
"include": ["**/*.ts"]
}
Once this is done, the built file can be ran using the usual nx serve.

Couldn't import web3 library in react application

ERROR in ./node_modules/cipher-base/index.js 3:16-43
Module not found: Error: Can't resolve 'stream' in 'C:\Users\Sumana\Desktop\Web3\web3app\node_modules\cipher-base'
BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.
If you want to include a polyfill, you need to:
- add a fallback 'resolve.fallback: { "stream": require.resolve("stream-browserify") }'
- install 'stream-browserify'
If you don't want to include a polyfill, you can use an empty module like this:
resolve.fallback: { "stream": false }
You can fix this issue in 2 way .
Delete node_module then change your react-scripts version from "5.0.0" to "4.0.3" after that run npm install.
or
Configure webpack.
1 - install these packages .
npm install fs assert https-browserify os os-browserify stream-browserify stream-http react-app-rewired
2 - Create config-coverrides.js in Root dir of your project next to the package.json
const webpack = require('webpack');
module.exports = function override(config, env) {
config.resolve.fallback = {
url: require.resolve('url'),
fs: require.resolve('fs'),
assert: require.resolve('assert'),
crypto: require.resolve('crypto-browserify'),
http: require.resolve('stream-http'),
https: require.resolve('https-browserify'),
os: require.resolve('os-browserify/browser'),
buffer: require.resolve('buffer'),
stream: require.resolve('stream-browserify'),
};
config.plugins.push(
new webpack.ProvidePlugin({
process: 'process/browser',
Buffer: ['buffer', 'Buffer'],
}),
);
return config;
}
I have had this issue for the last week too. It has been documented in many place like this. I don't understand how to fix it but it seems like the people who made the library will fix it https://github.com/ChainSafe/web3.js/issues/4659
Install the polyfills for node.JS and adding two things to webpack.config.js:
npm install node-polyfill-webpack-plugin
In the file [node_modules > react-scripts > config > webpack.config.js] add:
const NodePolyfillPlugin = require('node-polyfill-webpack-plugin');
module.exports > return > plugins:
plugins: [
new NodePolyfillPlugin(),
……………
]
More on the solution:
https://github.com/Richienb/node-polyfill-webpack-plugin#readme

npm package.json aliases like webpack

i am trying to alias a module however i am not sure how to do that with package.json
in webpack you would do something like this:
module.exports = {
//...
resolve: {
alias: {
'pixi.js': 'pixi.js-legacy'
}
}
};
But what is the equivalent without webpack?
Since NPM Version 6.9 of March 2019 it is supported without installing any additional packages (see the RFC):
npm i aliasName#npm:packageToInstall
⬇⬇⬇
// package.json
"dependencies": {
"aliasName": "npm:packageToInstall#^1.6.1"
}
The idea seems to be that npm: is a URI-like scheme in a dependency version specifier.
Usage:
const alias = require( 'aliasName' );
There is a npm package for this: module-alias.
After installing it you can add your aliases to the package.json, like so:
"_moduleAliases": {
"#root" : ".", // Application's root
"#deep" : "src/some/very/deep/directory/or/file",
"#my_module" : "lib/some-file.js",
"something" : "src/foo", // Or without #. Actually, it could be any string
}
Make sure to add this line at the top of your app's main file:
require('module-alias/register');
You should only use this in final products (and not packages you intend to publish in npm or use elsewhere) - it modifies the behavior of require.

Unable to implement webpack in project with node-red

I am trying to implement webpack in my project which contains node-red. However, I keep getting the following warning. Please suggest how to solve this error -
WARNING in ./node_modules/node-red/red/runtime/storage/localfilesystem/projects/git/node-red-ask-pass.sh 1:26
Module parse failed: Unexpected token (1:26)
You may need an appropriate loader to handle this file type.
> "$NODE_RED_GIT_NODE_PATH" "$NODE_RED_GIT_ASKPASS_PATH" "$NODE_RED_GIT_SOCK_PATH" $#
|
# ./node_modules/node-red/red/runtime/storage sync ^\.\/.*$ ./localfilesystem/projects/git/node-red-ask-pass.sh
# ./node_modules/node-red/red/runtime/storage/index.js
# ./node_modules/node-red/red/runtime/index.js
# ./app.js
My webpack.config.js is -
const path = require('path');
var nodeExternals = require('webpack-node-externals');
module.exports = {
target: 'node',
externals: [nodeExternals()],
entry: './app.js',
output: {
path: path.resolve(__dirname, './output'),
filename: 'bundle.js'
},
resolve: {
extensions: ['.js','.json', '.sh'],
modules: [
'node_modules'
],
},
module: {
rules: [
{
test:/\.css$/,
use:['style-loader','css-loader']
},
{
test: /\.coffee$/,
use: [ 'coffee-loader' ]
}
]
}
};
For Webpack, every file is a .js. In order to handle other extensions, like .css or .sh, you're supposed to use a loader, like you did with css-loader, that will tranform CSS rules into JS.
The issue you're facing is that you've got an import chain (./app.js -> .../index.js -> .../index.js -> .../node-red-ask-pass.sh), so Webpack will, at some point, will import a .sh file, but will throw an error because shell code is obviousouly invalid JavaScript. that is why you're seeing the error that you have.
By the way, I couldn't reproduce the issue you're facing:
npm init -y
npm i node-red
# ./node_modules/node-red/red is not a directory
So it was probably a node-red bug. Update the package to the latest version.

Slack Integraton with Laravel Issues

I am trying to install slack node library, but not able to do it successfully.
I installed this library successfully on laravel 5.4 using node js. And my gulpfile is upgraded from 5.3 to 5.4 and attached below.
npm install #slack/client --save (Installation is fine but gukp is causing issue)
But when i run gulp command on shell i am getting following error:-
After adding adding this line in app.js:-
var RtmClient = require('#slack/client').RtmClient;
gulpfile.js (manually eddited)
const elixir = require('laravel-elixir');
const path = require('path');
const debug = require('gulp-debug');
const moment = require('moment');// in my gulp file
require('laravel-elixir-webpack-official');
require('laravel-elixir-vue-2');
elixir(function(mix) {
// Elixir.webpack.config.module.loaders = [];
Elixir.webpack.mergeConfig({
resolveLoader: {
root: path.join(__dirname, 'node_modules'),
},
module: {
loaders: [
{
test: /\.css$/,
loader: 'style!css'
}
]
}
});
mix.sass('app.scss')
.webpack('app.js')
.copy('node_modules/bootstrap-sass/assets/fonts/bootstrap/','public/fonts/bootstrap')
});
Error on Gulp Command
user1#console:/opt/lampp/htdocs/dev$ gulp
[15:40:27] Using gulpfile /opt/lampp/htdocs/dev/gulpfile.js
[15:40:27] Starting 'all'...
[15:40:27] Starting 'sass'...
[15:40:28] Finished 'sass' after 1.08 s
[15:40:28] Starting 'webpack'...
{ [Error: ./~/winston/package.json
Module parse failed: /opt/lampp/htdocs/dev/node_modules/winston/package.json Unexpected token (2:9)
You may need an appropriate loader to handle this file type.
| {
| "_args": [
| [
| {
# ./~/winston/lib/winston.js 14:18-44
# ./~/#slack/client/lib/helpers.js
# ./~/#slack/client/lib/clients/client.js
# ./~/#slack/client/lib/clients/web/client.js
# ./~/#slack/client/index.js
# ./resources/assets/js/app.js./~/winston/lib/winston/common.js
Module not found: Error: Can't resolve 'fs' in '/opt/lampp/htdocs/dev/node_modules/winston/lib/winston'
resolve 'fs' in '/opt/lampp/htdocs/dev/node_modules/winston/lib/winston'
Parsed request is a module
using description file: /opt/lampp/htdocs/dev/node_modules/winston/package.json (relative path: ./lib/winston)
Field 'browser' doesn't contain a valid alias configuration
after using description file: /opt/lampp/htdocs/dev/node_modules/winston/package.json (relative path: ./lib/winston)
resolve as module
/opt/lampp/htdocs/dev/node_modules/node_modules doesn't exist or is not a directory
Thanks in advance

Resources