Vue-cli: Add a watch mode

Created on 17 May 2018  ·  26Comments  ·  Source: vuejs/vue-cli

What problem does this feature solve?

Sometimes you don't want to serve html and other build files with integrated serve command.

Requirements

watch command option needs to take into account vue.config.js's outputDir or --dest. (I'm guessing this would work out of the box even). I think it's actually same as running webpack-cli with webpack --watch.

Would you be willing to merge a PR that adds this command / command option?

What does the proposed API look like?

vue-cli-service watch

or (preferably)

vue-cli-service build --watch
feature request cli-service build

Most helpful comment

Sure, we can take a PR for build --watch

All 26 comments

Sure, we can take a PR for build --watch

This new featured have a side effect: since the hash on filename changes every time, the dist folder starting to have all old versions from the same file

image

Besides that, is there a way to allow other flag or something to avoid vue-cli-service build --watch add hash in the end of filename? This will helps a lot use this build process when you need run Vue.js apps inside old apps, like my actual scenario: I'm building a Vue app runing inside a legacy app, so my Vue instance is only a div inside a whole old webapp.

@gtso86 during development you should use --mode development for faster rebuilds and the files will not have hashes. And we should probably default to dev mode when --watch is used... thoughts @zigomir ?

Yeah, this makes sense. I'm always using --watch with --mode development and can't think of a good use case when you'd want to have --watch within a production mode.

Edit: Changes are now in see #1430.

Is there any possibility to activate HMR mode with this command:
vue-cli-service build --watch --mode development.

Like: vue-cli-service build --watch --mode development --hmr

I would like to say that it's primary on not SPA environments.

If you are using --watch, the files are written to disk, so it's impossible to have HMR for that.

Yes, indeed, before I was using the webpack-hot-middleware with my existing server. But with the CLI I don't have this choice anymore.

I'll try to find an alternative solution or to make webpack-hot-middleware work with the CLI.

I met two problems with vue-cli-service build --watch --mode development.

  1. Lots of [hash].hot-update.json are being generated:

vue-cli

  1. The assets files are not in the sub directory:

image

dashboard.js is supposed to be put into public/js dir, but it's in public/ now.


Here's my vue.config.js:

module.exports = {
  outputDir: 'public',

  pages: {
    dashboard: {
      entry: 'client/src/dashboard/app.js',
      template: 'client/public/index.html',
      filename: '../resources/views/dashboard.blade.php',
      chunks: ['chunk-vendors', 'chunk-common', 'dashboard']
    }
  },

  chainWebpack (config) {
    config.resolve
      .alias
        .set('@', path.resolve(__dirname, 'client/src'))
        .end()
  },
}

With version 3.0.3

I can confirm what @meteorlxy experienced:

vue-cli-service build and vue-cli-service build --watch results in a different dist directory structure.

dashboard.js is supposed to be put into public/js dir, but it's in public/ now.

vue-cli-service build also generated a css folder, whereas it doesn't wit hthe --watch option.

@meteorlxy I found a workaround, but I'm not 100% sure what the issue is or why it works. Today is my first day using vue-cli or webpack for that matter!

This issue tipped me off: https://github.com/vuejs/vue-cli/issues/1617

Setting the NODE_ENV to production changes the output dir structure:

NODE_ENV=production vue-cli-service build --watch --mode development

If anyone would explain what's actually going on, that would be awesome :D

@anthonylebrun @meteorlxy

1.) running vue-cli-service build --watch runs in development mode by default: reference
2.) about "dashboard.js is supposed to be put into public/js dir, but it's in public/ now": not entirely correct. When you build in development mode @vue/cli won't extract css into separate file and thus sub-directories js and css aren't needed. If you wan't to use production like build, with split directories, you can use vue-cli-service build --watch --mode production. But that will make rebuilds slower due to minification and all.

@zigomir

Yeah, thanks.


  1. I know the point, and I just found that vue-cli-service build --watch with or without --mode development has different behaviors, which means --watch is not in "really" development mode?

  1. The css sub-dir is not necessray, but I think it's better to have the same directory structure (i.e. js sub-dir) in watch mode.

I notice that the output.filename is modified in prod.js to have js sub-dir, I think watch mode should have similar config:

https://github.com/vuejs/vue-cli/blob/ce335da9da54fbf14681c38f598ffc05082fe12c/packages/%40vue/cli-service/lib/config/prod.js#L6-L9


Maybe it's not good to discuss here, I'll try to open another issue for that. 😄

@anthonylebrun

LOL that's really an insteresting workaround 😄 I'll try it out. Thank you!

I have the same problem, integrating a vuejs app into an existing website.
For that I would just need the js/css and put a <div id="app"></div> into the existing site.

For that I actually am not using the dev server but the existing website local server to render the page.

But with the current cli setup I think it is a bit complicated to do so:
The build --watch task builds the JS assets into the root folder.
The build --watch --mode production uses the /js subfolder.

So I have to either change the vuejs JS inlucde folder everytime I want to deploy the app (from root to /js), or develop in production mode.

Wouldn´t it make more sense to put the js files into the same folder regardless if we are using production or development mode?

I also support using JS (and optionally CSS) subdirectories both in development and production mode. I am currently working on a project that uses Vue with CMS. The CMS requires including assets using its own including methods, hence it'd be convenient to fetch the assets from their dedicated directories as opposed to build separate configs for development and production modes.

EDIT: I was able to compile JS files into a JS directory even in development mode when I explicitly set the webpack output filename in vue.config.js. Here's the change:

chainWebpack: (config) => {
   config
      .output
         .filename('js/[name].js');
},

To create different output directories for prod vs development you can do something like this in your vue.config.js:

module.exports = {

  outputDir: process.env.NODE_ENV === 'production' ? 'dist/prd' : 'dist/dev',
  chainWebpack: config => {
      config.output
        .filename( process.env.NODE_ENV === 'production' ? 'js/[name].js' : 'js/[name].dev.js')
        .chunkFilename(`js/[name].js`)
  }  

}

same problem like @gtso86
Man, i just need "vue-cli-service build" in --watch mode with the same file and filename results!
Can it be that hard?
So file output und structure should be equal: --mode development == --mode production.
The hack was helping at moment: vue-cli-service build --watch --mode production

Lots of [hash].hot-update.json are being generated

I also ran into this problem in a situation where I am integrating vue into an existing project and can not use the dev server, but I still want to rebuild the package automatically whenever something changes.

After much searching, the best workaround I found was to limit and restrict these files to a dir that is in .gitignore.

module.exports = {
    configureWebpack: {
        output: {
            hotUpdateChunkFilename: '<dir>/<filename>',
            hotUpdateMainFilename: '<dir>/<filename>'
        }
    }
}

I would prefer a solution that cleans them up automatically whenever they are generated, if anyone knows of one.

I have the same problem.
When I build with --watch then it seems that vue-cli-service completely ignores the file vue.config.js

This is my vue.config.js

module.exports = {
    filenameHashing: false,
    publicPath: './webroot/dist/',
    outputDir: './webroot/dist/',
    chainWebpack: config => {
        config.plugins.delete('html')
        config.plugins.delete('preload')
        config.plugins.delete('prefetch')
    }
}

Guys for my cloud based environment I really need css files created, I do not need hot module replacement since I can see visual change only after files are uploaded to server(there is no option for localhost development)

So files are compiled and instantly uploaded to server, currently to make it work I have to use

vue-cli-service build --watch --mode production

This way I get the correct code with css files created, but I would like to also have possibility to do
vue-cli-service build --watch , in development mode but still have css files created,

I think it can speed up the build a bit.

I am using vue.config.js for my configuration

Can you please help?

I agree. When running without the built-in serve, it should be possible to have a watch in dev mode that creates the same directory structure, else Vue CLI is too opinionated and means dispensing with the CLI altogether and creating a regular Webpack config.

@MarkiyanPyts @mosfetish

Can you confirm that the vue.config.js is not used when building with --watch? Because for me it seems like that. If that is the case then maybe it's a bug in the view-cli.

It is using the config file.

The only thing that --watch changes, it this:

https://github.com/vuejs/vue-cli/blob/dev/packages/%40vue/cli-service/lib/commands/build/index.js#L143-L147

...which only sets weback's watch option to true.

It doesn'T skip or change anything else.

@LinusBorg

This is my vue.config.js

module.exports = {
    filenameHashing: false,
    publicPath: './webroot/dist/',
    outputDir: './webroot/dist/',
    chainWebpack: config => {
        config.plugins.delete('html')
        config.plugins.delete('preload')
        config.plugins.delete('prefetch')
    }
}

When I build with --watch then it feels like vue.config.js is completely ignored. The files are not written to /webroot/dist/. If I use --watch --mode production everything works fine and my vue.config.js seems to be used.

@MarkiyanPyts

Can you confirm that the vue.config.js is not used when building with --watch? Because for me it seems like that. If that is the case then maybe it's a bug in the view-cli.

vue.config.js is being used. This is mine:

module.exports = {
    outputDir: './public/'
}

And in both --watch and non --watch modes the files are written to ./public (the default is ./dist)

My package.json script commands are:

    "dev": "vue-cli-service build --watch --mode development",
    "build": "vue-cli-service build --mode production"

The problem is that in --watch mode OR in --mode development, a different directory structure is created, as already noted.

--watch with --mode production creates the full directory structure, as desired, but production mode is not wanted during development.

I am doing this

"dev": "vue-cli-service build --watch --mode development",

it only creates

  File                     Size                     Gzipped

  ../priv/static/app.js    18391.72 KiB             3172.99 KiB

  Images and other types of assets omitted.

 DONE  Build complete. Watching for changes...

why not any CSS files?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ghenry picture ghenry  ·  40Comments

yyx990803 picture yyx990803  ·  34Comments

yangzhuq picture yangzhuq  ·  33Comments

williamstar picture williamstar  ·  79Comments

brunoseco picture brunoseco  ·  35Comments