The issue is I get the error below when I run my Node/React app.
I had no issues importing images like this with create-react-app, but I want to do server side rendering so I followed a course on pluralsight which involves tooling the webpack and babel yourself.
D:\Repo\WhiteTigerSSR\client\assets\img\clients\kier-logo.png:1 �PNG
SyntaxError: Invalid or unexpected token at wrapSafe (internal/modules/cjs/loader.js:979:16) at Module._compile (internal/modules/cjs/loader.js:1027:27) at Module._extensions..js (internal/modules/cjs/loader.js:1092:10) at Object.newLoader [as .js] (D:\Repo\WhiteTigerSSR\node_modules\pirates\lib\index.js:104:7) at Module.load (internal/modules/cjs/loader.js:928:32) at Function.Module._load (internal/modules/cjs/loader.js:769:14) at Module.require (internal/modules/cjs/loader.js:952:19) at require (internal/modules/cjs/helpers.js:88:18) at Object. (D:\Repo\WhiteTigerSSR\client\client-page/index.js:3:1) at Module._compile (internal/modules/cjs/loader.js:1063:30)
My NodeJS looks like this where I am doing server side rendering. I run babel-node server to run the app. Ignore the data API.
import React from 'react'
import express from 'express';
import {readFileSync} from 'fs'
import {renderToString} from 'react-dom/server'
import {App} from '../client/home-page/index'
const app = new express();
//serve client js file
app.use(express.static("dist"));
app.get("/data",async(_req,res) =>{
res.json(data);
});
app.get('/', async (_req,res) =>
{
const index = readFileSync("public/index.html","utf-8");
//insert this server rendered string into our index file
const rendered = renderToString(<App />);
res.send(index.replace("{{rendered}}",rendered));
//this was used for client side render
//res.send(index);
// res.send(
// '<h1>React is Awesome</h1>'
// )
});
app.listen(7777);
My webpack
const path = require('path');
process.env.BABEL_ENV = "development";
module.exports = {
mode: "development",
target:'web',
entry: {
client: "./client/client.js",
},
output: {
filename: '[name].js',
publicPath:'/',
path: path.resolve(__dirname,"build")
},
resolve: {
extensions: ['.js', '.jsx'],
},
/** can module be omitted for a simple project? No, it cannot. */
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /(node_modules)/,
use: {
loader: 'babel-loader',
options: {
presets: [
'@babel/preset-env',
'@babel/preset-react'
]
}
}
},
{
test: /\.(jpg|png|svg)$/,
loader: 'url-loader',
options: {
limit: 25000,
},
},
{
test: /(\.css)$/,
use: ["style-loader", "css-loader"],
},
{
test: /\.(svg|jpeg|gif|png|jpg|webp)$/,
use: {
loader: 'file-loader',
options: {
name: "[name].[ext]",
outputPath: "images"
}
}
}
]
}
}
Package.json
{
"name": "whitetiger_ssr",
"version": "1.0.0",
"description": "Marketing Website for White Tiger Ltd",
"main": "index.js",
"scripts": {
"test": "echo \no test specfied",
"start": "babel-node server",
"build": "webpack"
},
"author": "Luke Perrin",
"license": "ISC",
"dependencies": {
"bootstrap": "^4.5.3",
"compression": "^1.7.4",
"express": "^4.17.1",
"font-awesome": "^4.7.0",
"ionicons": "^5.3.0",
"jquery": "^3.5.1",
"popper.js": "^1.16.1",
"react": "^17.0.1",
"react-dom": "^17.0.1",
"react-popper": "^2.2.4",
"react-router-dom": "^5.2.0"
},
"devDependencies": {
"@babel/cli": "^7.13.0",
"@babel/core": "^7.7.7",
"@babel/node": "^7.13.0",
"@babel/preset-env": "^7.7.7",
"@babel/preset-react": "^7.7.4",
"babel-loader": "^8.0.6",
"css-loader": "^5.0.0",
"file-loader": "^6.2.0",
"style-loader": "^2.0.0",
"url-loader": "^4.1.1",
"webpack": "^4.41.5",
"webpack-cli": "^4.5.0",
"webpack-dev-server": "^3.10.1"
}
}
In my react component I am importing the image like this
import kier from '../assets/img/clients/kier-logo.png'
And rendering like this..
render() {
return (<div class="container p-4 client-container">
<div class="client-background soft-corner">
<div class="d-flex flex-column marketing-header soft-corner">
<h2 class="text-center center-item">Our Clients</h2>
</div>
</div>
<h3 class="text-center">Construction & Industrial</h3>
<div class="row">
<div class="col-sm-6 col-md-3 text-center d-flex"><img class="img-fluid align-self-center client-logo align-middle" data-toggle="tooltip" data-bs-tooltip="" data-bs-hover-animate="pulse" src={kier} title="Kier Construction" alt="Kier Construction White Tiger Client" /></div>
<div class="col-sm-6 col-md-3 text-center d-flex"><img class="img-fluid align-self-center client-logo" data-toggle="tooltip" data-bs-tooltip="" data-bs-hover-animate="pulse" src={bam} title="Bam Construction" alt="Luton Hoo White Tiger Client" /></div>
<div class="col-sm-6 col-md-3 text-center d-flex"><img class="img-fluid align-self-center client-logo" data-toggle="tooltip" data-bs-tooltip="" data-bs-hover-animate="pulse" src={inter} title="Interserve Construction" alt="Redcoats Famehouse White Tiger Client" /></div>
<div class="col-sm-6 col-md-3 text-center d-flex"><img class="img-fluid align-self-center client-logo" data-toggle="tooltip" data-bs-tooltip="" data-bs-hover-animate="pulse" src={taylor} title="Taylor Wimpey Construction" alt="Taylor Wimpey White Tiger Client" /></div>
</div>
<h3 class="text-center">Hotels & Leisure</h3>
<div class="row">
<div class="col-sm-6 col-md-4 text-center d-flex"><img class="img-fluid align-self-center client-logo" data-toggle="tooltip" data-bs-tooltip="" data-bs-hover-animate="pulse" src={bw} title="Best Western Hotels" alt="Best Western White Tiger Client" /></div>
<div class="col-sm-6 col-md-4 text-center d-flex"><img class="img-fluid align-self-center client-logo" data-toggle="tooltip" data-bs-tooltip="" data-bs-hover-animate="pulse" src={luton} title="Luton Hoo Hotels" alt="Bupa Cromwell Hospital White Tiger Client" /></div>
<div class="col-sm-12 col-md-4 text-center d-flex"><img class="img-fluid align-self-center client-logo" data-toggle="tooltip" data-bs-tooltip="" data-bs-hover-animate="pulse" src={redcoats} title="Redcoats Hotel and Restaurant" alt="Interserve White Tiger Client" /></div>
</div>
<h3 class="text-center">Hospitals</h3>
<div class="row">
<div class="col-md-12 text-center"><img class="rounded img-fluid client-logo" data-toggle="tooltip" data-bs-tooltip="" data-bs-hover-animate="pulse" src={bupa} alt="Bupa Cromwell Hospital White TIger Client" title="Bupa – Cromwell Hospital London" /></div>
</div>
</div>
)
}
This is the entry point in the app
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter as Router } from "react-router-dom";
import {App} from './home-page/index'
import { clickhander } from '../shared/utility'
ReactDOM.hydrate(
<Router >
<App />
</Router>,
document.getElementById('root'));
This is the main body in index.html
<body>
<div id="root">{{rendered}}</div>
<script src="client.js"></script>
<!-- comment out script for pure server rendered markup -->
</body>