Home > Software engineering >  SVG's used in component library are not found in consuming app
SVG's used in component library are not found in consuming app

Time:06-07

Been reading for a bit but can't seem to find something that fits my issue.

PREFACE: I've built a private component library using storybook on component library

Now, I opened another app to try and consume said awesome library. I already have this app running nextjs/reactjs/netlify, really simple landing page with basic components in. I got over the github auth problems and seem to be successful running yarn add @username/component-library.

However, when I run the app, I'm seeing an error that the svg is not found:

next js app fail

Points to mention - I'm loading the svgs in the library like this:

-Footer.tsx
import FacebookSvg from '-!svg-react-loader!./facebook.svg';
import InstaSvg from '-!svg-react-loader!./insta.svg';
import LinkedInSvg from '-!svg-react-loader!./linkedin.svg';

<a target="_blank" href={facebook} rel="noreferrer">
  <FacebookSvg />
</a>

Using svg-react-loader. Again, this is all working within the library using storybook.

Also - the images are supposed to be inaccessible directly from the consuming app, I only want the components availble for import.

Assuming I have done something wrong in TS or webpack or rollup configs (all to follow). All my peer dependencies are installed in the consuming app.

QUESTION - Essentially I'm looking to "bundle" up the images with the components in the library so that consuming apps don't have to worry about the image assets. Can someone point out where I have gone wrong?

Help appreciated! I don't really understand where this is going wrong either, thought that if I had published a library with assets loaded within it, once consumed the assets would already be built into the components - keen to get an explanation for what I'm not fully understanding here as well.

Component Library:

-index.ts
import PageWrapper from './PageWrapper/PageWrapper';

export { PageWrapper };


-package.json
{
  "name": "@username/component-library",
  "version": "0.0.1",
  "description": "'common component library'",
  "author": "jamadan-dev",
  "license": "MIT",
  "main": "build/index.js",
  "module": "build/index.es.js",
  "files": [
    "build"
  ],
  "typings": "build/index.d.ts",
  "publishConfig": {
    "registry": "https://npm.pkg.github.com"
  },
  "scripts": {
    "build": "rollup -c",
    "storybook": "start-storybook -p 6006",
    "storybook:export": "build-storybook -o docs",
    "lint-fix": "eslint . --fix",
    "prepublishOnly": "npm run build"
  },
  "devDependencies": {
    "@babel/core": "^7.18.2",
    "@rollup/plugin-commonjs": "^22.0.0",
    "@rollup/plugin-node-resolve": "^13.3.0",
    "@storybook/react": "^6.5.7",
    "@types/react": "^18.0.12",
    "babel-loader": "^8.2.5",
    "babel-preset-react-app": "^10.0.1",
    "eslint": "^8.17.0",
    "eslint-config-next": "^12.1.6",
    "eslint-plugin-better-styled-components": "^1.1.2",
    "eslint-plugin-simple-import-sort": "^7.0.0",
    "eslint-plugin-unused-imports": "^2.0.0",
    "next": "^12.1.6",
    "prettier": "^2.6.2",
    "react": "^18.1.0",
    "react-dom": "^18.1.0",
    "rollup": "^2.75.5",
    "rollup-plugin-peer-deps-external": "^2.2.4",
    "rollup-plugin-svg": "^2.0.0",
    "rollup-plugin-typescript2": "^0.32.0",
    "sass-loader": "^13.0.0",
    "styled-components": "^5.3.5",
    "svg-react-loader": "^0.4.6",
    "typescript": "^4.7.3",
    "typescript-plugin-styled-components": "^2.0.0"
  },
  "dependencies": {},
  "peerDependencies": {
    "react": ">=16.8.0",
    "react-dom": ">=16.8.0",
    "svg-react-loader": "^0.4.6"
  }
}


-globals.d.ts
declare module '*.svg' {
  const content: string;
  export default content;
}


-rollup.config.js
import commonjs from "@rollup/plugin-commonjs";
import resolve from "@rollup/plugin-node-resolve";
import peerDepsExternal from "rollup-plugin-peer-deps-external";
import svg from 'rollup-plugin-svg'
import typescript from "rollup-plugin-typescript2";

const packageJson = require("./package.json");

const defaultExport = {
  input: "src/index.ts",
  output: [
    {
      file: packageJson.main,
      format: "cjs",
      sourcemap: true
    },
    {
      file: packageJson.module,
      format: "esm",
      sourcemap: true
    }
  ],
  plugins: [
    svg(),
    peerDepsExternal(),
    resolve(),
    commonjs(),
    typescript({ useTsconfigDeclarationDir: true }),
  ]
};

export default defaultExport;


-tsconfig.json
  {
    "compilerOptions": {
      "declaration": true,
      "declarationDir": "build",
      "module": "esnext",
      "target": "es5",
      "lib": ["es6", "dom", "es2016", "es2017"],
      "sourceMap": true,
      "jsx": "react",
      "moduleResolution": "node",
      "allowSyntheticDefaultImports": true,
      "esModuleInterop": true
    },
    "include": ["src/**/*"],
    "exclude": [
      "node_modules",
      "build",
      "src/**/*.stories.tsx",
      "src/**/*.test.tsx"
    ],
    "files": ["typings/globals.d.ts"]
  }


-PageWrapper.tsx
import Footer, { FooterProps } from './Footer';
const PageWrapper = ({ headKey, footerProps, children }: PageWrapperProps) => {

  return <div id="outer-container">
      <...blah including children... />
      <Footer address={footerProps.address} socials={footerProps.socials} />
    </StyledPageWrapper>
  </div>;};

export default PageWrapper;

CodePudding user response:

Managed to fix this, thanks go to some old dev mates...

What I did:

-Sacked off svg-react-loader and used @svgr/cli to convert my svgs to tsx components. Rebuilt the library. Published it

-Removed the sass and css loaders and all plugins/peer deps except react and react-dom

-Re-imported the component library in the consuming app


What I've learned:

-svgr is the way to go to make passing around pre-built components with images in them

CodePudding user response:

I can't run and check but as you mention It seems the error is due to path you should use ../ instead of ./

import FacebookSvg from '-!svg-react-loader!../facebook.svg';
import InstaSvg from '-!svg-react-loader!../insta.svg';
import LinkedInSvg from '-!svg-react-loader!../linkedin.svg';
  • Related