Building deeply nested html with vue-cli takes forever - vue.js

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 divs 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 divs. 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
})
}
}

Update 2019
Recently vue-loader added a flag in their options in order to disable prettier also during development.
Just add prettify: false to your vue-loader options.
https://vue-loader.vuejs.org/options.html#prettify
Notice: Just make sure you have the latest vue-loader version

I had similar issues with vue-cli 3.1.1 (TypeScript + SCSS) and Bootstrap (which by default requires some nesting). Example structure:
<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>
...
needed ~12 seconds to compile 400+ lines of code (template + TypeScript + SCSS). After removing:
:data-key="somekey1" #click="onClickMethod"
:data-key="somekey2" #click="onClickMethod"
the code needed ~5-6 seconds to compile. After moving the code to custom component (and some TypeScript code from Vue component to Helper.ts file):
<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/>
it needs ~700ms to compile (one main component and two additional sub-components, each file having less than 100 lines of code + Helper.ts having exactly 97 lines of code).
So if you suffer from poor npm run serve performance, try sub-components first, I didn't noticed much difference in compile time while invoking npm run build so I assume (maybe incorrectly) that this problem is also caused by code prettifier which is enabled for serve but disabled for build (TSLint is not invoked on save action so it does not affect npm run serve in my case).

I do not have any particular issue with your 25 nested <div>'s: (below example with Vue runtime compiler, so that you can easily test it directly in your browser)
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>
Here is a demo with a Vue CLI project on CodeSandbox, probably closer to your example: https://codesandbox.io/s/v3knpl447l
(i.e. it precompiles the templates, so the building process actually happens on CodeSandbox server)

Related

Custom MathJax snippet expression disappears after adding the snippet in CMS page - Odoo 15

I have created a snippet to convert the tex commands to expressions and while the snippet is added to the CMS page, the commands are converting into expressions but its getting disappears after a few seconds.
Also, I have tried dynamically by adding the command through js and converting it using the MathJax.typeset() and MathJax.Hub.Queue(['Typeset', MathJax.Hub, tag]);.
But still, the same problem occurs and if we try to add the MathJax js in the snippet then the expressions are displayed multiple times.
Please find the below snippet and help us on finding the issue.
<template id="mathjax_form_12" name="Mathjax">
<section>
<t t-call="web.layout">
<div class="section">
<div class="section-contact">
<div class="container">
<div class="contact-form">
<p>
When \(a \ne 0\), there are two solutions to \(ax^2 + bx + c = 0\) and they are
\[x = {-b \pm \sqrt{b^2-4ac} \over 2a}.\]
$$f(x,y)=\int_0^\infty dp\int_0^\infty dq \frac{pqf(p,q)}{\sqrt{x^2+y^2}}$$
</p>
</div>
</div>
</div>
</div>
<script>
(function(){
MathJax = {
tex: {
inlineMath: [['$'], ['\\(',')']],
packages: ['base', 'newcommand', 'configMacros']
},
};
})();
</script>
<script async="1" src='https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_SVG'></script>
</t>
</section>
</template>
Thanks!!

Issues with downloading a PDF after deploying Vue.js app

So I'm creating a Vue.js web app to act as my resume. On there, I want users to be able to actually download a copy of my resume, but I can't seem to get it working correctly. On my Home.vue page, I have:
<template>
<div class="flex-grow overflow-auto max-h-screen w-full dark:text-gray-300">
<div class="m-auto pt-4 lg:grid lg:grid-cols-2 lg:grid-rows-2 lg:gap-8">
<div class="m-auto">
<img class="rounded-md" alt="headshot" src="../assets/headshot.jpg">
</div>
<div class="m-auto">
<h2 class="text-2xl pl-2 py-4 text-center lg:text-left lg:text-8xl lg:px-8">Quick blurb</h2>
</div>
<div class="lg:col-span-2 mx-auto lg:h-8">
<p class="text-base text-center lg:text-2xl">
Email
|
LinkedIn
|
GitHub
|
<a href="my_resume.pdf" download>Resume</a>
</p>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'Home'
}
</script>
When I'm running it locally, I have no issue downloading it. When I run yarn build and run a server from dist/, I have no issue downloading it. It's only when I deploy it on AWS Amplify and test it from there do I run into the issue (basically acting like it can't find it). I've tried putting
<a href="/my_resume.pdf" download>Resume</a>
as well as
<a :href="`${publicPath}my_resume.pdf`" download>Resume</a>
....
data () {
return {
publicPath: process.env.BASE_URL
}
}
to no avail. It's in the public/ folder, along with the index.html and an icon that it has no issues accessing. I have no idea what the issue is.
I dont know what version of vue you use and how did you configure your webpack, so i dont know if my solution is gonna work for you, but here i go:
Add assets folder to your public folder and add in it your pdf:
example
2.to your source folder add file vue.config.js if its not already there: example
define assets as your assets folder in your vue.config.js:
module.export ={
assetsDir: 'assets'
}
<a href="assets/my_resume.pdf" download>Resume</a>
here is the documantation: https://cli.vuejs.org/config/#assetsdir

use dynamic component in the nuxt layout get runtime compile error

in my nuxt application. in layout file use dynamic component for set the component in different pages like below
<template>
<div id="app">
<div id="app-body">
<div id="app-topbar">
<component v-bind:is="actionBar.component"></component>
</div>
<div id="app-content">
<nuxt />
</div>
</div>
</div>
</template>
but when I'm runing the application I got the error in below
You are using the runtime-only build of Vue where the template compiler is not available. Either pre-compile the templates into render functions, or use the compiler-included build.
I'll try to wrap my component in no-ssr tags but the error still exist
as DigitalDrifter already said, you need to use the compiler-included build.
To do that in nuxt try to add the following to your nuxt.config.js:
build: {
extend(config, ctx) {
config.resolve.alias['vue'] = 'vue/dist/vue.common'

Dynamic images failing at production build VueJs

I'm trying to load dynamic images here. My api provides me only with the filename. I combine it with the path (which is the public path of nodejs), then I require it from vuejs to show the image.
It all works fine in the development but when it comes to production build it fails and says "Cannot find the module".
I've spent tons of hours to this and still cannot find an answer.
Edit - I noticed after the production build earlier images I saved from development mode is also displayed in production build.but If I try save a new image from a production build it wouldnt work.My URL is somehow converted to point the public/img folder in vue from development mode.
in HTML
<div class="section-1" v-for="(cardinfo,index) in cardinfos" style="cursor:pointer" :key="index" #mouseover="moment(cardinfo)">
<div class="img-wrap" >
<a #click="deleteAd(cardinfo)">
<mdb-icon v-if="data.myads" icon="trash-alt" class="close red-text" size="lg" />
</a>
<img class="img-fluid ad-image" :src="getImgUrl(cardinfo.images[0])" alt="ad" v-on:click="navigateToAd(cardinfo)" />
</div>
<div class="wrapper" v-on:click="navigateToAd(cardinfo)">
<mdb-card-title>{{cardinfo.subject}}</mdb-card-title>
<hr class="mb-3" />
<div class="venue">
<strong>Venue:</strong>
<p>{{cardinfo.venue}}</p>
</div>
<div class="contact">
<strong>Contact:</strong>
<p>{{cardinfo.contact}}</p>
</div>
<div class="Conducted-By" >
<p title="Click to visit">{{cardinfo.lecturer}}</p>
</div>
</div>
<div class="info-footer">
<div class="info">
<div class="name">{{time}}</div>
</div>
</div>
</div>
in Script
getImgUrl(pic) {
return require("../../../tuition/public/images/" + pic);
}
Error
vue.runtime.esm.js:1888 Error: Cannot find module './marques-brownlee-wallpaper.jpg-1588649676704.png'
at n (.*$:142)
at s (.*$:137)
at o.getImgUrl (Card.vue:107)
at Card.vue?852f:1
at o.jt [as _l] (vue.runtime.esm.js:2630)
at o.B (Card.vue?852f:1)
at o.e._render (vue.runtime.esm.js:3548)
at o.a (vue.runtime.esm.js:4066)
at na.get (vue.runtime.esm.js:4479)
at na.run (vue.runtime.esm.js:4554)```

datetimepicker not working in asp.net core

I was trying to use a DateTimePicker in the Asp.net core Razor page.
I searched the internet and found this page seems works good.
So, I went to the NuPackage and found Bootstrap.v3.datetimepicker 4.17.45, and downloaded it.
After install, I got a warning:
Bootstrap.v3.Datetimepicker 4.17.45 depends on bootstrap.less (>= 3.3.0) but bootstrap.less 3.3.0 was not found. An approximate best match of bootstrap.less 3.3.5 was resolved.
Since the bootstrap version in the project is 3.3.5, and it is a warning instead an error, so I think it should be fine. I copied the sample code into my cshtml file, and run it.
<div class="container">
<div class="row">
<div class='col-sm-6'>
<div class="form-group">
<div class='input-group date' id='datetimepicker1'>
<input type='text' class="form-control" />
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar"></span>
</span>
</div>
</div>
</div>
<script type="text/javascript">
$(function () {
$('#datetimepicker1').datetimepicker();
});
</script>
</div>
</div>
The DateTimePicker showed up. How ever, when I clicked on the calendar button, nothing happened. It seems javascript is not running?
I searched everywhere, and I found this part in the layout page.
<environment include="Development">
<script src="~/lib/jquery/dist/jquery.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.js"></script>
<script src="~/js/site.js" asp-append-version="true"></script>
</environment>
It seems I need to include the js file which contains the datetimepicker here. However, I search the whole project, cannot find any js file contains 'datetimepicker' string.
I am not familiar with front-end structure. what I did wrong or missing? Is my datetimepicker installation not success? is the js script not working on my razor page? How do I diagnose it?
Added:
I enabled the javascript debugging, and I got the following exception. It looks really wired as exception comes from the sample code, which runs with no problem on the original webpage.
The DateTimePicker.js NuGet package itself will be in the %UserProfile%\.nuget\packages directory if you need to get the javascript files.You could copy it in your project and add #section Scripts { and } in your project.
The better way is to use either LibMan or npm to get your client-side libraries.
Here is a simple sample in my project as below.Anyway,the version up to you:
<div class="row">
<div class='col-sm-6'>
<div class="form-group">
<div class='input-group date' id='datetimepicker1'>
<input type='text' class="form-control" />
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar"></span>
</span>
</div>
</div>
</div>
</div>
#section Scripts
{
<link rel="stylesheet" href="~/lib/bootstrap/3.3.0/content/Content/bootstrap.min.css" />
<link rel="stylesheet" href="~/lib/bootstrap/3.3.0/content/Content/bootstrap-theme.min.css" />
<script type="text/javascript" src="~/lib/jquery/1.9.1/Content/Scripts/jquery-1.9.1.js"></script>
<script src="~/lib/moment.js/2.9.0/Content/Scripts/moment.min.js"></script>
<script src="~/lib/bootstrap/3.3.0/content/Scripts/bootstrap.min.js"></script>
<script src="~/lib/bootstrap.v3.datetimepicker/4.17.45/content/Scripts/bootstrap-datetimepicker.min.js"></script>
<script type="text/javascript">
$(function () {
$('#datetimepicker1').datetimepicker();
});
</script>
}
Note: moment.js should render before the datetimepicker.js