How to load images from Common Component in Monorepo UI Packages?

518 views Asked by At

I'm building a monorepo using the Yarnberry workspace (version 3.6). My folder structure is as follows:

pakages
|
└── ui
|   └──src
|       └──assets
|           └── close.png
|       └──modals
|            └──Modal.tsx
|         
sevices
└── 
    └── next-app

I've created a simple modal component in the UI folder, and that component uses the close image in assets.

And I imported it from the next-app project of services and confirmed that it was loaded normally. However, only the images did not load normally.

I got the value [object Object] from the src value of the image.

How can I solve this?

Below is the package.json for the ui folder.

{
  "name": "@common/ui",
  "packageManager": "[email protected]",
  "main": "./src/index.ts",
  "scripts": {
  ...
  },
  "devDependencies": {
    "@babel/cli": "^7.22.9",
    "@babel/core": "^7.22.9",
    "@babel/preset-env": "^7.22.9",
    "@babel/preset-react": "^7.22.5",
    "@babel/preset-typescript": "^7.22.5",
    "esbuild": "latest",
    "esbuild-css-modules-plugin": "^2.7.1",
    "esbuild-sass-plugin": "^2.10.0",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "sass": "^1.64.1",
    "vite": "^4.4.7"
  },
}
//index.ts
export { default as Modal } from "./modals/Modal";
//Modal.tsx
import Close from '../../assets/colse.png';
const Modal = ({ title, content, buttonName }: IConfirmType) => {
  return (
    <div className="popup_message_view_align">
      <img
        className="btn_close"
        src={Close}
        alt="close"
      />
      ...
    </div>
  );
};
1

There are 1 answers

3
dave.tdv On BEST ANSWER

Once Next.js builds the app, scripts and assets will be bundled and stored in .next directory. Image that is imported will be seen as an object as below.

Example

{
  src: '/_next/static/media/abcdef.a7717b40.jpg',
  height: 3800,
  width: 2850,
  blurDataURL: '/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Fabcdef.a7717b40.jpg&w=6&q=70',
  blurWidth: 6,
  blurHeight: 8
}

As you can see, the final path won't be the same as the relative path you provided.

You can either do

<img
  className="btn_close"
  src={Close.src}
  alt="close"
/>

Or, since you use Next.js you can also try using next/image. It will handle the imported image object internally plus better image optimization.

import Image from 'next/image';

//...

<Image
  src={Close}
  alt="Close image"
  className="btn_close"
  width={600}
  height={400}
  priority
/>