Cant get svgs and fonts to work with webpack

I am mostly a server side developer, so apologies in advance if my attempt to describe the problem seems weird.

I used the standard tutorial to setup a plugin using react. It all worked. Then I added the Semantic UI to power the accordion feature. This worked. But for some reason, when I try to use <Icon name='dropdown' /> component from Semantic UI, it just shows a placeholder with a question mark inside. I did the whole setup of the app outside of XD, and it all works as normal, I can see the icon being loaded properly. But within XD it does not work.

I include this in my component.

import 'semantic-ui-css/semantic.min.css'
import { Accordion, Icon } from 'semantic-ui-react'

My webpack.config.js has this loader, I also tried file-loader.

{
  test: /\.(ttf|woff|woff2|eot|png|svg|gif)$/,
  use: {
    loader: 'url-loader'
  }
}

I am thinking there is something that might be overriding the font-family and breaking Sematic UI fonts being loaded properly. But I can’t debug this, since it seems XD plugin development is like a black box, the best I can do is view the Developer Console, but does not show much.

Here is the full webpack.config.js

const path = require('path');

module.exports = {
  entry: __dirname + "/src/main.jsx",
  output: {
    path:  __dirname,
      filename: 'main.js',
      libraryTarget: "commonjs2"
  },
  devtool: "none", // prevent webpack from using eval() on my module
  externals: {
    application: "application",
    scenegraph: "scenegraph",
    viewport: "viewport",
    assets: "assets",
    clipboard: "clipboard",
    uxp: "uxp"
  },
  resolve: {
    extensions: [".js", ".jsx"]
  },
  module: {
    rules: [{
      test: /\.jsx?$/,
      exclude: /node_modules/,
      loader: "babel-loader",
      options: {
        plugins: [
          "transform-react-jsx",
          "transform-object-rest-spread",
          "transform-class-properties"
        ]
      }
    }, {
      test: /\.png$/,
      exclude: /node_modules/,
      loader: 'file-loader'
    }, {
      test: /\.css$/,
      use: ["style-loader", "css-loader", "resolve-url-loader"],
      include: [
        path.join(__dirname, 'src'),
        /node_modules/
      ]
    }, {
      test: /\.scss$/,
      use: [
        { loader: "style-loader" },
        { loader: "css-loader" },
        { loader: "sass-loader" }
      ]
    },
    {
      test: /\.(ttf|woff|woff2|eot|png|svg|gif)$/,
      use: {
        loader: 'file-loader'
      }
    }]
  }
}
1 Like

You might need something like the last rule below which handles SVG loading in React.

(This is all vaguely understood boilerplate from Adobe sample plugins.)

module.exports = {
  entry: './src/main.jsx',
  output: {
    path: __dirname,
    filename: 'main.js',
    libraryTarget: 'commonjs2',
  },
  devtool: 'none', // prevent webpack from using eval() on my module
  externals: {
    application: 'application',
    clipboard: 'clipboard',
    commands: 'commands',
    os: 'os',
    scenegraph: 'scenegraph',
    uxp: 'uxp',
    viewport: 'viewport',
    document: 'document',
  },
  resolve: {
    extensions: ['.js', '.jsx'],
    modules: [__dirname + '/node_modules'],
  },
  performance: { hints: false },
  module: {
    rules: [
      {
        test: /\.jsx?$/,
        exclude: /node_modules/,
        loader: 'babel-loader',
        options: {
          plugins: ['transform-react-jsx'],
        },
      },
      {
        test: /\.png$/,
        exclude: /node_modules/,
        loader: 'file-loader',
      },
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader'],
      },
      {
        test: /\.svg$/,
        exclude: /node_modules/,
        use: [
          {
            loader: 'babel-loader',
            options: {
              plugins: ['transform-react-jsx'],
            },
          },
          {
            loader: 'react-svg-loader',
            options: {
              jsx: true,
            },
          },
        ],
      },
    ],
  },
}

Hey, thanks for the reply. I have tried every combination of loaders available, and also the one you mentioned. Webpack “packs” the font files, and I can see them in the directory tree, but they are not being read properly by semantic css. I was able to get it working on a react app outside of XD. But there is something in XD that is breaking it.

I tried chrome devtool with XD, but it does not really show anything useful. No errors, no network activity, no console logs. XD development is like a black box where you need to know exactly how it works to build plugins for it.

After 3 days of trying to get Semantic UI icons to work, Im giving up on this.

try to use url-loader, i had the same problem with file-loader? esModule: false also important
here is my webpack config

module.exports = {
entry: ['./src/index.tsx'],
output: {
    path: __dirname,
    filename: 'dist/main.js',
    libraryTarget: 'commonjs2',
},
devtool: 'none',
externals: {
    application: 'application',
    uxp: 'uxp',
    scenegraph: 'scenegraph',
    clipboard: 'clipboard',
},
resolve: {
    extensions: ['.js', '.jsx', '.ts', '.tsx'],
},
module: {
    rules: [
        {
            test: /\.tsx?$/,
            exclude: /node_modules/,
            use: 'ts-loader',
        },
        {
            test: /\.s[ac]ss$/i,
            use: ['style-loader', 'css-loader', 'sass-loader'],
        },
        {
            test: /\.css$/i,
            use: ['style-loader', 'css-loader'],
        },
        {
            test: /\.(png|svg|jpg|jpeg|gif|ico)$/,
            use: [
                {
                    loader: 'url-loader',
                    options: {
                        name: '[name].[ext]',
                        outputPath: 'dist/img',
                        esModule: false,
                    },
                },
            ],
        },
    ],
},

};

and here is image somewhere is the src folder

<img src={require('../assets/congratulation.svg')} />
1 Like

you can convert your image to base64 and display

usted es un genio! Soluciono mi problema
Porque funciona con esModule=false ?