Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Instructions on using @icon/font #7

Closed
dternyak opened this issue Dec 1, 2019 · 15 comments
Closed

Instructions on using @icon/font #7

dternyak opened this issue Dec 1, 2019 · 15 comments

Comments

@dternyak
Copy link

dternyak commented Dec 1, 2019

I've been unable to get <Icon> working in my project. I'm not running into webpack compile errors, and the uikon style seems to be applying to the element, but I'm just seeing the plaintext "building" instead of the building icon render.

Specific instructions on how to get <Icon/> working would be appreciated!

@march08
Copy link
Owner

march08 commented Dec 4, 2019

I've been unable to get <Icon> working in my project. I'm not running into webpack compile errors, and the uikon style seems to be applying to the element, but I'm just seeing the plaintext "building" instead of the building icon render.

Specific instructions on how to get <Icon/> working would be appreciated!

Hey there, sorry I think I haven't clarified that clearly.
can you try import '@duik/it/dist/styles.css' in your root of the application?

@dternyak
Copy link
Author

dternyak commented Dec 4, 2019

Yup, already doing this. Also tried importing import '@duik/icon/dist/styles.css'; with no luck.

@march08
Copy link
Owner

march08 commented Dec 4, 2019

Yup, already doing this. Also tried importing import '@duik/icon/dist/styles.css'; with no luck.

What is your project setup? The CSS loads eot and other font files. Does your stack support that? You can also try that manually using these files: https://github.com/march08/dashboard-ui-kit/tree/master/packages/Icon

@dternyak
Copy link
Author

dternyak commented Dec 4, 2019 via email

@dternyak
Copy link
Author

dternyak commented Dec 5, 2019

const hash = require('string-hash');
const _ = require('lodash');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

const isDev = process.env.NODE_ENV === 'development';

const lessLoader = {
  loader: 'less-loader',
  options: { javascriptEnabled: true },
};

const sassLoader = {
  loader: 'sass-loader',
};

const tsBabelLoaderClient = {
  test: /\.tsx?$/,
  use: [
    {
      loader: 'babel-loader',
      options: {
        plugins: [
          '@loadable/babel-plugin',
          'react-hot-loader/babel',
          '@babel/plugin-proposal-object-rest-spread',
          '@babel/plugin-proposal-class-properties',
          ['import', { libraryName: 'antd', style: false }],
        ],
        presets: ['@babel/react', ['@babel/env', { useBuiltIns: 'entry', "corejs": "2.5.7"}]],
      },
    },
    {
      loader: 'ts-loader',
      options: { transpileOnly: isDev },
    },
  ],
};

const tsBabelLoaderServer = {
  test: /\.tsx?$/,
  use: [
    {
      loader: 'babel-loader',
      options: {
        plugins: [
          '@loadable/babel-plugin',
          '@babel/plugin-proposal-object-rest-spread',
          '@babel/plugin-proposal-class-properties',
          ['import', { libraryName: 'antd', style: false }],
        ],
        presets: [
          '@babel/react',
          ['@babel/env', { useBuiltIns: 'entry', "corejs": "2.5.7", targets: { node: 'current' } }],
        ],
      },
    },
    {
      loader: 'ts-loader',
      options: { transpileOnly: isDev },
    },
  ],
};

const cssLoaderClient = {
  test: /\.css$/,
  exclude: [/node_modules/],
  use: [
    {
      loader: MiniCssExtractPlugin.loader,
      options: {
        hmr: isDev,
      },
    },
    {
      loader: 'css-loader',
    },
  ]
};

const sassLoaderClient = {
  test: /\.scss$/,
  exclude: [/node_modules/],
  use: [...cssLoaderClient.use, 'resolve-url-loader', sassLoader]
}

const lessLoaderClient = {
  test: /\.less$/,
  exclude: [/node_modules/],
  use: [...cssLoaderClient.use, lessLoader],
};

const cssLoaderServer = {
  test: /\.css$/,
  exclude: [/node_modules/],
  use: [
    {
      loader: 'css-loader/locals',
    },
  ],
};

const lessLoaderServer = {
  test: /\.less$/,
  exclude: [/node_modules/],
  use: [...cssLoaderServer.use, lessLoader],
};

const sassLoaderServer = {
  test: /\.scss$/,
  exclude: [/node_modules/],
  use: [...cssLoaderServer.use, 'resolve-url-loader', sassLoader],
};

const urlLoaderClient = {
  test: /\.(png|jpe?g|gif)$/,
  loader: require.resolve('url-loader'),
  options: {
    limit: 2048,
    name: 'assets/[name].[hash:8].[ext]',
  },
};

const urlLoaderServer = {
  ...urlLoaderClient,
  options: {
    ...urlLoaderClient.options,
    emitFile: false,
  },
};

const markdownLoaderClient = {
  test: /\.md$/,
  use: [
    {
      loader: 'html-loader',
    },
    {
      loader: 'markdown-loader',
    },
  ],
};

const markdownLoaderServer = {
  ...markdownLoaderClient,
  use: [
    {
      loader: 'html-loader',
      options: {
        emitFile: false,
      },
    },
    {
      loader: 'markdown-loader',
    },
  ],
};

const fileLoaderClient = {
  // WARNING: this will catch all files except those below
  exclude: [/\.(js|ts|tsx|css|less|mjs|html|json|ejs)$/],
  use: [
    {
      loader: 'file-loader',
      options: {
        name: 'assets/[name].[hash:8].[ext]',
      },
    },
  ],
};

const fileLoaderServer = _.defaultsDeep(
  {
    use: [{ options: { emitFile: false } }],
  },
  fileLoaderClient,
);

const svgLoaderClient = {
  test: /\.svg$/,
  issuer: {
    test: /\.tsx?$/,
  },
  use: ({ resource }) => ({
    loader: '@svgr/webpack',
    options: {
      svgoConfig: {
        plugins: [
          {
            inlineStyles: {
              onlyMatchedOnce: false,
            },
          },
          {
            cleanupIDs: {
              prefix: `svg-${hash(resource)}`,
            },
          },
        ],
      },
    },
  }), // svg -> react component
};

const svgLoaderServer = svgLoaderClient;

// Write css files from node_modules to its own vendor.css file
const externalCssLoaderClient = {
  test: /\.css$/,
  include: [/node_modules/],
  use: [
    MiniCssExtractPlugin.loader,
    'css-loader',
  ]
};

const externalLessLoaderClient = {
  test: /\.less$/,
  include: [/node_modules/],
  use: [
    MiniCssExtractPlugin.loader,
    'css-loader',
    lessLoader,
  ]
};

const externalSassLoaderClient = {
  test: /\.scss$/,
  include: [/node_modules/],
  use: [
    MiniCssExtractPlugin.loader,
    'css-loader',
    'resolve-url-loader',
    sassLoader,
  ]
};

// Server build needs a loader to handle external .css files
const externalSassLoaderServer = {
  test: /\.scss$/,
  include: [/node_modules/],
  use: ['css-loader/locals', 'resolve-url-loader', sassLoader],
};

const externalCssLoaderServer = {
  test: /\.css$/,
  include: [/node_modules/],
  loader: 'css-loader/locals',
};

const externalLessLoaderServer = {
  test: /\.less$/,
  include: [/node_modules/],
  use: ['css-loader/locals', lessLoader],
};

const client = [
  {
    // oneOf: first matching rule takes all
    oneOf: [
      tsBabelLoaderClient,
      cssLoaderClient,
      sassLoaderClient,
      lessLoaderClient,
      svgLoaderClient,
      urlLoaderClient,
      markdownLoaderClient,
      fileLoaderClient,
      externalCssLoaderClient,
      externalLessLoaderClient,
      externalSassLoaderClient,

    ],
  },
];

const server = [
  {
    // oneOf: first matching rule takes all
    oneOf: [
      tsBabelLoaderServer,
      cssLoaderServer,
      sassLoaderServer,
      lessLoaderServer,
      svgLoaderServer,
      urlLoaderServer,
      markdownLoaderServer,
      fileLoaderServer,
      externalCssLoaderServer,
      externalLessLoaderServer,
      externalSassLoaderServer
    ],
  },
];

module.exports = {
  client,
  server,
};

Here are the various loaders -- this is probably the most relevant bit I can share.

@dternyak
Copy link
Author

dternyak commented Dec 5, 2019

Screen Shot 2019-12-04 at 9 04 08 PM

@march08
Copy link
Owner

march08 commented Dec 7, 2019

@dternyak can you mail me march08@outlook.com, i'll try to take a look

Also, one solution might be hosting the font files and replacing the URL of the files. Of course you can also use other icons as well. I;ll try to reply soon once I get your mail.

@dternyak
Copy link
Author

dternyak commented Dec 9, 2019

Thank you so much! I greatly appreciate this. I've just sent you an email.

@tleite
Copy link

tleite commented Dec 17, 2019

Hey guys, ran into the same issue... I has to do with :global scope on @duik/icon/styles.scss

This is an issue with sass-loader - webpack-contrib/sass-loader#448

A quick and dirty way to fix it, is to replace line 86 (@duik/icon/styles.scss)

From:
:global {

To:
html {

If anybody knows a more permanent solution, please let me know.

@dternyak
Copy link
Author

Thanks for commenting @tleite.

That temporary fix didn't work for me either actually, interestingly enough. Hopefully @march08 get's a chance to look at this soon.

@tleite
Copy link

tleite commented Dec 17, 2019

For me it did, make sure you clear your cache and rebuild. Try finding the css in the dom and change the :global to html and the icon should appear. Also, make sure the font file is loading, in my case it was.

I settled with this webpack rule to find and replace ":global" to "html" for now:

  config.module.rules.push( {
    test: path.resolve(__dirname, '../node_modules/@duik/icon/styles.scss'),
    loader: 'string-replace-loader',
    options: {
      search: ':global',
      replace: 'html',
    }
  });

@dternyak
Copy link
Author

Thank you so much for the help @tleite!

Last bit I'm stuck on: I'm a bit unfamiliar with font-loading. Do you mind pointing me towards any resources on how to check if fonts are getting loaded? Unfortunately still not able to get this working.

@dternyak
Copy link
Author

dternyak commented Dec 18, 2019

I think I've found another partial source of the problem:

My font-family url paths are broken. This is what I see when inspecting the loaded icon stylesheet.

@font-face {
  font-family: 'uikon';
  src: url([object Module]);
  src: url([object Module]) format("embedded-opentype"), url([object Module]) format("truetype"), url([object Module]) format("woff"), url([object Module]) format("svg");
  font-weight: normal;
  font-style: normal; }

It's probably something related to my file loader, but I'm not sure what. Any tips would be appreciated!

const fileLoaderClient = {
  // WARNING: this will catch all files except those below
  exclude: [/\.(js|ts|tsx|css|less|mjs|html|json|ejs)$/],
  use: [
    {
      loader: 'file-loader',
      options: {
        name: 'assets/[name].[hash:8].[ext]',
      },
    },
  ],
};

@march08
Copy link
Owner

march08 commented Dec 18, 2019

@dternyak sorry I just got time to check the repo. It seems like the file loader in the repo doesn't process files under node_modules properly and you can see that in the manifest.json as well.

To resolve that quickly without fiddling with the webpack config, you can copy the contents from the packages/icon into the project. The font files and the CSS code where it defines the font-family with the imports.

@tleite
Copy link

tleite commented Dec 18, 2019

Thank you so much for the help @tleite!

Last bit I'm stuck on: I'm a bit unfamiliar with font-loading. Do you mind pointing me towards any resources on how to check if fonts are getting loaded? Unfortunately still not able to get this working.

  1. look on your network tab, make sure the font files are loading
  2. try inspecting an element, and hardcode the font-family to see if it loads

@march08 march08 closed this as completed Mar 30, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants