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

Test and dev builds omit css and image files #2625

Closed
jost-s opened this issue Sep 27, 2018 · 6 comments
Closed

Test and dev builds omit css and image files #2625

jost-s opened this issue Sep 27, 2018 · 6 comments

Comments

@jost-s
Copy link
Contributor

jost-s commented Sep 27, 2018

Version

3.0.4

Reproduction link

https://github.com/jost-s/vue-cli3-demo

Node and OS info

Node 8.10.0 / npm 6.4.1 / Windows 8.1

Steps to reproduce

  • Clone repository
  • Run .\node_modules\.bin\vue-cli-service build --mode test
  • Check ./dist folder
  • Set NODE_ENV to "test"
  • Run npm run build
  • Check ./dist folder

What is expected?

Create a build including all files

What is actually happening?

Create a build omitting additional images and css files.


At first I ran in to this issue because I deployed an app to a test system where the NODE_ENV was set to "test". Building resulted in an incomplete dist folder without images and css files, even though the output said "Building for production...".
After trying different combinations of environment variables and webpack modes, it turns out the problem is two-fold:

  1. When building in "test" mode, the images and css files are omitted.
  2. When setting NODE_ENV = test, it looks like production mode is used, yet css and image assets are omitted from the build.

This issue is related to #2327

@LinusBorg
Copy link
Member

LinusBorg commented Sep 27, 2018

I think this comes down to the problem of your documentation not explaining the different implacts of NODE_ENV & its default modes well enough, because what you are seeing is expected behaviour and works the way it does for a reason.

So I'll try and explain what we want to get across, and maybe you can give feedback how we can word or strcuture this part of the documentation.

Have you read the documentation about environment variables and modes? this one:

https://cli.vuejs.org/guide/mode-and-env.html#environment-variables-and-modes

It has an explicit note about NODE_ENV:

NODE_ENV

If you have a default NODE_ENV in your environment, you should either remove it or explicitly set NODE_ENV when running vue-cli-service commands.

So the immediate solution to your problem is to call your build process with an explicitly set NODE_ENV=production

In the next section about modes it explains in the first paragraph, that NODE_ENV=test is set by the test mode, which is used by vue-cli-service test:unit.

In other words: NODE_ENV=test creates a webpack config that is intended to be used for unit tests, and is optimized for that purpose. Which is why it doesn't process assets in the way you expect: In unit tests, that would be useless thing to do. So this is intended behaviour for NODE_ENV=test

Similarly, NODE_ENV=development creates a webpack confuration intended to be used during development, i.e. it enables HMR, doesn't hash assets, doesn't create vendor bundles and so forth, in order to create a fast re-build experience when running a dev server (which is essentially why #2327 is, similarly, expected behaviour).

When you are running vue-cli-service build, your NODE_ENV should always be set to production, because that's what you are doing: you are creating a production build. Wether this is intended to be served in a "staging" or "QA" environment or whatever you might call it doesn't matter. It's intended to behave just like your actual production app, except for maybe some ENV Vara that change API URLs to non-production values (which you would do via .env files as explained in the linked documentation).

Does that make it clearer? And if it does, what would you like to read about this in the docs, and where would you expect to find it? We don't always find it easy to get docs for things like this right the first time, as it's hard for someone intimately familiar with a tool to think about things from a new user's perspective on it.

@jost-s
Copy link
Contributor Author

jost-s commented Sep 27, 2018

@LinusBorg
Thank you very much for your detailed answer. I understand the intention and behavior now. I had read the docs but didn't quite get it. Now reading them again it's pretty much all there. I will make a suggestion on how to extend it for clarification.

The solution you provide for the build works fine, thanks. I'm using a pipeline to push to the different environments, and I remember I had thought of that solution reading the yellow note on NODE_ENV in the docs, but wasn't happy with it because it doesn't work on Windows and Linux alike. Anyway, it's good enough for now.

What I'm generally wondering is why does NODE_ENV have to match the webpack production mode? The env var will set different URLs or texts or whatever for different environments, whereas the webpack production mode affects the build itself, like which files to include, source maps, pruning and the whole lot. This seems to be not necessarily related to me.

Like in my case, I could want to deploy an app to a dev system or a test system, where the env vars are set accordingly, but the build should be a production build. Would it be awkward to keep NODE_ENV and webpack mode independent?

[edit] And I don't know if that ties in with that, but if my NODE_ENV is set to "test" and I call vue-cli-service build --mode production, it says "Building for production" but builds for test. That is confusing to me. [/edit]

@LinusBorg
Copy link
Member

LinusBorg commented Sep 28, 2018

What I'm generally wondering is why does NODE_ENV have to match the webpack production mode?

I think this is another misunderstanding. vue-cli's --mode is not webpack's --mode, it's our own thing.

Webpack's --mode does only a few things (one of them setting NODE_ENV to development or production, by the way).

Our --mode does quite a few more things.

  • Load environment variables from .env, .env.local, .env.${mode} and .env.${mode}.local
  • these env files can set NODE_ENV
  • if they don't, the mode sets NODE_ENV to the matching value
  • NODE_ENV is then used to
    • create the right webpack config for the set value (see here and here, for example)
    • determine what mode the dev-server is running in (see here)
    • and some other things

So the point is:

  • webpack's --mode isn't really important here - it's a nice shortcut when you use webpack bare-bones, but not enough for our purposes
  • NODE_ENV is central in the process of determining what primary mode your app is runnning in: development, production or test - and consequently, what kind of webpack config we create etc.
  • our --mode sets this NODE_ENV and loads other env variables for the mode that is being set. This allows for e.g. staging environments like explained here

And I don't know if that ties in with that, but if my NODE_ENV is set to "test" and I call vue-cli-service build --mode production, it says "Building for production" but builds for test. That is confusing to me.

That's because we never overwrite any environment variable that was being passed in from the system running vue-cli-service.

So --mode is still production, but the NODE_ENV can't be set to production because the system has it predefined.

I'm aware that this is maybe not the most straightforward way to handle this, but it's the best way we found so far that allows for the flexibility we need to support various ways to define env vars and different modes.

@jost-s
Copy link
Contributor Author

jost-s commented Sep 29, 2018

Great explanation again, thanks for that. Now I have it, I believe, and enough material to improve the docs :-)

Two more related questions:

So --mode is still production, but the NODE_ENV can't be set to production because the system has it predefined.

That makes sense, but the resulting build should be a production build, no?! If NODE_ENV is "test" and I run vue-cli-service build --mode production, it should be the same as running NODE_ENV=production vue-cli-service build. Currently it's a test build though without assets.

And secondly, when I have an actual production build with all assets included, there's nevertheless an output saying "Images and other types of assets omitted.". Why is that?

@LinusBorg
Copy link
Member

LinusBorg commented Sep 29, 2018

That makes sense, but the resulting build should be a production build, no?!

No. As I explained, the NODE_ENV value is what actually determines the kind of webpack config you get. And since we do not overwrite environment variables from the system, you run a build with a test config if your system has defined NODE_ENV=test, which means: images etc are not processed.

As to the second question, I believe that's simply referring to the fact that images and such assets are omitted from the list of created assets that's printrd to the console.

@jost-s
Copy link
Contributor Author

jost-s commented Sep 29, 2018

Okay, it's all clarified now, thanks a lot for your help!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants