使用 vue-cli 构建深度嵌套的 html 需要永远 [英] Building deeply nested html with vue-cli takes forever
问题描述
我发现 vue-cli(2.9.6,但 3.0.0 beta* 有同样的问题)的构建过程一旦模板的 html 变得相对深入.
例如,我只是在预先包含的 App.vue
中添加了一些 div
:
<div id="应用程序"><img src="./assets/logo.png"><div><div><div><div></div></div></div></div><HelloWorld/>
</模板>
不需要那么长时间.
但是一旦得到这个:
<div id="应用程序"><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/>
</模板>
那么建造过程需要很长时间,我相信这种深度的巢穴并不少见.
我该如何处理这个问题?
编辑(详细信息)
看来问题可能是特定于环境的,所以这里是详细信息.
这个问题至少可以在这些环境下重现:
- Mac mini 上的 macOS High Sierra(2014 年末)
- 戴尔 XPS 13 上的 Ubuntu 18.04
以及 node 和 npm 版本是:
node --version# 印刷v8.9.4# 和npm 版本# 印刷{ npm: '6.1.0',战神:'1.10.1-DEV',cldr: '31.0.1',http_parser: '2.7.0',ICU: '59.1',模块:'57',nghttp2: '1.25.0',节点:'8.9.4',openssl: '1.0.2n',tz: '2017b',unicode: '9.0',紫外线:'1.15.0',v8: '6.1.534.50',zlib: '1.2.11' }
有了这些,我在我的 Mac 上重试了以下操作:
npm uninstall -g vue-clinpm install -g vue-clivue init webpack divnest# 然后是一些 Enter 键 - 一切都是默认的cd divnest
然后,打开App.vue
,放很多div:
<div id="应用程序"><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><路由器视图/>
</模板>
(由于我在这里使用了默认设置,
与原始帖子不同,但应该不是问题.)
最后,
npm run dev
这需要永远 - 具体来说,该过程在此时停止:
13% 构建模块 28/31 个模块 3 个活动 ...myname/Documents/divnest/src/App.vue
在
的情况下npm 运行构建
,过程到此停止:
<代码>>divnest@1.0.0 构建/Users/myname/Documents/divnest>节点构建/build.js哈希:483ebabc54d5aed79fd7版本:webpack 3.12.0时间:13742ms资产大小块块名称静态/js/vendor.7fed9fa7b7ba482410b7.js 112 kB 0 [emitted] 供应商静态/js/app.f1ebca7a6e0ec0b7ebdf.js 12 kB 1 [发出] 应用程序static/js/manifest.2ae2e69a05c33dfc65f8.js 857 字节 2 [emitted] 清单静态/css/app.30790115300ab27614ce176899523b62.css 432 字节 1 [emitted] appstatic/css/app.30790115300ab27614ce176899523b62.css.map 828 字节 [emitted]静态/js/vendor.7fed9fa7b7ba482410b7.js.map 553 kB 0 [emitted] 供应商静态/js/app.f1ebca7a6e0ec0b7ebdf.js.map 23.3 kB 1 [发出] 应用程序static/js/manifest.2ae2e69a05c33dfc65f8.js.map 4.97 kB 2 [发出] 清单index.html 509 字节 [发出]构建完成.提示:构建的文件旨在通过 HTTP 服务器提供服务.通过 file://打开 index.html 将不起作用.94% 资产优化
如果我放手,它需要...... 1155409ms!!!!!!
DONE 1155409ms 13:35:34 编译成功我你的应用程序在这里运行: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 secs(这太令人困惑了.上面的 100 万秒是多少!?也许重新安装 vue-cli 需要更改?)立> - vue-cli 3.0.0-beta16 +
vue serve
- 挂起(与@tony19 的报告相反) - vue-cli 3.0.0-beta16 +
vue build
- 5 秒
更多编辑
所以,看来这肯定是prettier造成的.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 项目也会出现此问题.
挂起实际上发生在 prettier
中,从 vue-loader
的模板编译器.嵌套的 <div>
被 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('路由器视图'),_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
的深层嵌套函数调用.我在 prettier
(问题 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: 配置 =>{配置模块.rule('vue').use('vue-loader').loader('vue-loader').tap(选项 => {options.prettify = false退货选项})}}
I found that vue-cli (2.9.6, but 3.0.0 beta* has the same issue) 's building process takes forever once the template's html gets relativelly deep.
For example, I just added some div
s to App.vue
which is pre-included:
<template>
<div id="app">
<img src="./assets/logo.png">
<div><div><div><div></div></div></div></div>
<HelloWorld/>
</div>
</template>
which doesn't take so long.
But once it gets this:
<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>
then the building process takes forever, and I believe that the nest of this depth isn't so uncommon.
How should I deal with this problem?
EDIT(Details)
It seems that the problem might be environment specific, so here are the details.
This problem can be reproduced with these environments at least:
- macOS High Sierra on Mac mini (Late 2014)
- Ubuntu 18.04 on Dell XPS 13
and node and npm version are:
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' }
With these, I've retried the followings on my Mac:
npm uninstall -g vue-cli
npm install -g vue-cli
vue init webpack divnest
# then some Enter keys - everything is default
cd divnest
Then, open up App.vue
and put many divs:
<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>
(Since I used the default settings here, <router-view/>
is included unlike the original post, but should not be the problem.)
And finally,
npm run dev
which takes forever - specifically, the process stops at this point:
13% building modules 28/31 modules 3 active ...myname/Documents/divnest/src/App.vue
In the case of
npm run build
, the process stops at this point:
> divnest@1.0.0 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
and if I let it go, it takes... 1155409ms!!!!
DONE Compiled successfully in 1155409ms 13:35:34
I Your application is running here: http://localhost:8080
MORE EDIT
As @tony19 pointed out, prettier is the likely suspect. Following the advice, I've tried some patterns with Ubuntu 18.04 (not Mac because Mac isn't here right now, sorry) and my results are:
- vue-cli 2.9.6 +
npm run dev
- hang - vue-cli 2.9.6 +
npm run build
- 6 secs (This is so confusing. What was the 1 million seconds above!? Maybe reinstalling vue-cli owes the change?) - vue-cli 3.0.0-beta16 +
vue serve
- hang (as opposed to @tony19's report) - vue-cli 3.0.0-beta16 +
vue build
- 5 secs
EVEN MORE EDIT
So, it seems that this is definitely caused by prettier. https://github.com/prettier/prettier/issues/1250 is the original issue that addressed this problem and the dev team thought that https://github.com/prettier/prettier/pull/2259 fixed it, but the reality is that it couldn't handle my case, as @tony19 shows it on https://github.com/prettier/prettier/issues/4672 . Oh well.
"SOLUTION"
I ended up doing this - following @tony19's report, changing /node_modules/vue-loader/lib/template-compiler/index.js
lines 78:81
if (!isProduction) {
code = prettier.format(code, { semi: false })
}
to
// if (!isProduction) {
// code = prettier.format(code, { semi: false })
// }
thus the problem is solved. Thank you frontend, thank you.
I can reproduce the performance issue as you described (macOS High Sierra 10.13.4, Node 8.9.4 and 9.11.1). The issue also occurs with a newly created vue-cli
3.x project.
The hang is actually happening in prettier
, called from vue-loader
's template compiler. The nested <div>
s are converted into JavaScript by vue-loader
, and that becomes the following snippet:
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
passes this long string to prettier
, which takes about 159 seconds to process. The cause of the bug is the deeply nested function calls that create the div
s. I've reported this bug in prettier
(Issue 4672).
In the meantime, I recommend refactoring your HTML to avoid deep nesting. If you need to stick with the old template, you could workaround the issue by building in production mode, as vue-loader
skips prettier
for production builds:
NODE_ENV=production npm run dev
UPDATE vue-loader
v15.5.0 adds the prettify
option to allow disabling prettier
(update to the latest version of @vue/cli
to ensure your vue-loader
is current with the new option). You can use this option as follows:
Add
vue.config.js
(if it doesn't exist already) to the root of your project.Edit the file to include:
module.exports = { chainWebpack: config => { config.module .rule('vue') .use('vue-loader') .loader('vue-loader') .tap(options => { options.prettify = false return options }) } }
这篇关于使用 vue-cli 构建深度嵌套的 html 需要永远的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!