Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue with vue.js and building for production #1294

Closed
carbontwelve opened this issue May 4, 2018 · 24 comments
Closed

Issue with vue.js and building for production #1294

carbontwelve opened this issue May 4, 2018 · 24 comments
Labels

Comments

@carbontwelve
Copy link

This is a 🐛 bug report.

When using parcel to build for production it breaks my vue.js application. This only happens when building for production, using parcel in development works with no issue.

🎛 Configuration (.babelrc, package.json, cli command)

package.json:

{
  "dependencies": {
    "vue": "^2.5.16",
    "vue-hot-reload-api": "^2.3.0"
  },
  "devDependencies": {
    "@vue/component-compiler-utils": "^1.1.0",
    "parcel-bundler": "^1.8.1",
    "vue-template-compiler": "^2.5.16"
  }
}

.babelrc

{
  "presets": [
    "env"
  ]
}

🤔 Expected Behavior

When building https://github.com/photogabble/vuejs-incremental-game-tutorial using the command parcel build index.html --public-url=./ --out-file=index.html and uploading to http://builds.photogabble.co.uk/parcel-js-vue-bug-report/ the app should work as expected (when it does work locally in dev mode.)

Below shows a screenshot of the expected behavior:

image

😯 Current Behavior

The app doesn't work as expected. Instead certain buttons are broken as shown in below screen shot (or if you visit that page):

image

In vue the component is loaded via <Resource name="Ore Reserves" units="tons" v-on:doBuy="buyOre" v-on:doSell="sellOre" v-bind:amount="ore" v-bind:buyPrice="oreBuy" v-bind:sellPrice="oreSell" v-bind:credits="credits" transactional></Resource> and the buy/sell prices are passed through from App.vue as not being the zero being displayed.

Given that this only happens when parcel bundles for production I feel that this is a bug with parcel and not with my code.

💁 Possible Solution

The only solution I have found is to run parcel index.html --public-url=./ --out-file=index.html and then upload the development files from the dist folder. This can be seen working at http://builds.photogabble.co.uk/vuejs-incremental-game-tutorial-p1/.

This tells me that there is something wonky going on with the build process for production.

🔦 Context

I was just trying to get a demo of my project online to share and it wasn't working, which is odd to me because it does work when built for development.

💻 Code Sample

🌍 Your Environment

Software Version(s)
Parcel 1.8.1
Node 8.9.4
npm/Yarn 5.6.0/1.6.0
Operating System Windows 10
@luikore
Copy link
Contributor

luikore commented May 9, 2018

I met this issue too.

I think it is related to uglify name mangling: parcel concats some prelude js with uglified code. But uglify-es changes variable / function names in compression without knowing what name has been used by outside code.

Adding a .uglifyrc with {mangle: false} should work around this problem.

@carbontwelve
Copy link
Author

carbontwelve commented May 14, 2018

I added a .uglifyrc as @luikore suggests but the result from parcel build is still broken. I do think its something to do with uglification changing variable names... possibly lower-casing my camel-cased variables.

edit:

After realizing this is indeed an issue with uglify mangling and after adding .uglifyrc, I have managed to fix things for the time being by disabling minification on build completely. parcel build --no-minify results in a working build.

This tells me that there is something wrong with parcels usage of uglify,

@houd1ni
Copy link

houd1ni commented May 16, 2018

Affected me too. Looks like something tries to minify HTML/templates before they transpiled by vue-template transpiler.

<div v-for="(foo, key) in bar> ... </div>" => <div prop="[Object, Object]"> ... </div>

And half of my app is just blank. Without any errors!

@DeMoorJasper
Copy link
Member

DeMoorJasper commented May 16, 2018

Perhaps we can add a check to html and not minify the html if it's part of another asset

this:

if (this.options.minify) {
	await htmlnanoTransform(this);
}

to:

if (this.options.minify && !this.options.rendition) {
	await htmlnanoTransform(this);
}

This is the line that should change:
https://github.com/parcel-bundler/parcel/blob/master/src/assets/HTMLAsset.js#L158

@houd1ni
Copy link

houd1ni commented May 17, 2018

@DeMoorJasper

Thank you! But the trick does work only if we do the same with pretransform simultaneously with transform method that you mentioned. Please, check that it's a good solution and add this to the project!

The solution is:

  async pretransform() {
    if(!this.options.rendition) {
      await posthtmlTransform(this);
    }
  }

  async transform() {
    if (this.options.minify && !this.options.rendition) {
      await htmlnanoTransform(this);
    }
  }

By the way, in a project with .ts, vue, .js, .json and assets there're nothing left unminified after applying the trick 👍

@SteffenL
Copy link
Contributor

SteffenL commented May 17, 2018

The problem (in my case) is with posthtml and its lack of support for self-closing custom tags (I wrote some details in #1363).

I am not sure makes sense to transform the template multiple times as it will go through the Vue template compiler (or whatever compiler) anyway. As long as linked assets (images, etc) within the template are still bundled and linked in the output as expected, then it seems reasonable to me to skip the transformation.

If minification is enabled, then I think that the compiled template (I mean the final HTML) should be minified as well, just after compilation rather than before. Or maybe the minification should be done only on the "root" documents?

Related: #1103 #1316

@houd1ni
Copy link

houd1ni commented May 17, 2018

@SteffenL

Thank you for the great investigation!

I believe, that "the final HTML" after vue-template-compiler should not be a HTML, but rather a render function, that is plain JS, so, it is the reason why I've got the minified bundle without html minification in my project without .html assets.

@DeMoorJasper
Copy link
Member

@houd1ni I think your solution looks good, the only concern I have regarding this fix is assets that get compiled down to html, if it's the final transform than it should be responsible for the minification. Which if I'm not mistaken won't happen in your solution

@SteffenL
Copy link
Contributor

SteffenL commented May 17, 2018

@houd1ni You are right. I was having a dumb moment there thinking the template was included in the JS bundle! So when the template compiles to a render function/JSX, there is no point in minifying the template. It should still be possible for other asset types to compile to HTML and apply minification.

@houd1ni
Copy link

houd1ni commented May 17, 2018

@DeMoorJasper

So, for instance, if one has included her own .html in a project, that IS NOT a .vue file, her bundle will have that unminified html in the output ? If not, could you, please, give an thought experiment, that can produce such faulty resaults? Thank you!

(In the case of .vue, the vue compiler itself will turn it to JS, that I've already mentioned, then uglify will minify that js).

@DeMoorJasper
Copy link
Member

DeMoorJasper commented May 17, 2018

I meant languages like pug and markdown that get transpiled down to html @houd1ni

@gorbypark
Copy link

gorbypark commented May 23, 2018

I think this is also affecting me..parcel index.html works great, parcel build index.html results in a blank page, with no errors. I can see all the assets are loaded but haven't been able to track down the exact cause yet.

@muzafarova
Copy link

Noticed same issue recently. This only happens if there are a few self-closing vue tags.
All fine in dev, but part of contents is missing in build for production, no errors/warnings.

@jbrodriguez
Copy link

jbrodriguez commented Jul 7, 2018

I've just installed 1.9.4 and this is still an issue.

Lost a morning trying to figure it out (drove me a bit insane).

It was compounded by the fact that I can't seem to get the bundler middleware to generate a non-minified build (minify: false doesn't work).

I'll open an issue about that.

EDIT:
Forgot to mention that this happens to me with Vuejs.

@Morgul
Copy link

Morgul commented Jul 7, 2018

Yeah, this issue keeps biting me on my projects. I love parcel, but this bug is intensely frustrating.

@fang0rnz
Copy link

Refactored all self-closing tags as @muzafarova said and it works fine now

@TiboC
Copy link

TiboC commented Jul 31, 2018

Hello,
I have the same issue. It doesn't work after the first self-closing tag.
This doesn't work:
<b-img :src="logo" class="mb-4" fluid alt="Logo" width="72" height="72" />

While this does:
<b-img :src="logo" class="mb-4" fluid alt="Logo" width="72" height="72" ></b-img>

Any chance to get this resolved?
Thanks

Thibaut

@Morgul
Copy link

Morgul commented Aug 28, 2018

To throw more fuel on the fire, I just encountered an example that isn't self closing tags where valid Vue code breaks because of this.

I have a project using BootstrapVue, and in it I'm popping some modals. I used the directive shorthand for that:

<b-btn variant="danger" class="float-right" v-b-modal.delModal>
    Delete
</b-btn>

That wasn't working in production builds and I couldn't figure out why. However, it works if I change it to the alternative syntax:

<b-btn variant="danger" class="float-right" v-b-modal="'delModal'">
    Delete
</b-btn>

Seems like another situation in which the HTML minification is building an incorrect AST and confusing Vue.

@nandlal-tjm
Copy link

I used packages name in v-for as below:
<tr v-for="package in packages>"
above breaks in the production. I use following instead
<tr v-for="share in shares>"
It works.
Is packages or package is the reserve keyword?

@aarongeorge
Copy link

There is still an issue with Parcel and the build command when using Vue. Here is a reproducible repo. I have detailed what I have already tried in the readme.md.

Any help on this would be great. I've even tried using the latest alpha 2.0.0-alpha.1.1 and that won't even allow the build to happen :(

@aarongeorge
Copy link

@devongovett, @mischnic any chance of getting word from someone on the team about this issue please?

I've read #2924 and even with closing the tags there is still an issue. The repo linked here details the problem when using the build command, where as, running serve results in the dist folder having working code (albeit unoptimised).

@github-actions
Copy link

This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 14 days if no further activity occurs.

@github-actions github-actions bot added the Stale Inactive issues label Mar 16, 2020
@jdlrobson
Copy link

Hello! I'm interested in championing the use of Parcel.js for Wikipedia for prototyping and development but I hit this bug recently which means that may not be viable. Keen to not see this issue go stale!

@github-actions github-actions bot removed the Stale Inactive issues label Mar 30, 2020
@github-actions
Copy link

This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 14 days if no further activity occurs.

@github-actions github-actions bot added the Stale Inactive issues label Sep 27, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests