Ant-design-vue: bunlde size too large

Created on 20 Dec 2018  ·  15Comments  ·  Source: vueComponent/ant-design-vue

Most helpful comment

image
我无力吐槽了

All 15 comments

umi.js can work on vue?

有没有某个工具检测项目中哪些地方运用到了某些组件,然后按需引入,而不必手动按需引入

@zhe-he 我自己写了个简单的小工具,可以实现自动获取组件是引入的组件,然后自己可以根据获取的使用组件列表,来书写按需注入代码。项目在这里:https://github.com/yugasun/auto-detect-component

有好的解决方案了么?打包后的文件太大了,Icon的svg图标占了400多kb

仔细查看了 antd vue 的相关源码,我觉得把 moment 替换成 2kb 大小的 dayjs 是一个可行的优化。代码层面基本没有太多的改变,打包体积能把 moment 的 100kb 缩减成 10 kb 以内。

如果 @tangjinzhou 有兴趣的话 我可以提供一些帮助 谢谢

⏰ Day.js 2KB immutable date library alternative to Moment.js with the same modern API
https://github.com/iamkun/dayjs

@xxyuk 非常感谢你的建议!
不过 day.js 替换 moment 短期内应该不会,这个主要还是和 antd 同步
相关讨论可以参考 https://github.com/ant-design/ant-design/issues/10437

另外,可以通过 webpack 进行 moment 优化,代码体积还在在可接受范围内的
优化参考 https://github.com/jmblog/how-to-optimize-momentjs-with-webpack

哎,按需要加载一个 Button,结果打包后就 566 KB,头疼…

image

哎,按需要加载一个 Button,结果打包后就 566 KB,头疼…

image

解决了吗?同样遇到

@atjason @531431988 icon 问题,优化方案可以查看这个 https://vuecomponent.github.io/ant-design-vue/docs/vue/getting-started/#Import-on-Demand

image
我无力吐槽了

在 vuecli4 中使用 icon 按需加载时,出现找不到依赖的问题。在vuecli2.x没这个问题

/  Building for analyz...

 ERROR  Failed to compile with 13 errors                                                                                                              1:32:12 PM
These dependencies were not found:

* @ant-design/icons/lib/fill/CalendarFill in ./src/utils/antdIcon.js
* @ant-design/icons/lib/fill/CloseCircleFill in ./src/utils/antdIcon.js
* @ant-design/icons/lib/fill/CodeFill in ./src/utils/antdIcon.js
* @ant-design/icons/lib/fill/StarFill in ./src/utils/antdIcon.js
* @ant-design/icons/lib/outline/CheckOutline in ./src/utils/antdIcon.js
* @ant-design/icons/lib/outline/DownOutline in ./src/utils/antdIcon.js
* @ant-design/icons/lib/outline/DownSquareOutline in ./src/utils/antdIcon.js
* @ant-design/icons/lib/outline/ForkOutline in ./src/utils/antdIcon.js
* @ant-design/icons/lib/outline/LeftOutline in ./src/utils/antdIcon.js
* @ant-design/icons/lib/outline/LoadingOutline in ./src/utils/antdIcon.js
* @ant-design/icons/lib/outline/RightOutline in ./src/utils/antdIcon.js
* @ant-design/icons/lib/outline/SearchOutline in ./src/utils/antdIcon.js
* @ant-design/icons/lib/outline/StarOutline in ./src/utils/antdIcon.js

To install them, you can run: npm install --save @ant-design/icons/lib/fill/CalendarFill @ant-design/icons/lib/fill/CloseCircleFill @ant-design/icons/lib/fill/CodeFill @ant-design/icons/lib/fill/StarFill @ant-design/icons/lib/outline/CheckOutline @ant-design/icons/lib/outline/DownOutline @ant-design/icons/lib/outline/DownSquareOutline @ant-design/icons/lib/outline/ForkOutline @ant-design/icons/lib/outline/LeftOutline @ant-design/icons/lib/outline/LoadingOutline @ant-design/icons/lib/outline/RightOutline @ant-design/icons/lib/outline/SearchOutline @ant-design/icons/lib/outline/StarOutline
Error parsing bundle asset "E:\04.dev\lemonitor\docs\static\js\app.js": no such file
Error parsing bundle asset "E:\04.dev\lemonitor\docs\static\js\chunk-vendors.js": no such file
Error parsing bundle asset "E:\04.dev\lemonitor\docs\static\js\usage.js": no such file

No bundles were parsed. Analyzer will show only original module sizes from stats file.

Webpack Bundle Analyzer saved report to E:\04.dev\lemonitor\docs\report.html
 ERROR  Build failed with errors.
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] analyz: `vue-cli-service build --mode analyz`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the [email protected] analyz script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

vue.config.js

chainWebpack: config => {
    // 添加别名
    config.resolve.alias
      .set("vue$", "vue/dist/vue.esm.js")
      .set("@", path.resolve(__dirname, "src"))
      .set("@components", path.resolve(__dirname, "src/components"))
      .set("@views", path.resolve(__dirname, "src/views"))
      .set("@router", path.resolve(__dirname, "src/router"))
      .set("@store", path.resolve(__dirname, "src/store"))
      .set(
        "@ant-design/icons/lib/dist$",
        path.resolve(__dirname, "src/utils/antdIcon.js")
      );
}

src/utils/antdIcon.js

/**
 * 修改Antd 的默认加载图标,改为按需加载,减小打包体积 使用Antd默认图标之前需要在此文件引用
 * webpack alias 添加:
 * {'@ant-design/icons/lib/dist$': path.resolve(__dirname, 'src/utils/antdIcon.js')}
 */

export { default as CheckOutline } from "@ant-design/icons/lib/outline/CheckOutline";
export { default as DownSquareOutline } from "@ant-design/icons/lib/outline/DownSquareOutline";
export { default as LoadingOutline } from "@ant-design/icons/lib/outline/LoadingOutline";
export { default as DownOutline } from "@ant-design/icons/lib/outline/DownOutline";
export { default as SearchOutline } from "@ant-design/icons/lib/outline/SearchOutline";
export { default as LeftOutline } from "@ant-design/icons/lib/outline/LeftOutline";
export { default as RightOutline } from "@ant-design/icons/lib/outline/RightOutline";
export { default as ForkOutline } from "@ant-design/icons/lib/outline/ForkOutline";
export { default as StarOutline } from "@ant-design/icons/lib/outline/StarOutline";
export { default as StarFill } from "@ant-design/icons/lib/fill/StarFill";
export { default as CodeFill } from "@ant-design/icons/lib/fill/CodeFill";
export { default as CalendarFill } from "@ant-design/icons/lib/fill/CalendarFill";
export { default as CloseCircleFill } from "@ant-design/icons/lib/fill/CloseCircleFill";

@sendya

Thank you, I tried this method, but there is still an error。

package.json

  "dependencies": {
    "@ant-design/icons": "^4.0.3",
    "@babel/runtime": "^7.9.2",
    "amfe-flexible": "^2.2.1",
    "ant-design-vue": "^1.4.12",
    "axios": "^0.19.2",
    "babel-plugin-import": "^1.13.0",
    "babel-polyfill": "^6.26.0",
    "core-js": "^3.6.4",
    "highlight.js": "^9.18.1",
    "less": "^3.11.1",
    "less-loader": "^5.0.0",
    "vue": "^2.6.11",
    "vue-markdown": "^2.2.4",
    "vue-router": "^3.1.5",
    "vuex": "^3.1.2"
  }

vue.config.js

const path = require("path");
const resolve = dir => require("path").join(__dirname, dir);
const CompressionWebpackPlugin = require("compression-webpack-plugin"); //Gzip
const productionGzipExtensions = /\.(js|css|json|txt|html|ico|svg)(\?.*)?$/i;
const BundleAnalyzerPlugin = require("webpack-bundle-analyzer")
  .BundleAnalyzerPlugin; //Webpack包文件分析器
const CopyWebpackPlugin = require("copy-webpack-plugin");

const IS_PROD = ["production", "prod"].includes(process.env.NODE_ENV); //env
const isAnalyz = process.env.IS_ANALYZ === "true";

module.exports = {
  // publicPath: "./", //打包后的位置(如果不设置这个静态资源会报404)
  publicPath:
    process.env.NODE_ENV === "production" ? process.env.API_ROOT : "./",
  outputDir: "docs", //打包后的目录名称
  assetsDir: "static", //静态资源目录名称
  productionSourceMap: false, //去掉打包的时候生成的map文件
  lintOnSave: true, // eslint-loader 是否在保存的时候检查
  filenameHashing: false,
  runtimeCompiler: true, // 是否使用包含运行时编译器的 Vue 构建版本
  parallel: require("os").cpus().length > 1, // 是否为 Babel 或 TypeScript 使用 thread-loader。该选项在系统的 CPU 有多于一个内核时自动启用,仅作用于生产构建。
  pwa: {}, // 向 PWA 插件传递选项。
  // css相关配置
  css: {
    // 是否使用css分离插件 ExtractTextPlugin
    extract: false,
    // 开启 CSS source maps?
    sourceMap: !IS_PROD,
    // css预设器配置项
    loaderOptions: {
      less: {
        javascriptEnabled: true
      }
    }
  },
  chainWebpack: config => {
    // 打包分析
    // if `IS_ANALYZ` env is TRUE on report bundle info
    isAnalyz &&
      config.plugin("webpack-report").use(BundleAnalyzerPlugin, [
        {
          analyzerMode: "static"
        }
      ]);
    // 修复HMR
    config.resolve.symlinks(true);

    // 如果使用多页面打包,使用vue inspect --plugins查看html是否在结果数组中
    // config.plugin("html").tap(args => {
    //   // 修复 Lazy loading routes Error
    //   args[0].chunksSortMode = "none";
    //   return args;
    // });

    config.resolve.extensions
      .add(".js")
      .add(".vue")
      .add(".json");

    // 添加别名
    config.resolve.alias
      .set("vue$", "vue/dist/vue.esm.js")
      .set("@", resolve("src"))
      .set("@components", resolve("src/components"))
      .set("@views", resolve("src/views"))
      .set("@router", resolve("src/router"))
      .set("@store", resolve("src/store"));
      // .set("@ant-design/icons/lib/dist$", resolve("src/utils/antdIcon.js"));

    if (IS_PROD) {
      // 压缩图片
      // 需要 npm i -D image-webpack-loader
      config.module
        .rule("images")
        .test(/\.(png|jpe?g|gif|svg)(\?.*)?$/)
        .use("image-webpack-loader")
        .loader("image-webpack-loader")
        .options({
          mozjpeg: { progressive: true, quality: 65 },
          optipng: { enabled: false },
          pngquant: { quality: [0.65, 0.9], speed: 4 },
          gifsicle: { interlaced: false }
        });
    }
  },
  devServer: {
    // overlay: { // 让浏览器 overlay 同时显示警告和错误
    //   warnings: true,
    //   errors: true
    // },
    // open: false, // 是否打开浏览器
    // host: "localhost",
    // port: "8080", // 代理断就
    // https: false,
    // hotOnly: false, // 热更新
    proxy: {
      "/api": {
        target: "http://hosts/api", // 目标代理接口地址
        secure: false,
        changeOrigin: true, // 开启代理,在本地创建一个虚拟服务端
        // ws: true, // 是否启用 websockets
        pathRewrite: {
          "^/api": "/"
        }
      }
    }
  },
  configureWebpack: config => {
    const plugins = [];
    // 拷贝static目录
    plugins.push(
      new CopyWebpackPlugin([
        {
          from: path.resolve(__dirname, "static"),
          to: path.resolve(__dirname, "docs/static"),
          ignore: [".*"]
        }
      ])
    );

    if (IS_PROD) {
      // 开启 gzip 压缩
      // 需要 npm i -D compression-webpack-plugin
      plugins.push(
        new CompressionWebpackPlugin({
          filename: "[path].gz[query]",
          algorithm: "gzip",
          test: productionGzipExtensions,
          threshold: 10240,
          minRatio: 0.8
        })
      );
    }
    config.resolve = {
      alias: {
        "@ant-design/icons/lib/dist$": path.join(
          __dirname,
          "./src/utils/antdIcon.js"
        )
      }
    };
    config.plugins = [...config.plugins, ...plugins];
  }
};

Repo: https://github.com/lework/lemonitor

@lework I have encounter the same problem, I found that the from path like @ant-design/icons/lib/outline/CheckOutlineis not in my project, it should be ant-design-vue/node_modules/@ant-design/icons/lib/outline/CheckOutline

you can have a try.

this problem maybe happened in you file : src/utils/antdIcon.js

/**
 * 修改Antd 的默认加载图标,改为按需加载,减小打包体积 使用Antd默认图标之前需要在此文件引用
 * webpack alias 添加:
 * {'@ant-design/icons/lib/dist$': path.resolve(__dirname, 'src/utils/antdIcon.js')}
 */

export { default as CheckOutline } from "@ant-design/icons/lib/outline/CheckOutline";
export { default as DownSquareOutline } from "@ant-design/icons/lib/outline/DownSquareOutline";

find your own @ant-design path.

@lework I have encounter the same problem, I found that the from path like @ant-design/icons/lib/outline/CheckOutlineis not in my project, it should be ant-design-vue/node_modules/@ant-design/icons/lib/outline/CheckOutline

you can have a try.

this problem maybe happened in you file : src/utils/antdIcon.js

/**
 * 修改Antd 的默认加载图标,改为按需加载,减小打包体积 使用Antd默认图标之前需要在此文件引用
 * webpack alias 添加:
 * {'@ant-design/icons/lib/dist$': path.resolve(__dirname, 'src/utils/antdIcon.js')}
 */

export { default as CheckOutline } from "@ant-design/icons/lib/outline/CheckOutline";
export { default as DownSquareOutline } from "@ant-design/icons/lib/outline/DownSquareOutline";

find your own @ant-design path.

there is a problem,the button component or message component also use the icon,how to solve it

Was this page helpful?
0 / 5 - 0 ratings