テンプレートのhtmlが比較的深くなると、vue-cli(2.9.6、ただし3.0.0 beta *にも同じ問題があります)の構築プロセスに永遠に時間がかかることがわかりました。
たとえば、いくつかのdiv
sを事前に含まれている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>
構築プロセスには永遠に時間がかかり、この深さの巣はそれほど珍しいものではないと思います。
この問題にどのように対処すればよいですか?
問題は環境固有のものである可能性があるため、詳細を以下に示します。
この問題は、少なくとも次の環境で再現できます。
ノードと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ではなく、申し訳ありません)。私の結果は次のとおりです。
npm run dev
-ハングnpm run build
-6秒(これは非常に紛らわしい。上記の100万秒は何でしたか?vue-cliを再インストールすると変更が発生する可能性がありますか?)vue serve
-ハング(@ tony19のレポートとは対照的に)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 })
// }
したがって、問題は解決されます。フロントエンド、ありがとうございます。
説明したとおりにパフォーマンスの問題を再現できます(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秒かかります。バグの原因は、div
sを作成する深くネストされた関数呼び出しです。このバグはprettier
( Issue 4672 )で報告しました。
それまでの間、HTMLをリファクタリングして、深いネストを回避することをお勧めします。古いテンプレートに固執する必要がある場合は、vue-loader
がプロダクションビルドのprettier
をスキップするため、プロダクションモードでビルドすることで問題を回避できます。
NODE_ENV=production npm run dev
[〜#〜] update [〜#〜]vue-loader
v15.5.0は prettify
を追加します= prettier
の無効化を許可するオプション(@vue/cli
を最新バージョンに更新して、vue-loader
が新しいオプションで最新であることを確認してください)。このオプションは次のように使用できます。
vue.config.js
(まだ存在しない場合)をプロジェクトのルートに追加します。
ファイルを編集して、以下を含めます。
module.exports = {
chainWebpack: config => {
config.module
.rule('vue')
.use('vue-loader')
.loader('vue-loader')
.tap(options => {
options.prettify = false
return options
})
}
}
最近vue-loader
は、開発中にもprettier
を無効にするためにオプションにフラグを追加しました。
prettify: false
オプションにvue-loader
を追加するだけです。
https://vue-loader.vuejs.org/options.html#prettify
注意:最新のvue-loaderバージョンを使用していることを確認してください
ネストされた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><div></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サーバーで実際に行われます)
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
に影響しません)。