tabler / tabler-icons

A set of over 5300 free MIT-licensed high-quality SVG icons for you to use in your web projects.
https://tabler.io/icons
MIT License
17.59k stars 877 forks source link

Bundle size extreme large, transforming all icons when build #1161

Open Nradar opened 3 weeks ago

Nradar commented 3 weeks ago

Browser

chrome

OS

windows 10

Screen size

1920x1080

Describe the bug

Hi All! I have project(called A) built with remix/vite, and it include my other library(called B) built based on storybook and vite. Both A and B have installed @tabler/icons-react as dev dependency.

When I build library B itself, the tabler icons are doing okay, only include icons been imported in the build. But when I build the project A, all of the tabler icons in B are all transforming and packed into build/client/assets/B.js. It occupied a huge bundle size. I'm not sure if this is related to treeshaking or some configs? Hope someone can help me on this! Thanks in advance.

Project A vite config:

import { vitePlugin as remix } from "@remix-run/dev";
import { defineConfig } from "vite";
import tsconfigPaths from "vite-tsconfig-paths";
import mdx from "@mdx-js/rollup";
import remarkFrontmatter from "remark-frontmatter";
import remarkMdxFrontmatter from "remark-mdx-frontmatter";
import { visualizer } from "rollup-plugin-visualizer";

export default defineConfig({
  ssr: {
    noExternal: ["pdfmake/build/vfs_fonts" /* , "dc" */],
  },

  plugins: [
    mdx({
      remarkPlugins: [remarkFrontmatter, remarkMdxFrontmatter],
    }),
    remix(),
    tsconfigPaths(),
    visualizer({
      open: true,
      gzipSize: true,
      template: "treemap",
    }),
  ],
});

Library B vite config:

import { defineConfig } from 'vite'
import { resolve } from 'path'
import react from '@vitejs/plugin-react'
import { viteStaticCopy } from 'vite-plugin-static-copy'
import ignore from 'rollup-plugin-ignore'
import dts from 'vite-plugin-dts'
import * as packageJson from './package.json'
import dynamicImport from 'vite-plugin-dynamic-import'
import { visualizer } from 'rollup-plugin-visualizer'

export default defineConfig({
    plugins: [
        visualizer({ open: true, gzipSize: true }),
        react(),
        ignore(['moment', 'moment-timezone']),
        dts({
            include: ['src'],
        }),
        dynamicImport(),

        viteStaticCopy({
            targets: [
                {
                    src: 'tailwind.config.js',
                    dest: '',
                },
                {
                    src: 'node_modules/@fontsource/inter/files/*400*',
                    dest: 'files',
                },
            ],
        }),
    ],
    build: {
        minify: true,
        copyPublicDir: false,
        lib: {
            entry: resolve(__dirname, 'src/index.tsx'),
            name: 'custom-components',
            formats: ['es', 'cjs'],
            fileName: format => `custom-components.${format}.js`,
        },
        rollupOptions: {
            external: [
                ...Object.keys(packageJson.devDependencies),
                ...Object.keys(packageJson.peerDependencies),
                'moment',
                'moment-timezone',
                '@fontsource/inter',
            ],
            output: {
                sourcemap: false,
                compact: false,
            },
        },
    },
})

How to reproduce

  1. (Lib B)Create a storybook with vite config as mine, installed tabler-icons as dev deps
  2. (Project A)Create a remix project with vite config as mine, and installed tabler-icons as dev deps
  3. Install Lib B in step 1 as deps into project A in step 2 and run build
  4. Check the folder build/client/assets/Lib B.(something would be like libb.cjs-DdmG1IpM.js)
  5. Using any bundle size visualizer will see that the tabler icons in LibB occupy huge size around 5mb.

Screenshots

No response

JSFiddle

No response

codecalm commented 3 weeks ago

Hi, this is project about Tabler Dashboard, Tabler Icons are here: https://github.com/tabler/tabler-icons

novaotp commented 2 weeks ago

I also had this issue where building my app would include all the icons. The workaround is to import all icons as a default export. I'm using Svelte but it should be similar enough. For example : import IconUser from "@tabler/icons-svelte/IconUser.svelte"

The annoying part is that each import only adds a single icon, so you have to do it multiple times if you use a lot of icons. I've had this issue since 3.0.0 and I haven't seen anything changed yet. I really like the library so I won't change it, but it would be convenient to import the icons as named imports, like import { IconUser } from "@tabler/icons-svelte".

Nradar commented 2 weeks ago

I also had this issue where building my app would include all the icons. The workaround is to import all icons as a default export. I'm using Svelte but it should be similar enough. For example : import IconUser from "@tabler/icons-svelte/IconUser.svelte"

The annoying part is that each import only adds a single icon, so you have to do it multiple times if you use a lot of icons. I've had this issue since 3.0.0 and I haven't seen anything changed yet. I really like the library so I won't change it, but it would be convenient to import the icons as named imports, like import { IconUser } from "@tabler/icons-svelte".

Thank you. I will try your approach to import icons directly