【问题标题】:Extremely long build times for a medium sized app (120+ seconds) with TypeScript (Vue-Loader and TS-Loader)使用 TypeScript(Vue-Loader 和 TS-Loader)的中型应用程序的构建时间极长(120 多秒)
【发布时间】:2019-04-08 06:13:25
【问题描述】:

我将 Nuxt 2 与 TypeScript 和所有最新的依赖版本一起使用。

我有一个中等大小的应用程序,编译时间太慢了。

我的电脑规格: 锐龙 7 2700X(8 核/16 线程) 16GB DDR4 3000MHZ NVM-SSD

客户端编译需要大约 72 秒。 服务器编译大约需要 55 秒。

我的 package.json

{
  "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"
  }
}

Nuxt.config.js

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 => 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&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}
];

模块/typescript.js

export default function() {
  // Add .ts extension for store, middleware and more
  this.nuxt.options.extensions.push("ts")
  // Extend build
  this.extendBuild(config => {
    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")
    }
  })
}

在构建中使用 --profile 标志后,我发现了慢速加载器:

加载器 │ 请求 │ 时间 │ 时间/请求 │ 描述
ts-loader │ 190 │ 50s │ 265ms │ Ts Loader
vue-loader │ 817 │ 57s │ 70ms │ Vue 加载器

我有大约 44 个 .Vue 组件(全部使用 TypeScript)和 13 个 .Vue 页面。

非常感谢任何帮助。

【问题讨论】:

    标签: typescript vue.js nuxt.js vue-loader ts-loader


    【解决方案1】:

    至于 ts-loader,您应该阅读 https://github.com/TypeStrong/ts-loader#faster-builds 它对我们的构建时间有很大帮助。

    【讨论】:

      【解决方案2】:

      长话短说,可能的罪魁祸首是类型检查与构建的其余部分发生在同一线程上。存在一个将类型检查分叉到不同线程的插件。对于我的个人项目,我看到了 4 倍的加速,只需执行以下操作:

      使用您喜欢的包管理器添加模块

      yarn add fork-ts-checker-webpack-plugin --dev

      将以下内容添加到您的 webpack 配置中:

      const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin'); plugins: [new ForkTsCheckerWebpackPlugin()]

      示例配置可能如下所示:

      const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
      
      const webpackConfig = {
        context: __dirname, // to automatically find tsconfig.json
        entry: './src/index.ts',
        module: {
          rules: [
            {
              test: /\.tsx?$/,
              loader: 'ts-loader',
              options: {
                // disable type checker - we will use it in fork plugin
                transpileOnly: true
              }
            }
          ]
        },
        plugins: [new ForkTsCheckerWebpackPlugin()]
      };
      

      【讨论】:

      • 不工作让情况变得更糟
      猜你喜欢
      • 1970-01-01
      • 2021-05-05
      • 2019-08-09
      • 2017-05-27
      • 2017-02-22
      • 2018-09-12
      • 2016-07-19
      • 2020-05-03
      • 2020-08-31
      相关资源
      最近更新 更多