Unable to import image in react app "Invalid or unexpected token"

Viewed 715

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 &amp; 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 &amp; 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>
1 Answers

To resolve error "SyntaxError: Invalid or unexpected token" regarding CSS on server side node.js install css-modules-transform with dev dependency

npm install css-modules-transform --save-dev

and at .bablerc add

{
"plugins": ["css-modules-transform"]
}

To resolve error "SyntaxError: Invalid or unexpected token" regarding Files on server side node.js install babel-plugin-file-loader with dev dependency

npm install babel-plugin-file-loader --save-dev

and at .bablerc add

{
"plugins": ["css-modules-transform", "file-loader"]
} 

finally run with babel-node

"scripts": {    "dev": "nodemon --exec babel-node src/server.js"}
Related