ADL
ADL

Reputation: 3

Nx React - Assets can't be resolved

I'm working on a nx monorepo that has a few library and 2 apps.

File Structures

apps
\--api
\--funnel ( react with webpack )
\--api-e2e
\--funnel-e2e
libs
\--funnel
\----pages
\--shared
\----assets
\-------src
\--------lib
\----------'some .tsx assets' ( lottie files )
\--------assets
\----------images
\-------------**/*.(png|webp|gif|svg) ( all others assets )

What's expected

In my libraries and in my app, I'd like to use the assets as such:
import imageName from '/assets/images/<some-image-folder>/<some-image-name>.<ext>';

For all svg, png, jpeg, etc...

for svgs:
import { ReactComponent from imageName } from '/assets/images/<some-image-folder>/<some-image-name>.svg';

Issue

My actual issues is that when i'm building the funnel app nx run funnel:build --verbose

my assets seems to be loaded into the cache but every assets return a : Module not found: Error: Can't resolve '/assets/images/<some-image-folder>/<some-image-name>.<ext>' from '<whatever-lib>/<main-app>'

Yes i use /assets/images As i'm using angular functionaility to "serve" the assets to /assets/images

What is my config

#NX Report

Node : 16.16.0 OS : darwin x64 npm : 9.2.0

nx : 15.6.0
@nrwl/angular : Not Found
@nrwl/cypress : 15.6.0
@nrwl/detox : Not Found
@nrwl/devkit : 15.6.0
@nrwl/esbuild : Not Found
@nrwl/eslint-plugin-nx : 15.6.0
@nrwl/expo : Not Found
@nrwl/express : 15.6.3
@nrwl/jest : 15.6.0
@nrwl/js : 15.6.0
@nrwl/linter : 15.6.0
@nrwl/nest : Not Found
@nrwl/next : Not Found
@nrwl/node : 15.6.3
@nrwl/nx-cloud : 15.0.3
@nrwl/nx-plugin : Not Found
@nrwl/react : 15.6.0
@nrwl/react-native : Not Found
@nrwl/rollup : Not Found
@nrwl/schematics : Not Found
@nrwl/storybook : Not Found
@nrwl/web : Not Found
@nrwl/webpack : 15.6.3
@nrwl/workspace : 15.6.0
@nrwl/vite : Not Found
typescript : 4.8.4

#app/funnel/project.json

My assets are imported through the main app as i don't build any of the sub-lib here's the selector :

{  
   "input": "libs/shared/assets/src/assets/images",
   "glob": "**/*",  
   "output": "assets/images"
}

#app/funnel/webpack.config.js

Couldn't import the whole code due to StackOverflow error but, in simple terms i added svgr support, file-loader & url-loader

module: {
      rules: [
        {
          test: /\.(webp|png|gif|jpe?g)$/i
          loader: 'file-loader',
          options: {
            name: '[path][name].[ext]',
          },
        },
        {
          test: /\.svg$/,
          use: [
            '@svgr/webpack',
            'url-loader'
          ]
        }
      ],
}

Explanation of what I've tried so far

#1rst attempt I used the angular functionality to import assets on build such as shown on the top config with the selector.

#2nd attempt I used copy-webpack-plugin to copy static assets to '/assets/' without success

#3rd attempt I added a path to the main tsconfig.base.json "@myapp/assets/*" : ["libs/shared/assets/src/assets/**/*"]

and tried to serve the assets as such : "@myapp/assets//."

#4rth attempt

The solution that works but isn't optimized for my workflow is to put each asset next to its dependencies...

This is disgusting as I need to duplicate assets, which are subject to a lot of changes.

Please help.

Here's the small-sized test repo : https://github.com/Sosumappu/assets-monorepo-test

Upvotes: 0

Views: 2974

Answers (1)

sancelot
sancelot

Reputation: 2063

Regarding your project it is not an asset pb, but an issue with loading svg images

I managed to load it .

At first upgrade your nx project from nx 15.6.0 to nx 15.6.3 :
npx nx migrate latest

You made a mistake, replace apple-pay.svg with applepay.svg in your project

change the color of your svg file to red, we can not see it (white on white background).

edit webpack.config.js as follow :

const { composePlugins, withNx } = require('@nrwl/webpack');
const { withReact } = require('@nrwl/react');

// Nx plugins for webpack.
module.exports = composePlugins(
  withNx({
    nx: {
      svgr: true,
    },
  }),
  withReact({ svgr: true }),
  (config) => {
 
    return config;
  }
);

shared-ui.tsx

import styled from 'styled-components';

//Static Import
import Logo from '@github-test/shared/assets';
export const ApplePayIcon = () => {
  return <Logo />;
};

libs/shared/assets/src/index.ts :

import Logo from '-!@svgr/webpack!./assets/images/applepay.svg';
export default Logo;

here you can console.log(Logo), you will see it is creating a react component

Upvotes: 1

Related Questions