Working with Experience Builder developer edition v1.6. Try to use react-pdf in customized widget to generate pdf file with the react component.
But when install the react-pdf as instructed in following link, got a lot errors.
https://github.com/diegomura/react-pdf
Question is how to add following configuration into current webpack.config.js file under folder client?
Configuration:
resolve: { fallback: { process: require.resolve("process/browser"), zlib: require.resolve("browserify-zlib"), stream: require.resolve("stream-browserify"), util: require.resolve("util"), buffer: require.resolve("buffer"), asset: require.resolve("assert"), } }, plugins: [ new webpack.ProvidePlugin({ Buffer: ["buffer", "Buffer"], process: "process/browser", }), ]
Content of webpack.config.js under folder client:
const extensionsConfig = require('./webpack/webpack-extensions.config');
if(extensionsConfig.length === 0){
console.warn('You have to have at least one widget/theme.');
return;
}
module.exports = extensionsConfig;
Solved! Go to Solution.
Thank you very much @Junshan_Liu and @ShaunLangley . Finally installed it successfully, and here is the steps:
1. Open Command Prompt, go to Experience Builder folder /client, run following commands:
npm install @react-pdf/renderer -S
npm install process browserify-zlib stream-browserify util buffer assert -S
npm install iconv-lite -S
npm install https-browserify -S
npm install url -S
npm install stream-http -S
2. Open file webpack-extensions.common.js under /client/wepack, modify function getWidgetsWebpackConfig, add following part to "resolve":
fallback: {
process: require.resolve("process/browser"),
zlib: require.resolve("browserify-zlib"),
stream: require.resolve("stream-browserify"),
util: require.resolve("util"),
buffer: require.resolve("buffer"),
asset: require.resolve("assert"),
https: require.resolve("https-browserify"),
url: require.resolve("url/"),
http: require.resolve("stream-http")
add following part to plguins:
new webpack.ProvidePlugin({
Buffer: ["buffer", "Buffer"],
process: "process/browser",
}),
Here is the one works after modification:
The solution is quite involved. In short, you need to use craco on top of webpack to get this to work.
here is my (working) configuration:
webpack.config.js
const webpack = require('webpack')
const path = require('path')
module.exports = {
entry: './src/index.js',
mode: 'development',
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /(node_modules)/,
loader: 'babel-loader',
options: { presets: ['@babel/env', '@babel/preset-react'] },
},
{
test: /\.(css)$/,
use: ['style-loader', 'css-loader'],
},
{
test: /\.scss$/,
use: ['sass-loader'],
},
],
},
resolve: {
extensions: ['*', '.js', '.jsx'],
fallback: {
module: 'empty',
dgram: 'empty',
dns: 'mock',
fs: 'empty',
http2: 'empty',
net: 'empty',
tls: 'empty',
child_process: 'empty',
process: require.resolve('process/browser'),
zlib: require.resolve('browserify-zlib'),
stream: require.resolve('stream-browserify'),
util: require.resolve('util'),
buffer: require.resolve('buffer'),
asset: require.resolve('assert'),
},
},
output: {
path: path.resolve(__dirname, 'dist/'),
publicPath: '/dist/',
filename: 'bundle.js',
},
devServer: {
static: path.join(__dirname, 'public/'),
port: 3000,
compress: true,
historyApiFallback: true,
hot: true,
},
plugins: [
new webpack.ProvidePlugin({
Buffer: ['buffer', 'Buffer'],
process: 'process/browser',
}),
],
}
craco.config.js
const NodePolyfillPlugin = require("node-polyfill-webpack-plugin");
module.exports = {
webpack: {
plugins: {
add: [
new NodePolyfillPlugin({
excludeAliases: ["console"],
}),
],
},
},
};
package.json dependencies (not all relevant to your case)
"dependencies": {
"@babel/cli": "^7.17.6",
"@babel/core": "^7.17.8",
"@babel/preset-env": "^7.16.11",
"@babel/preset-react": "^7.16.7",
"@craco/craco": "^6.4.3",
"@devbookhq/splitter": "^1.3.2",
"@material-ui/core": "^4.12.3",
"@react-pdf/renderer": "^2.1.1",
"@testing-library/jest-dom": "^5.14.1",
"@testing-library/react": "^12.0.0",
"@testing-library/user-event": "^13.2.1",
"ag-grid-community": "^27.1.0",
"ag-grid-react": "^27.1.0",
"assert": "^2.0.0",
"babel-loader": "^8.2.4",
"bootstrap": "^5.1.3",
"browserify-zlib": "^0.2.0",
"buffer": "^6.0.3",
"craco": "^0.0.3",
"css-loader": "^6.7.1",
"firebase": "^9.6.10",
"node-polyfill-webpack-plugin": "^1.1.4",
"process": "^0.11.10",
"react": "^17.0.2",
"react-apexcharts": "^1.4.0",
"react-bootstrap": "^2.2.2",
"react-dom": "^17.0.2",
"react-hook-form": "^7.28.1",
"react-icons": "^4.3.1",
"react-router-dom": "^6.2.2",
"react-scripts": "^5.0.0",
"react-table": "^7.7.0",
"sass": "^1.49.9",
"sass-loader": "^12.6.0",
"stream-browserify": "^3.0.0",
"style-loader": "^3.3.1",
"styled-components": "^5.3.5",
"util": "^0.12.4",
"web-vitals": "^2.1.4",
"webpack": "^5.71.0",
"webpack-cli": "^4.9.2",
"webpack-dev-server": "^4.7.4"
},
you might consider html2pdf as a better alternative. I found it a bit easier to setup but of course not as flexible to use. So there's a tradeoff there
Thank you very much for the help. Let me try react-pdf first, if still failed to setup, then switch to html2pdf :).
For the config "entry: './src/index.js'" in the webpack.config.js, the file index.js is you manually created? I mean by default the Experience Builder doesn't have that file, correct?
you'll have to merge the webpack config code. I didn't implement my solution in the context of exb. Post your code if you can't get it to work and we can troubleshoot
Hello @JunshanLiu, can you please help on this? How to merge following part
resolve: { fallback: { process: require.resolve("process/browser"), zlib: require.resolve("browserify-zlib"), stream: require.resolve("stream-browserify"), util: require.resolve("util"), buffer: require.resolve("buffer"), asset: require.resolve("assert"), } }, plugins: [ new webpack.ProvidePlugin({ Buffer: ["buffer", "Buffer"], process: "process/browser", }), ]
to default ArcGIS Experience builder webpack.config.js that has following content?:
const extensionsConfig = require('./webpack/webpack-extensions.config');
if(extensionsConfig.length === 0){
console.warn('You have to have at least one widget/theme.');
return;
}
module.exports = extensionsConfig;
you'll probably have to edit webpack-extensions.config. I'm going to try on my end but post something if you get it working.
Hi, You can edit the "getWidgetsWebpackConfig" method in "webpack-extensions.common.js"
Thank you very much @Junshan_Liu and @ShaunLangley . Finally installed it successfully, and here is the steps:
1. Open Command Prompt, go to Experience Builder folder /client, run following commands:
npm install @react-pdf/renderer -S
npm install process browserify-zlib stream-browserify util buffer assert -S
npm install iconv-lite -S
npm install https-browserify -S
npm install url -S
npm install stream-http -S
2. Open file webpack-extensions.common.js under /client/wepack, modify function getWidgetsWebpackConfig, add following part to "resolve":
fallback: {
process: require.resolve("process/browser"),
zlib: require.resolve("browserify-zlib"),
stream: require.resolve("stream-browserify"),
util: require.resolve("util"),
buffer: require.resolve("buffer"),
asset: require.resolve("assert"),
https: require.resolve("https-browserify"),
url: require.resolve("url/"),
http: require.resolve("stream-http")
add following part to plguins:
new webpack.ProvidePlugin({
Buffer: ["buffer", "Buffer"],
process: "process/browser",
}),
Here is the one works after modification:
Nice work! Thanks for letting us know how you solved it.