I am trying to create a react app and connect it run it on the internet computer. I am seeing an error when I try and get it to render my index.js file which contains the .js and .jsx components I have made, but it seems to work with the index.html standard file.
I have the entry path defined in webpack.config.js;
const frontend_entry = path.join("src", frontendDirectory, "src", "index.html");
module.exports = {
target: "web",
mode: isDevelopment ? "development" : "production",
entry: {
// The frontend.entrypoint points to the HTML file for this build, so we need
// to replace the extension to `.js`.
index: path.join(__dirname, frontend_entry).replace(/\.html$/, ".js"),
},
this does not seem to work and when I instead comment out the entry path.join etc and manually change the entry to index.js in frontend_entry I see this error;
Html Webpack Plugin:
Error: document is not defined
- index.js:33792 Object.insertStyleElement
/Users/isaacdugdale/Desktop/SmartBet/Vault/VaultBetI nitial/ICVault/src/ICVault_frontend/src/index.js:337 92:17
- index.js:33887 Object.domAPI
/Users/isaacdugdale/Desktop/SmartBet/Vault/VaultBetI nitial/ICVault/src/ICVault_frontend/src/index.js:338 87:30
- index.js:33683 addElementStyle
/Users/isaacdugdale/Desktop/SmartBet/Vault/VaultBetI nitial/ICVault/src/ICVault_frontend/src/index.js:336 83:21
- index.js:33667 modulesToDom
/Users/isaacdugdale/Desktop/SmartBet/Vault/VaultBetI nitial/ICVault/src/ICVault_frontend/src/index.js:336 67:21
The full code for my webpack.config.js file is
const path = require("path");
const webpack = require("webpack");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const TerserPlugin = require("terser-webpack-plugin");
function initCanisterEnv() {
let localCanisters, prodCanisters;
try {
localCanisters = require(path.resolve(
".dfx",
"local",
"canister_ids.json"
));
} catch (error) {
console.log("No local canister_ids.json found. Continuing production");
}
try {
prodCanisters = require(path.resolve("canister_ids.json"));
} catch (error) {
console.log("No production canister_ids.json found. Continuing with local");
}
const network =
process.env.DFX_NETWORK ||
(process.env.NODE_ENV === "production" ? "ic" : "local");
const canisterConfig = network === "local" ? localCanisters : prodCanisters;
return Object.entries(canisterConfig).reduce((prev, current) => {
const [canisterName, canisterDetails] = current;
prev[canisterName.toUpperCase() + "_CANISTER_ID"] =
canisterDetails[network];
return prev;
}, {});
}
const canisterEnvVariables = initCanisterEnv();
const isDevelopment = process.env.NODE_ENV !== "production";
const frontendDirectory = "ICVault_frontend";
const frontend_entry = path.join("src", frontendDirectory, "src", "index.html");
module.exports = {
target: "web",
mode: isDevelopment ? "development" : "production",
entry: {
// The frontend.entrypoint points to the HTML file for this build, so we need
// to replace the extension to `.js`.
index: path.join(__dirname, frontend_entry).replace(/\.html$/, ".js"),
},
devtool: isDevelopment ? "source-map" : false,
optimization: {
minimize: !isDevelopment,
minimizer: [new TerserPlugin()],
},
resolve: {
extensions: [".js", ".ts", ".jsx", ".tsx"],
fallback: {
assert: require.resolve("assert/"),
buffer: require.resolve("buffer/"),
events: require.resolve("events/"),
stream: require.resolve("stream-browserify/"),
util: require.resolve("util/"),
},
},
output: {
filename: "index.js",
path: path.join(__dirname, "dist", frontendDirectory),
},
// Depending in the language or framework you are using for
// front-end development, add module loaders to the default
// webpack configuration. For example, if you are using React
// modules and CSS as described in the "Adding a stylesheet"
// tutorial, uncomment the following lines:
module: {
rules: [
{ test: /\.(ts|tsx|jsx)$/, loader: "ts-loader" },
{ test: /\.css$/, use: ['style-loader','css-loader'] },
{
test: /\.m?js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: [
['@babel/preset-env', { targets: "defaults" }],
['@babel/preset-react', { targets: "defaults" }],
]
}
}
},
{
test: /\.(jpe?g|png|gif|svg)$/i,
loader: 'file-loader',
options: {
name: '/public/icons/[name].[ext]'
}
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: path.join(__dirname, frontend_entry),
cache: false,
}),
new webpack.EnvironmentPlugin({
NODE_ENV: "development",
...canisterEnvVariables,
}),
new webpack.ProvidePlugin({
Buffer: [require.resolve("buffer/"), "Buffer"],
process: require.resolve("process/browser"),
}),
],
// proxy /api to port 8000 during development
devServer: {
proxy: {
"/api": {
target: "http://127.0.0.1:8000",
changeOrigin: true,
pathRewrite: {
"^/api": "/api",
},
},
},
static: path.resolve(__dirname, "src", frontendDirectory, "assets"),
hot: true,
watchFiles: [path.resolve(__dirname, "src", frontendDirectory)],
liveReload: true,
},
};
and index.js is
import React from 'react';
import { BrowserRouter, Route, Routes } from 'react-router-dom'
import './index.css';
import ReactDOM from 'react-dom/client';
import About from "./pages/about";
import Navbar from './pages/components/Navbar'
import Footer from "./pages/components/Footer"
// document.querySelector("form").addEventListener("submit", async (e) => {
// return false;
// });
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<header class="sticky top-0 z-50">< Navbar /></header>
<BrowserRouter>
<Routes>
<Route path="/" element={<About />} />
<Route path="/about" element={<About />} />
</Routes>
</BrowserRouter>
<footer class="fixed bottom-0 w-full z-50">
< Footer/>
</footer>
</React.StrictMode>
);
Any help would be very very much appreciated, thanks!