title: Extremely long build times for a medium sized app (120+ seconds) with TypeScript (Vue-Loader and TS-Loader)
body: <p>I am using Nuxt 2 with TypeScript and all the latest  dependency versions.</p>
  
  <p>I have a medium sized app and the compilation time is way too slow.</p>
  
  <p>My PC specs:
  Ryzen 7 2700X (8 Cores/16 Threads)
  16 GB DDR4 3000MHZ
  NVM-SSD</p>
  
  <p>Client-compilation takes ~72 seconds.
  Server-compilation takes ~55 seconds.</p>
  
  <p>My package.json</p>
  
  <pre><code>{
    "name": "nuxt",
    "version": "1.0.0",
    "private": true,
    "dependencies": {
      "@fortawesome/fontawesome-svg-core": "^1.2.8",
      "@fortawesome/free-brands-svg-icons": "^5.5.0",
      "@fortawesome/free-solid-svg-icons": "^5.5.0",
      "@fortawesome/vue-fontawesome": "^0.1.2",
      "@nuxtjs/axios": "^5.3.4",
      "@types/lodash": "^4.14.117",
      "bulma": "^0.7.2",
      "lodash": "^4.17.11",
      "nuxt": "^2.2.0",
      "nuxt-buefy": "^0.3.1",
      "nuxt-class-component": "^1.2.1",
      "nuxt-fontawesome": "^0.3.0",
      "nuxt-property-decorator": "^1.2.0",
      "v-lazy-image": "^1.2.2",
      "vue-infinite-scroll": "^2.0.2",
      "vue-moment": "^4.0.0",
      "vue-multiselect": "^2.1.3",
      "vue-recaptcha": "^1.1.1",
      "vue2-leaflet": "^1.1.1",
      "vue2-leaflet-markercluster": "^2.0.0",
      "vue2-scrollspy": "^2.3.1",
      "vuex-class": "^0.3.0"
    },
    "scripts": {
      "dev": "nuxt",
      "build": "nuxt build",
      "start": "nuxt start",
      "generate": "nuxt generate"
    },
    "devDependencies": {
      "@types/node": "^10.12.2",
      "babel-plugin-transform-class-properties": "^6.24.1",
      "babel-plugin-transform-decorators-legacy": "^1.3.5",
      "node-sass": "^4.9.4",
      "sass-loader": "^7.1.0",
      "ts-loader": "5.3.0",
      "typescript": "^3.1.6"
    }
  }
  </code></pre>
  
  <p>Nuxt.config.js</p>
  
  <pre><code>import parseArgs from "minimist";
  
  // https://github.com/buefy/buefy/issues/1052
  global.File = typeof window === 'undefined' ? Object : window.File;
  
  const argv = parseArgs(process.argv.slice(2), {
      alias: {
          H: "hostname",
          p: "port"
      },
      string: ["H"],
      unknown: parameter =&gt; false
  });
  
  const port =
      argv.port ||
      process.env.PORT ||
      process.env.npm_package_config_nuxt_port ||
      "3000";
  const host =
      argv.hostname ||
      process.env.HOST ||
      process.env.npm_package_config_nuxt_host ||
      "localhost";
  
  export const env = {
      baseUrl: process.env.BASE_URL || `http://${host}:${port}`
  };
  export const head = {
      title: "Conference Finder",
      meta: [
          {charset: "utf-8"},
          {
              name: "viewport",
              content: "width=device-width, initial-scale=1"
          },
          {
              hid: "description",
              name: "description",
              content: "Nuxt.js project"
          }
      ],
      link: [
          {
              rel: "icon",
              type: "image/x-icon",
              href: "/favicon.ico"
          }
      ],
      script: [
          {src: 'https://www.google.com/recaptcha/api.js?onload=vueRecaptchaApiLoaded&amp;render=explicit'}
      ]
  };
  
  /*
  ** Customize the progress-bar color
  */
  export const loading = {color: "#3B8070"};
  
  /*
  ** Build configuration
  */
  export const css = [
      {src: "~/assets/css/main.scss", lang: 'scss'},
      {src: 'leaflet/dist/leaflet.css', lang: 'css'},
      {src: 'leaflet.markercluster/dist/MarkerCluster.css', lang: 'css'},
      {src: 'leaflet.markercluster/dist/MarkerCluster.Default.css', lang: 'css'},
      {src: 'vue-multiselect/dist/vue-multiselect.min.css', lang: 'css'}
  ];
  
  export const build = {
      build: {
          babel: {
              plugins: ['transform-decorators-legacy', 'transform-class-properties']
          },
          extend (config, { isDev, isClient }) {
  
          }
      }
  };
  export const modules = [
      "@nuxtjs/axios",
      "~/modules/typescript.js",
      'nuxt-buefy',
      ["nuxt-fontawesome", {
          imports: [
              {
                  set: '@fortawesome/free-solid-svg-icons',
                  icons: [
                      ...]
              }, {
                  set: '@fortawesome/free-brands-svg-icons',
                  icons: [
                      ...
                  ]
              }
          ]
      }]];
  export const axios = {};
  export const plugins = [
      "~/plugins/filters.ts",
      "~/plugins/vue-moment.ts",
      {src: "~/plugins/vue-lazyimage.ts", ssr: false},
      {src: "~/plugins/vue-leaflet.ts", ssr: false},
      {src: "~/plugins/vue-infinite-scroll.ts", ssr: false},
      {src: '~/plugins/vue2-scrollspy.ts', ssr: false}
  ];
  </code></pre>
  
  <p>modules/typescript.js</p>
  
  <pre><code>export default function() {
    // Add .ts extension for store, middleware and more
    this.nuxt.options.extensions.push("ts")
    // Extend build
    this.extendBuild(config =&gt; {
      const tsLoader = {
        loader: "ts-loader",
        options: {
          appendTsSuffixTo: [/\.vue$/]
        },
        exclude: [
          /vendor/,
          /\.nuxt/
        ]
      }
      // Add TypeScript loader
      config.module.rules.push(
        Object.assign(
          {
            test: /((client|server)\.js)|(\.tsx?)$/
          },
          tsLoader
        )
      )
      // Add TypeScript loader for vue files
      for (let rule of config.module.rules) {
        if (rule.loader === "vue-loader") {
          rule.options.loaders = rule.options.loaders || {}
          rule.options.loaders.ts = tsLoader
        }
      }
      // Add .ts extension in webpack resolve
      if (
        config.resolve.extensions.indexOf(".ts") ===
        -1
      ) {
        config.resolve.extensions.push(".ts")
      }
    })
  }
  </code></pre>
  
  <p>After using --profile flag on the build, I identified the slow loaders:</p>
  
  <p>Loader           │ Requests │ Time │ Time/Request │ Description<br>
  ts-loader       │ 190           │ 50s   │ 265ms              │ Ts Loader<br>
  vue-loader    │ 817           │ 57s   │ 70ms                │ Vue Loader</p>
  
  <p>I have ~44 .Vue components (all with TypeScript) and 13 .Vue pages.</p>
  
  <p>Any help is greatly appreciated.</p>