skip to Main Content

When I run ‘npm run build’ I get the following error:

> [email protected] build
> react-scripts build

Creating an optimized production build...
Failed to compile.

Unexpected end of JSON input

However, ‘npm start’ works and the website works locally. This issue only arises when I run ‘npm run build’

I’ve tried a variety of things to fix this issue, rebuilding after each (and trying all of them and then rebuilding):

  • cleared build cache
  • cleared npm cache
  • deleted and reinstalled node modules, package-lock.json and package.json
  • Created a new react app and copied the files over

My package.json passes jsonlint, and I cannot figure out the issue
But nothing is working. Here are my files:
package.json:

{
  "homepage": "http://[redacted].github.io/",
  "name": "my-website",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "framer-motion": "^10.16.4",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-icons": "^4.11.0",
    "react-scripts": "5.0.1"
  },
  "scripts": {
    "start": "react-scripts start",
    "predeploy": "npm run build",
    "deploy": "gh-pages -d build",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  },
  "devDependencies": {
    "autoprefixer": "^10.4.14",
    "gh-pages": "^6.1.1",
    "postcss": "^8.4.23",
    "tailwindcss": "^3.3.5"
  }
}

webpack.config.js

const path = require('path');

module.exports = {
  entry: './src/index.js',
  output: {
    path: path.resolve(__dirname, 'build'),
    filename: 'bundle.js',
  },
  module: {
    rules: [
      {
        test: /.(js|jsx)$/,
        exclude: /node_modules/,
        use: ['babel-loader'],
      },
      {
        test: /.css$/,
        use: ['style-loader', 'css-loader', 'postcss-loader'],
      },
    ],
  },
  resolve: {
    extensions: ['*', '.js', '.jsx'],
  },
};

tailwind.config.js:

/** @type {import('tailwindcss').Config} */
module.exports = {
  content: ["./src/**/*.{js,jsx,ts,tsx}"],
  theme: {
    extend: {},
  },
  plugins: [],
}

App.js:

import React from 'react';
import HomePage from './components/Homepage';

function App() {
  return (
    <div className="App">
      <HomePage />
    </div>
  );
}

export default App;

Homepage.js:

import React, { useEffect, useRef, useState } from 'react';
import { motion, useScroll, useSpring } from 'framer-motion';
import HeroSection from './HeroSection';
import AboutSection from './AboutSection';
import ProjectsSection from './ProjectsSection';
import SkillsSection from './SkillsSection';
import './styles.css';

const Home = () => {
  const [arrowSize, setArrowSize] = useState(window.innerHeight / 6);
  const heroSectionRef = useRef(null);
  const [showName, setShowName] = useState(true);
  const [nameSize, setNameSize] = useState('text-4xl sm:text-6xl');

  const { scrollY } = useScroll();
  const scaleX = useSpring(scrollY, {
    stiffness: 100,
    damping: 30,
    restDelta: 0.001
  });

  useEffect(() => {
    return scrollY.onChange((latest) => {
      if (latest > 0) {
        setShowName(false);
      } else {
        setShowName(true);
      }
    });
  }, [scrollY]);

  useEffect(() => {
    const handleResize = () => {
      const screenWidth = window.innerWidth;
      if (screenWidth < 640) {
        setNameSize('text-2xl');
      } else {
        setNameSize('text-4xl sm:text-6xl');
      }
    };

    handleResize(); // Initial calculation
    window.addEventListener('resize', handleResize); // Recalculate on window resize

    return () => {
      window.removeEventListener('resize', handleResize);
    };
  }, []);

  useEffect(() => {
    const arrowObserver = new IntersectionObserver(
      ([entry]) => {
        if (entry.isIntersecting) {
          const newSize = window.innerHeight / 6;
          setArrowSize(newSize);
        }
      },
      { threshold: [0, 0.5, 1] }
    );

    if (heroSectionRef.current) {
      arrowObserver.observe(heroSectionRef.current);
    }

    return () => {
      if (heroSectionRef.current) {
        arrowObserver.unobserve(heroSectionRef.current);
      }
    };
  }, []);

  return (
    <div className="snap-y snap-mandatory h-screen overflow-y-scroll">
      {showName && (
        <motion.div
          className="fixed top-2 right-2 p-5 text-orange-500 z-50"
          initial={{ opacity: 0, scale: 0.5 }}
          animate={{ opacity: 1, scale: 0.7 }}
          transition={{
            duration: 0.8,
            delay: 0.5,
            ease: [0, 0.71, 0.2, 1.01]
          }}
        >
          <h1 className={nameSize}>[MY NAME]</h1>
        </motion.div>
      )}

      {/* <HeroSection arrowSize={arrowSize} />
      <AboutSection arrowSize={arrowSize} />
      <ProjectsSection arrowSize={arrowSize} />
      <SkillsSection arrowSize={arrowSize} />
      <motion.div className="progress" style={{ scaleX }} /> */}
    </div>
  );
};

export default Home;

styles.css:

/* Custom scrollbar styles */
::-webkit-scrollbar {
    width: 12px;
  }
  
  ::-webkit-scrollbar-track {
    background: #a5f3fc; /* Cyan-200 color */
  }
  
  ::-webkit-scrollbar-thumb {
    background-color: #ff7f00; /* Orange color */
    border-radius: 10px;
    border: 3px solid #a5f3fc; /* Cyan-200 color to match the track */
  }
  
  ::-webkit-scrollbar-thumb:hover {
    background-color: #ff6600; /* Darker orange color on hover */
  }

  .line-drawing {
    stroke-dasharray: 1000;
    stroke-dashoffset: 1000;
    animation: draw 2s forwards;
  }
  
  @keyframes draw {
    to {
      stroke-dashoffset: 0;
    }
  }

Homepage.css:

/* Homepage specific styles */
.home-container {
  scroll-snap-type: y mandatory;
  overflow-y: scroll;
  height: 100vh;
}

section {
  scroll-snap-align: center;
  height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
  text-align: center;
  padding: 20px;
  transition: opacity 0.5s ease-in-out;
  position: relative;
  width: 100%;
}

/* Animation styles */
@keyframes fade-in {
  from { opacity: 0; }
  to { opacity: 1; }
}

.animate-fade-in {
  animation: fade-in 1s ease-in-out forwards;
}

.animate-fade-in-delay {
  animation: fade-in 2s ease-in-out forwards;
  animation-delay: 2s;
}

/* Line drawing animation */
.line-drawing {
  stroke-dasharray: 1000;
  stroke-dashoffset: 1000;
  animation: draw 2s forwards;
}

@keyframes draw {
  to {
      stroke-dashoffset: 0;
  }
}

here are one of the inner screens, which works when I do ‘npm start’:

import React, { useRef, useState, useEffect } from 'react';
import { motion } from 'framer-motion';
import Arrow from './Arrow';
import { FaLinkedin, FaGithub, FaEnvelope } from 'react-icons/fa';

const HeroSection = ({ arrowSize }) => {
  const heroSectionRef = useRef(null);
  const [arrowSizeDynamic, setArrowSizeDynamic] = useState(arrowSize);
  const [buttonSize, setButtonSize] = useState('text-base sm:text-lg');
  const [textSize, setTextSize] = useState('text-xl sm:text-2xl');
  const [titleSize, setTitleSize] = useState('text-4xl sm:text-6xl');

  useEffect(() => {
    const handleResize = () => {
      if (heroSectionRef.current) {
        const heroSectionHeight = heroSectionRef.current.clientHeight;
        const contentHeight = heroSectionRef.current.scrollHeight;
        const remainingSpace = heroSectionHeight - contentHeight;
        const newSize = Math.max(arrowSize, remainingSpace / 2); // Adjust the divisor to control the size
        setArrowSizeDynamic(newSize);

        // Adjust button and text sizes based on screen width
        const screenWidth = window.innerWidth;
        if (screenWidth < 640) {
          setButtonSize('text-sm px-4 py-2');
          setTextSize('text-lg');
          setTitleSize('text-4xl');
        } else {
          setButtonSize('text-base sm:text-lg px-6 py-3 sm:px-10 sm:py-5');
          setTextSize('text-xl sm:text-3xl');
          setTitleSize('text-5xl sm:text-9xl');
        }
      }
    };

    handleResize(); // Initial calculation
    window.addEventListener('resize', handleResize); // Recalculate on window resize

    return () => {
      window.removeEventListener('resize', handleResize);
    };
  }, [arrowSize]);

  return (
    <section
      ref={heroSectionRef}
      className="section hero snap-start h-screen flex flex-col justify-between items-center text-center relative bg-cyan-200"
    >
      <div className="container mx-auto px-4 sm:px-10 relative z-10 mt-10">
        <motion.h1
          className={`${titleSize} mb-6 hero-title`}
          initial={{ opacity: 0, y: -50 }}
          animate={{ opacity: 1, y: 0 }}
          transition={{ duration: 1 }}
        >
          Hi! 👋
        </motion.h1>
        <motion.p
          className={`${textSize} mb-4`}
          initial={{ opacity: 0, y: -50 }}
          animate={{ opacity: 1, y: 0 }}
          transition={{ duration: 1, delay: 0.5 }}
        >
          I'm [Redacted]
        </motion.p>
        <motion.p
          className="text-lg sm:text-2xl mb-16 sm:mb-32"
          initial={{ opacity: 0, y: 20 }}
          animate={{ opacity: 1, y: 0 }}
          transition={{ duration: 1, delay: 1.5 }}
        >
          Passionate about things.
        </motion.p>
        <motion.div
          className="flex justify-center space-x-4 sm:space-x-8 mb-8"
          initial={{ opacity: 0 }}
          animate={{ opacity: 1 }}
          transition={{ duration: 1, delay: 2 }}
        >
          <a href="https://www.linkedin.com/in/myname" target="_blank" rel="noopener noreferrer">
            <FaLinkedin className="text-3xl sm:text-5xl text-blue-600 hover:text-blue-800" />
          </a>
          <a href="https://github.com/myusername" target="_blank" rel="noopener noreferrer">
            <FaGithub className="text-3xl sm:text-5xl text-gray-800 hover:text-gray-600" />
          </a>
          <a href="mailto:[email protected]" target="_blank" rel="noopener noreferrer">
            <FaEnvelope className="text-3xl sm:text-5xl text-orange-500 hover:text-orange-700" />
          </a>
        </motion.div>
        <motion.a
          href="/resume.pdf"
          className={`inline-block ${buttonSize} bg-orange-500 text-white rounded-full hover:bg-orange-600 transition-colors mb-10`}
          initial={{ opacity: 0, scale: 0.8 }}
          animate={{ opacity: 1, scale: 1 }}
          transition={{ duration: 1, delay: 2.5 }}
          download
        >
          Download Resume
        </motion.a>
      </div>
      <Arrow size={arrowSizeDynamic} target="#about" />
    </section>
  );
};

export default HeroSection;

2

Answers


  1. Chosen as BEST ANSWER

    SOLVED: For some reason, just upgrading node via homebrew fixed the issue. not sure what original caused the issue, but it is very annoying since the error I got did not indicate there was an issue with my node.js installation


  2. If you were already on v23.2.0 when facing this issue, roll back to the LTS (v22.11.0).

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search