如何减少捆绑包的大小以构建反应组件的自定义库?

时间:2019-07-15 14:13:52

标签: reactjs webpack semantic-ui bundling-and-minification semantic-ui-react

我正在寻求解决此捆绑代码大小的问题。

我设计了一个要安装在我们的React项目中的库,用于在当前工作中重用React组件。我认为自己对反应和现代前端工具有一定的熟练度。我为此库设计的团队主要是后端开发人员,几乎没有使用React的经验。我决定利用Semantic-UI-React来抽象一些前端开发。

我的计划是将语义ui-react的整体以及我们创建的各种组件包装在一起。我这样做是为了使所有UI都可以来自同一位置,并且任何自定义主题/样式都将紧密结合在一起。

export { default as CardMenuOption } from './components/CardMenuOption/CardMenuOption';
export { default as AdvancedTable } from './components/AdvancedTable/AdvancedTable';
export { default as PageHeader } from './components/PageHeader/PageHeader';
export { default as StandardButton } from './components/StandardButton /StandardButton';
export { default as StandardCheckBox } from './components/StandardCheckBox/StandardCheckBox';
export { default as StandardModal } from './components/StandardModal /StandardModal';
export * from 'semantic-ui-react';

如您所见。我正在从语义UI导出所有内容。这样效果很好,并允许我们像这样在整个项目中导入内容

import {
  PageHeader,
  StandardButton,
  Grid,
  Icon
} from 'component-library';

其中Grid和Icon是语义组件,而PageHeader和StandardButton是我们的自定义组件。

此解决方案面临的问题是整个库的捆绑包大小。当前,为组件库项目(将所有语义ui样式捆绑到一个大文件中)似乎正在减慢为React项目构建UI的速度。

> my-project@1.0.0 build C:\Working\SourceCode\DevStable\UI\my-project
> webpack --mode=production

[BABEL] Note: The code generator has deoptimised the styling of C:\Working\SourceCode\DevStable\ComponentLibrary\component-library\dist\index.js as it exceeds the max of 500KB.
[BABEL] Note: The code generator has deoptimised the styling of C:\Working\SourceCode\DevStable\ComponentLibrary\component-library\dist\index.js as it exceeds the max of 500KB.

我希望有一种方法可以只构建任何给定项目正在使用的实际组件。

这是在使用组件库的UI中使用的Webpack

const path = require('path');
const webpack = require('webpack');
const ExtractTextPlugin = require('extract-text-webpack-plugin');

const extractCSS = new ExtractTextPlugin('allstyles.css');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');

module.exports = {
  optimization: {
    minimizer: [new UglifyJsPlugin()],
  },
  entry: {
    clientManagementEntry: path.resolve(__dirname, './wwwroot/lib/react/entry/ClientManagementEntry.jsx'),
    administrationEntry: path.resolve(__dirname, './wwwroot/lib/react/entry/AdministrationEntry.jsx'),
    systemManagementEntry: path.resolve(__dirname, './wwwroot/lib/react/entry/SystemManagementEntry.jsx'),
    FileImportEntry: path.resolve(__dirname, './wwwroot/lib/react/entry/FileImportEntry.jsx'),
    rolesManagementEntry: path.resolve(__dirname, './wwwroot/lib/react/entry/RolesManagementEntry.jsx'),
  },
  output: {
    path: path.resolve(__dirname, 'wwwroot/dist'),
    filename: '[name].js',
    publicPath: '/',
  },
  performance: {
    hints: false,
    maxEntrypointSize: 512000,
    maxAssetSize: 512000,
  },
  devtool: 'source-map',
  plugins: [
    extractCSS,
  ],
  module: {
    rules: [
      {
        test: /\.css$/,
        use: ExtractTextPlugin.extract({
          fallback: 'style-loader',
          use: 'css-loader',
        }),
      },
      {
        test: /\.jsx?$/,
        use: {
          loader: 'babel-loader',
          options: {
            presets:
                            ['@babel/preset-react', '@babel/preset-env'],
          },
        },
      },
      {
        test: /\.scss$/,
        use: [
          { loader: 'style-loader' },
          { loader: 'css-loader' },
          { loader: 'sass-loader' },
        ],
      },
      {
        test: /\.(woff2?|ttf|eot)$/,
        use: {
          loader: 'file-loader',
        },
      },
      {
        test: /\.(jpg|png|svg)$/,
        use: {
          loader: 'file-loader',
        },
      },
      {
        test: /\.js$|\.jsx$/,
        use: {
          loader: 'babel-loader',
        },
      },
    ],
  },
  resolve: {
    extensions: ['.js', '.jsx'],
  },

};

这就是Webpack配置在实际的组件库中的样子

const path = require('path');
const webpack = require('webpack');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');

module.exports = {
  optimization: {
    minimize: true,
    minimizer: [new UglifyJsPlugin()],
  },
  entry: './src/index',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'index.js',
    libraryTarget: 'commonjs2'
  },
  performance: {
    hints: false,
    maxEntrypointSize: 512000,
    maxAssetSize: 512000
  },
  devtool: false,
  plugins: [
    new webpack.LoaderOptionsPlugin({
      minimize: true,
      debug: false,
      options: {
        context: __dirname
      }
    }),
  ],
  module: {
    rules: [
      {
        test: /\.css$/,
        use: ExtractTextPlugin.extract({
          fallback: "style-loader",
          use: "css-loader"
        })
      },
      {
        test: /\.jsx?$/,
        use: {
          loader: 'babel-loader', options: {
            presets:
                ['@babel/preset-react', '@babel/preset-env'],
             plugins:
                ['react-hot-loader/babel']
          }
        }
      },
      {
        test: /\.scss$/,
        use: [
          { loader: 'style-loader' },
          { loader: 'css-loader' },
          { loader: 'sass-loader' }
        ]
      },
      {
        test: /\.(woff2?|ttf|eot)$/,
        use: {
          loader: 'file-loader'
        }
      },
      {
        test: /\.(jpg|png|svg)$/,
        use: {
          loader: 'file-loader'
        }
      },
      {
        test: /\.js$|\.jsx$/,
        use: {
          loader: 'babel-loader'
        }
      }
    ]
  },
  resolve: {
    extensions: ['.js', '.jsx']
  },

};

任何对此问题的见解将不胜感激

0 个答案:

没有答案