web-dev-qa-db-ja.com

vue-cliを使用して深くネストされたHTMLを構築するのに時間がかかります

テンプレートのhtmlが比較的深くなると、vue-cli(2.9.6、ただし3.0.0 beta *にも同じ問題があります)の構築プロセスに永遠に時間がかかることがわかりました。

たとえば、いくつかのdivsを事前に含まれているApp.vueに追加しました。

<template>
  <div id="app">
    <img src="./assets/logo.png">
    <div><div><div><div></div></div></div></div>
    <HelloWorld/>
  </div>
</template>

それほど時間はかかりません。

しかし、これを取得したら:

<template>
  <div id="app">
    <img src="./assets/logo.png">
    <div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div>
    <HelloWorld/>
  </div>
</template>

構築プロセスには永遠に時間がかかり、この深さの巣はそれほど珍しいものではないと思います。

この問題にどのように対処すればよいですか?

詳細を編集する)

問題は環境固有のものである可能性があるため、詳細を以下に示します。

この問題は、少なくとも次の環境で再現できます。

  • mac mini上のmacOS High Sierra(2014年後半)
  • Dell XPS 13上のUbuntu 18.04

ノードとnpmバージョンは次のとおりです。

node --version
# prints
v8.9.4
# and
npm version
# prints
{ npm: '6.1.0',
  ares: '1.10.1-DEV',
  cldr: '31.0.1',
  http_parser: '2.7.0',
  icu: '59.1',
  modules: '57',
  nghttp2: '1.25.0',
  node: '8.9.4',
  openssl: '1.0.2n',
  tz: '2017b',
  unicode: '9.0',
  uv: '1.15.0',
  v8: '6.1.534.50',
  zlib: '1.2.11' }

これらを使用して、Macで次のことを再試行しました。

npm uninstall -g vue-cli
npm install -g vue-cli
vue init webpack divnest
# then some Enter keys - everything is default
cd divnest

次に、App.vueを開き、多くのdivを配置します。

<template>
  <div id="app">
    <img src="./assets/logo.png">
    <div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div>
    <router-view/>
  </div>
</template>

(ここではデフォルトの設定を使用しているため、元の投稿とは異なり<router-view/>が含まれていますが、問題ではないはずです。)

そして最後に、

npm run dev

これは永遠にかかります-具体的には、プロセスはこの時点で停止します:

 13% building modules 28/31 modules 3 active ...myname/Documents/divnest/src/App.vue

の場合

npm run build

、プロセスはこの時点で停止します。

> [email protected] build /Users/myname/Documents/divnest
> node build/build.js

Hash: 483ebabc54d5aed79fd7
Version: webpack 3.12.0
Time: 13742ms
                                                  Asset       Size  Chunks             Chunk Names
               static/js/vendor.7fed9fa7b7ba482410b7.js     112 kB       0  [emitted]  vendor
                  static/js/app.f1ebca7a6e0ec0b7ebdf.js      12 kB       1  [emitted]  app
             static/js/manifest.2ae2e69a05c33dfc65f8.js  857 bytes       2  [emitted]  manifest
    static/css/app.30790115300ab27614ce176899523b62.css  432 bytes       1  [emitted]  app
static/css/app.30790115300ab27614ce176899523b62.css.map  828 bytes          [emitted]  
           static/js/vendor.7fed9fa7b7ba482410b7.js.map     553 kB       0  [emitted]  vendor
              static/js/app.f1ebca7a6e0ec0b7ebdf.js.map    23.3 kB       1  [emitted]  app
         static/js/manifest.2ae2e69a05c33dfc65f8.js.map    4.97 kB       2  [emitted]  manifest
                                             index.html  509 bytes          [emitted]  

  Build complete.

  Tip: built files are meant to be served over an HTTP server.
  Opening index.html over file:// won't work.

 94% asset optimization 

それを手放すと... 1155409ms !!!!

 DONE  Compiled successfully in 1155409ms                                                        13:35:34

 I  Your application is running here: http://localhost:8080

さらに編集

@ tony19が指摘したように、可愛らしさが疑わしいと思われます。アドバイスに従って、Ubuntu 18.04でいくつかのパターンを試してみました(Macは今ここにないのでMacではなく、申し訳ありません)。私の結果は次のとおりです。

  • vue-cli 2.9.6 + npm run dev-ハング
  • vue-cli 2.9.6 + npm run build-6秒(これは非常に紛らわしい。上記の100万秒は何でしたか?vue-cliを再インストールすると変更が発生する可能性がありますか?)
  • vue-cli 3.0.0-beta16 + vue serve-ハング(@ tony19のレポートとは対照的に)
  • vue-cli 3.0.0-beta16 + vue build-5秒

さらに編集

だから、これは間違いなくきれいに起因しているようです。 https://github.com/prettier/prettier/issues/1250 はこの問題に対処した元の問題であり、開発チームは https: //github.com/prettier/prettier/pull/2259 は修正しましたが、@ tony19が https:/ /github.com/prettier/prettier/issues/4672 。しかたがない。

"解決"

私はこれをやった-@ tony19のレポートに従って、/node_modules/vue-loader/lib/template-compiler/index.js行を変更する78:81

if (!isProduction) {
  code = prettier.format(code, { semi: false })
}

// if (!isProduction) {
//   code = prettier.format(code, { semi: false })
// }

したがって、問題は解決されます。フロントエンド、ありがとうございます。

18
akai

説明したとおりにパフォーマンスの問題を再現できます(macOS High Sierra 10.13.4、Node 8.9.4および9.11.1)。この問題は、新しく作成されたvue-cli 3でも発生します。 .xプロジェクト。

vue-loaderのテンプレートコンパイラ から呼び出されるprettierでハングが実際に発生しています。ネストされた<div>sはvue-loaderによってJavaScriptに変換され、次のスニペットになります。

var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{attrs:{"id":"app"}},[_c('img',{attrs:{"src":require("./assets/logo.png")}}),_vm._v(" "),_c('router-view'),_vm._v(" "),_vm._m(0)],1)}
var staticRenderFns = [function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',[_c('div',[_c('div',[_c('div',[_c('div',[_c('div',[_c('div',[_c('div',[_c('div',[_c('div',[_c('div',[_c('div',[_c('div',[_c('div',[_c('div',[_c('div',[_c('div',[_c('div',[_c('div',[_c('div',[_c('div',[_c('div',[_c('div',[_c('div',[_c('div')])])])])])])])])])])])])])])])])])])])])])])])])}]

vue-loaderはこの長い文字列をprettierに渡します。処理には約159秒かかります。バグの原因は、divsを作成する深くネストされた関数呼び出しです。このバグはprettierIssue 4672 )で報告しました。

それまでの間、HTMLをリファクタリングして、深いネストを回避することをお勧めします。古いテンプレートに固執する必要がある場合は、vue-loaderがプロダクションビルドのprettierをスキップするため、プロダクションモードでビルドすることで問題を回避できます。

NODE_ENV=production npm run dev

[〜#〜] update [〜#〜]vue-loader v15.5.0は prettify を追加します= prettierの無効化を許可するオプション(@vue/cliを最新バージョンに更新して、vue-loaderが新しいオプションで最新であることを確認してください)。このオプションは次のように使用できます。

  1. vue.config.js(まだ存在しない場合)をプロジェクトのルートに追加します。

  2. ファイルを編集して、以下を含めます。

    module.exports = {
      chainWebpack: config => {
        config.module
          .rule('vue')
          .use('vue-loader')
            .loader('vue-loader')
            .tap(options => {
              options.prettify = false
              return options
            })
      }
    }
    
19
tony19

更新2019

最近vue-loaderは、開発中にもprettierを無効にするためにオプションにフラグを追加しました。

prettify: falseオプションにvue-loaderを追加するだけです。

https://vue-loader.vuejs.org/options.html#prettify

注意:最新のvue-loaderバージョンを使用していることを確認してください

2
Orlandster

ネストされた25個の<div>には特に問題はありません:(Vueランタイムコンパイラの例の下にあり、ブラウザで直接簡単にテストできるように)

new Vue({
  el: '#app',
  template: '#app-template',
});
#app div {
  border: 1px solid grey;
  padding: 1px;
}
<script src="https://unpkg.com/vue@2"></script>

<div id="app">
</div>

<template id="app-template">
<div id="app">
  <div>
    <div>
      <div>
        <div>
          <div>
            <div>
              <div>
                <div>
                  <div>
                    <div>
                      <div>
                        <div>
                          <div>
                            <div>
                              <div>
                                <div>
                                  <div>
                                    <div>
                                      <div>
                                        <div>
                                          <div>
                                            <div>
                                              <div>
                                                <div>
                                                  <div>25 nested <code>&lt;div&gt;</code>'s</div>
                                                </div>
                                              </div>
                                            </div>
                                          </div>
                                        </div>
                                      </div>
                                    </div>
                                  </div>
                                </div>
                              </div>
                            </div>
                          </div>
                        </div>
                      </div>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
  </div>
</template>

Vue CodeSandboxのCLIプロジェクト、おそらくあなたの例により近いデモを示します: https://codesandbox.io/s/v3knpl447l

(つまり、テンプレートをプリコンパイルするため、構築プロセスはCodeSandboxサーバーで実際に行われます)

0
ghybs

Vue-cli 3.1.1(TypeScript + SCSS)とBootstrap(デフォルトではネストが必要です)。構造例:

<template>
    <div class="container">
        <div class="row">
            <div class="col-12">
                <div class="card-deck">
                    <div class="card">
                        <div class="card-body">
                            <div class="accordion">
                                <div class="card">
                                    <div class="card-header">
                                        ...
                                    </div>
                                    <div class="collapse">
                                        <div class="card-body">
                                            <div class="row">
                                                <div class="col-12 form-group">
                                                    <label>...</label>
                                                    <div class="dropdown">
                                                        <button class="custom-select" type="button" data-toggle="dropdown">{{someValue}}</button>
                                                        <div class="dropdown-menu">
                                                            <a class="dropdown-item" href="#" :data-key="somekey1" @click="onClickMethod">value1</a>
                                                            <a class="dropdown-item" href="#" :data-key="somekey2" @click="onClickMethod">value2</a>
                                                            ...

400行以上のコード(テンプレート+ TypeScript + SCSS)をコンパイルするのに最大12秒かかりました。削除後:

:data-key="somekey1" @click="onClickMethod"
:data-key="somekey2" @click="onClickMethod"

コードのコンパイルには約5〜6秒かかりました。コードをカスタムコンポーネントに移動した後(およびVueコンポーネントからHelper.tsファイルへのTypeScriptコード)):

<template>
    <div class="container">
        <div class="row">
            <div class="col-12">
                <div class="card-deck">
                    <div class="card">
                        <div class="card-body">
                            <div class="accordion">
                                <div class="card">
                                    <div class="card-header">
                                        ...
                                    </div>
                                    <div class="collapse">
                                        <div class="card-body">
                                            <SubComponent/>

コンパイルには約700msが必要です(1つのメインコンポーネントと2つの追加のサブコンポーネント。各ファイルのコードは100行未満+ Helper.tsのコードはちょうど97行です)。

したがって、npm run serveのパフォーマンスが悪い場合は、まずサブコンポーネントを試してください。npm run buildの呼び出し中にコンパイル時間に大きな違いは見られなかったので、この問題は(おそらく間違って) serveに対して有効であるがbuildに対して無効になっているコードプリティファイア(TSLintは保存アクションでは呼び出されないため、私の場合はnpm run serveに影響しません)。

0
dominik