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

Improve usefulness of 'vue inspect' command /w chainWebpack #881

Closed
LinusBorg opened this issue Feb 25, 2018 · 12 comments
Closed

Improve usefulness of 'vue inspect' command /w chainWebpack #881

LinusBorg opened this issue Feb 25, 2018 · 12 comments

Comments

@LinusBorg
Copy link
Member

LinusBorg commented Feb 25, 2018

What problem does this feature solve?

Currently, the vue inspect command outputs a stringified version of the webpack config, and it's is very useful to get an overview of the final config resulting from all the plugins you are using.

If you want to use configureWebpack() in vue.config.js to alter this config, this representation makes it easy to find the loader rule that you want to reach and change, for example.

But the chainWebpack config gives you a webpack-chain config, where all (most) pieces of the config have a name to access them by.

For example, if I wanted to change some options of the optimize-css-assets-webpack-plugin, I can to do this:

chainWebpack: config => {
  config
    .plugin('optimize-css')
      .tap(options => {
        options.setMyNewOption = true
        return options
      })
}

I like webpack-chain and think it' a great way to manipulate webpack's config, but for the above example, I must somehow be aware that the plugin's name in webpack-chain is 'optimize-css'.

So far, we haven't documented this anywhere, and the output of vue inspect doesn't help in that regard, either:

/* OptimizeCssAssetsPlugin */ {
      options: {
        safe: true,
        assetNameRegExp: /\.css$/g,
        cssProcessor: function () { /* omitted long function */ },
        cssProcessorOptions: {},
        canPrint: true
      },

So to learn that fact, I currently have to dig into the source of @vue/cli-service here, search through those files and then find this line:

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

The other approach would be to do something like this as a sort of debugging:

chainWebpack(config => {
  console.log(Object.keys(config.plugins,entries))
})

...which would give me an array of all plugin names (I may have gotten the exact webpack.chain syntax wrong, but that should be possible generally), and I have to guess which one the right one is.

I don't think that documenting it is enough, since documentation quickly can get out of sync, and there will also be numerous community-maintained plugins that don't necessarily adhere to the documentation standards we can provide for the official plugins.

What does the proposed API look like?

The output of vue inspect should also include the name for each piece of config that has one.

      /* OptimizeCssAssetsPlugin (webpack-chain name: 'optimize-css' ) */ {
      options: {
        safe: true,
        assetNameRegExp: /\.css$/g,
        cssProcessor: function () { /* omitted long function */ },
        cssProcessorOptions: {},
        canPrint: true
      },

(note the addition to the comment in the first line)

This surely isn't possible with the current implementation where we essentially pipe the already resolved webpack config through javascript -stringify (and replace plugin instances with the above json representation along the way).

Rather, we would have to somehow walk through the webpack-chain config and build the json representation from that.

I have no idea if this is possible, and won't have time to play around with the idea in the next few weeks, but maybe someone else has a great idea about how to tackle this.

It would greatly improve usability of the chainWebpack API.

@eliperelman
Copy link

Note: we are probably going to implement something like this inside webpack-chain so it's also usable in Neutrino: neutrinojs/neutrino#328

@mediaessenz
Copy link

mediaessenz commented Mar 31, 2018

Is there an example how to change / override a definition like this:

webpackConfig
        .plugin('extract-css')
          .use(ExtractTextPlugin, [Object.assign({
            filename: `css/[name].[contenthash:8].css`,
            allChunks: true
          }, userO

which is defined in @vue/cli-service/lib/config/css.js, using chainWebpack or configureWebpack inside vue.config.js?
I want to change the filename to Css/[name].css

@eliperelman
Copy link

eliperelman commented Mar 31, 2018

@mediaessenz you can use .tap to change the args of a plugin:

webpackConfig
  .plugin('extract-css')
  .tap(args => newArgs);

So if you wanted to change the options, which is the first arg:

webpackConfig
  .plugin('extract-css')
  .tap(([options, ...args]) => [newOptions, ...args]);

@mediaessenz
Copy link

@eliperelman thanks for your answer, but I stil don't know how to do this inside the vue.config.js

@mediaessenz
Copy link

@eliperelman Thanks again, I got it now!
This:

chainWebpack: config => {
        config
            .plugin('extract-css')
            .tap(([options, ...args]) => [{filename: 'Css/[name].css'}, ...args])
    },

inside my vue.config.js do the job!

@eliperelman
Copy link

LGTM, although if you want to make sure you pick up the other options, you should merge/assign:

chainWebpack: config => {
  config
    .plugin('extract-css')
    .tap(([options, ...args]) => [
      Object.assign({}, options, { filename: 'Css/[name].css' }),
      ...args
    ]);
},

@mediaessenz
Copy link

mediaessenz commented Mar 31, 2018

I thank you so much, you really save my eastern!
A final question I still have now is, how can I add this config modification only in production mode?
Currently it's also assigned under development, which gives me a TypeError: Plugin is not a constructor if I enter vue inspect. With vue inspect --mode production everything is fine.

@eliperelman
Copy link

If vue-cli works anything like Neutrino, then you can do this with an environment variable:

chainWebpack: config => {
  config
    .plugin('extract-css')
    .when(process.env.NODE_ENV === 'production', plugin => {
      plugin.tap(([options, ...args]) => [
        Object.assign({}, options, { filename: 'Css/[name].css' }),
        ...args
      ]);
    });
},

@mediaessenz
Copy link

mediaessenz commented Mar 31, 2018

If I try your snippet, I still get the changed filename, but when I try to inspect the development settings or try to start the serve/development mode with npm run serve I still get the same TypeError descriped above.
After some tests, I found the solution:

chainWebpack: config => {
    config
        .when(process.env.NODE_ENV === 'production', plugin => {
            plugin.plugin('extract-css').tap(([options, ...args]) => [
                Object.assign({}, options, { filename: 'Css/[name].css' }),
                ...args
            ])
        })
},

@LinusBorg
Copy link
Member Author

LinusBorg commented Mar 31, 2018

@eliperelman I apprechiate your willingness to help here, but that's is not what this issue is meant for, and it's making it harder to track its progress if individual discussions are taking place in the comments.

@mediaessenz Please use forum.vuejs.org or chat.vuejs.org to ask for help, we are active there as well.

@mediaessenz
Copy link

mediaessenz commented Mar 31, 2018

@LinusBorg Sorry, but I already tried to use the chat.vuejs.org, and did not get any answers :-(
I posted my problems under "need help", "webpack" and "german".
And discord is IMO not the best choice for a chat with mostly coding topics. Slack would be way better.

@LinusBorg
Copy link
Member Author

LinusBorg commented Mar 31, 2018

I understand that it can be frustrating when you need an answer and dont get it right away. But you will get one sooner or later.

Highjacking Issues on github about hardly related topics is not the way to get your answers, please respect that.

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

4 participants