首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >用vue-cli构建深度嵌套的html需要很长时间。

用vue-cli构建深度嵌套的html需要很长时间。
EN

Stack Overflow用户
提问于 2018-06-08 10:14:12
回答 3查看 7K关注 0票数 20

我发现vue-cli (2.9.6,但3.0.0 beta*有同样的问题)的构建过程一旦模板的html变得相对深入就永远不会有结果。

例如,我刚刚在App.vue中添加了一些预先包含的div

代码语言:javascript
复制
<template>
  <div id="app">
    <img src="./assets/logo.png">
    <div><div><div><div></div></div></div></div>
    <HelloWorld/>
  </div>
</template>

这不会花太长时间。

但是一旦它得到了这个:

代码语言:javascript
复制
<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>

然后,构建过程将永远持续下去,我相信这种深度的巢穴并不罕见。

我该如何处理这个问题呢?

编辑(详细信息)

似乎问题可能是特定于环境的,所以下面是详细信息。

这个问题至少可以在以下环境中重现:

  • macOS High Sierra on Mac mini (2014年末)
  • Ubuntu 18.04 on Dell XPS 13

节点和npm版本为:

代码语言:javascript
复制
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上重试了以下操作:

代码语言:javascript
复制
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:

代码语言:javascript
复制
<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/>,但应该不是问题。)

最后,

代码语言:javascript
复制
npm run dev

这将永远持续下去--具体地说,这个过程会在这一点停止:

代码语言:javascript
复制
 13% building modules 28/31 modules 3 active ...myname/Documents/divnest/src/App.vue

在以下情况下

代码语言:javascript
复制
npm run build

,则该过程在该点停止:

代码语言:javascript
复制
> 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 

如果我放手了,就得...1155409ms!

代码语言:javascript
复制
 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 - hang
  • vue-cli 2.9.6 + npm run build -6秒(这太令人困惑了。上面的一百万秒是什么!?也许重新安装vue-cli会导致change?)
  • vue-cli 3.0.0-beta16 + vue serve - hang (而不是@tony19的report)
  • 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

代码语言:javascript
复制
if (!isProduction) {
  code = prettier.format(code, { semi: false })
}

代码语言:javascript
复制
// if (!isProduction) {
//   code = prettier.format(code, { semi: false })
// }

这样问题就解决了。谢谢你前台,谢谢你。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2018-06-12 16:12:29

我可以重现您所描述的性能问题(macOS High Sierra 10.13.4,Node8.9.4和9.11.1)。新创建的vue-cli 3.x项目也会出现此问题。

挂起实际上发生在从vue-loader's template compiler调用的prettier中。嵌套的<div>vue-loader转换为JavaScript,并成为以下代码片段:

代码语言: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秒。bug的原因是创建div的深度嵌套函数调用。我已经在prettier (Issue 4672)中报告了此bug。

同时,我建议重构您的HTML以避免深度嵌套。如果您需要坚持使用旧模板,您可以通过在生产模式下构建来解决此问题,因为vue-loader会跳过prettier进行生产构建:

代码语言:javascript
复制
NODE_ENV=production npm run dev

UPDATE vue-loader v15.5.0添加了prettify选项以允许禁用prettier (更新到最新版本的@vue/cli,以确保您的vue-loader使用新选项是最新的)。您可以使用此选项,如下所示:

  1. 在project.
  2. Edit的根目录下添加要包含的文件的vue.config.js (如果它不存在):

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

票数 25
EN

Stack Overflow用户

发布于 2018-11-17 20:12:57

我在vue-CLI3.1.1 (TypeScript + SCSS)和Bootstrap (默认情况下需要一些嵌套)中遇到了类似的问题。示例结构:

代码语言:javascript
复制
<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秒。删除后:

代码语言:javascript
复制
:data-key="somekey1" @click="onClickMethod"
:data-key="somekey2" @click="onClickMethod"

代码大约需要5-6秒才能编译完成。在将代码移动到自定义组件(以及从Vue组件到Helper.ts文件的一些TypeScript代码)之后:

代码语言:javascript
复制
<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的编译时间(一个主组件和两个附加的子组件,每个文件不到100行代码+ Helper.ts恰好有97行代码)。

因此,如果你的npm run serve性能不佳,先试试子组件,我在调用npm run build时没有注意到编译时间上的太大差异,所以我假设(可能是错误的)这个问题也是由代码修饰器引起的,它在serve上启用,但在build上禁用(TSLint在保存操作时不会被调用,所以在我的例子中它不会影响npm run serve )。

票数 1
EN

Stack Overflow用户

发布于 2018-06-11 02:11:10

我对你的25个嵌套<div>没有任何特别的问题:(下面是Vue运行时编译器的例子,这样你就可以很容易地在你的浏览器中直接测试它)

代码语言:javascript
复制
new Vue({
  el: '#app',
  template: '#app-template',
});
代码语言:javascript
复制
#app div {
  border: 1px solid grey;
  padding: 1px;
}
代码语言:javascript
复制
<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>

下面是一个演示,其中包含CodeSandbox上的一个Vue CLI项目,可能更接近您的示例:https://codesandbox.io/s/v3knpl447l

(例如,它预编译模板,因此构建过程实际上发生在CodeSandbox服务器上)

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50752427

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档