guardicore / monkey

Infection Monkey - An open-source adversary emulation platform
https://www.guardicore.com/infectionmonkey/
GNU General Public License v3.0
6.63k stars 773 forks source link

NPM Build Time is Too Slow #608

Closed ShayNehmad closed 2 years ago

ShayNehmad commented 4 years ago

Describe the bug

Building the UI (which means running ` andnpm run dist` takes way too long.

To Reproduce

Steps to reproduce the behavior:

  1. cd into the cc/UI dir
  2. Build the UI
  3. Go make a cup of coffee 🙄

Expected behavior

Build time should be measured in seconds, not minutes.

Tasks

ilija-lazoroski commented 2 years ago

Measurement on what we need to focus on:

image

This is on production where we are using devtool: source-map. The explanation why is here. For development purposes we can use eval which is the fastest and for production we can use caching

ilija-lazoroski commented 2 years ago

One approach is to use HappyPack which the latest release is done in 2019 and the person maintaining it, lost interest in the project. Along with this I have noticed that we are running ts-loader even on node_modules. I have excluded the node_modules and run the typescript checker on a separate process using fork-ts-checker-webpack-plugin

The time reduction is ~71% for development on my machine.

Development (npm run dev): image

The webpack.config.js now looks like below:

const path = require('path');

const HtmlWebPackPlugin = require("html-webpack-plugin");
const SpeedMeasurePlugin = require("speed-measure-webpack-plugin");
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
const HappyPack = require('happypack');
var happyThreadPool = HappyPack.ThreadPool({ size: 10 });
const smp = new SpeedMeasurePlugin();

module.exports = smp.wrap({
  module: {
    rules: [
      { test: /\.tsx?$/,
        loader: 'ts-loader',
        options: {
          transpileOnly: true,
          happyPackMode: true
        }
      },
      {
        test: /\.js$/,
        use: 'happypack/loader?id=sml',
        enforce: "pre"
      },
      {
        test: /\.js$/,
        use: 'happypack/loader?id=jsx',
        exclude: /node_modules/,
      },
      {
        test: /\.css$/,
        use: 'happypack/loader?id=css'
      },
      {
        test: /\.scss$/,
        use: 'happypack/loader?id=scss'
      },
      {
        test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
        type: 'asset/resource'
      },
      {
        test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
        type: 'asset'
      },
      {
        test: /\.(png|jpg|gif)$/,
        type: 'asset'
      },
      {
        test: /\.html$/,
        use: [
          {
            loader: "html-loader"
          }
        ]
      }
    ]
  },
  devtool: process.env.WEBPACK_MODE === 'production' ? "source-map" : "eval",
  plugins: [
    new HtmlWebPackPlugin({
      template: "./src/index.html",
      filename: "./index.html"
    }),
    new ForkTsCheckerWebpackPlugin({
      typescript: {
        diagnosticOptions: {
          semantic: true,
          syntactic: true,
        },
      },
    }),
    new HappyPack({
      id: 'jsx',
      threadPool: happyThreadPool,
      loaders: ['babel-loader']
    }),
    new HappyPack({
      id: 'sml',
      threadPool: happyThreadPool,
      loaders: ['source-map-loader']
    }),
    new HappyPack({
      id: 'css',
      threadPool: happyThreadPool,
      loaders: ['style-loader', 'css-loader']
    }),
    new HappyPack({
      id: 'scss',
      threadPool: happyThreadPool,
      loaders: ['style-loader', 'css-loader', 'sass-loader']
    }),
  ],
  resolve: {
    extensions: ['.ts', '.tsx', '.js', '.jsx', '.css'],
    modules: [
      'node_modules',
      path.resolve(__dirname, 'src/')
    ]
  },
  optimization: {
    splitChunks: {
      chunks: 'all',
    },
  },
  output: {
    publicPath: '/'
  },
  devServer: {
    host: '0.0.0.0',
    proxy: {
      '/api': {
        target: 'https://localhost:5000',
        secure: false,
        changeOrigin: true
      }
    }
  }
});
ilija-lazoroski commented 2 years ago

Using thread-loader we got even better results. Because it is 'well' maintained I will go with this approach. Addition to the above is CacheDirectory in babel-loader which will be used when babel first runs.

The time reduction is ~73% for development on my machine.

Development (npm run dev): image

ilija-lazoroski commented 2 years ago

AppImage build time using npm run dist using devtool: source-map: 147s

AppImage build time using npm run dev using devtool: eval-source-map: 41s

Docker build time using npm run dist using devtool: source-map: 153s

Docker build time using npm run dev using devtool: eval-source-map: 38s

MSI build time using npm run dist using devtool: source-map: 155s

MSI build time using npm run dev using devtool: eval-source-map: 43s

ilija-lazoroski commented 2 years ago

Closed by #1880 and created issues: #1878 and #1879.