Skip to content
This repository has been archived by the owner on Feb 18, 2024. It is now read-only.

Feature request: command to output final webpack config #96

Closed
wmadden opened this issue Mar 5, 2017 · 22 comments
Closed

Feature request: command to output final webpack config #96

wmadden opened this issue Mar 5, 2017 · 22 comments
Milestone

Comments

@wmadden
Copy link

wmadden commented Mar 5, 2017

I recently started a project to try out Neutrino and while the initial setup was pretty easy, as soon as I wanted to make a change to the (eventual) webpack configuration I struggled to work out how to do it.

My first attempt to understand exactly what was ending up in webpack was to try to get ahold of the configuration object that webpack would receive. I was surprised to find there was no way to make neutrino output it, either using a --verbose flag or with a separate command. In the end I just added a custom preset which would print it out.

One of the biggest problems I observed using Grunt in production is that plugins you'd add would each modify the grunt configuration object, so that the actual configuration of tasks that'd be run would pass through many (often invisible) intermediate states before being used, making debugging impossible. I see a similarity here, in that after applying a couple of presets I had no way to know what webpack configuration was actually being used.

I think it'd be a good idea to make the underlying configuration more transparent to users - give them a way to see what it is before and after applying presets, and with different config properties switched on/off, and encourage them to use it in the documentation.

Moreover it'd give people a way to "eject" from Neutrino (borrowing the terminology from create-react-app), should they need to.

@paul-sachs
Copy link

paul-sachs commented Mar 5, 2017

I had some similar issues and found it helpful to output the config object. You can do this by adding adding a custom neutrino config like so:

\\ neutrino-custom.js
module.exports = (neutrino) => {
  console.log(neutrino.config.toConfig())
};

And adding that to the presets (as the last one)

It's not ideal, and a flag on neutrino is cleaner, but it may unblock you.

@tj
Copy link

tj commented Mar 5, 2017

dumping the config after each modification would be cool. I haven't used it enough yet to judge if it would be better, but doing config = middleware(config) with "vanilla" webpack might be a bit easier to grok than chained webpack, dunno, could be a lot worse, probably more error-prone

@eliperelman
Copy link
Member

As far as debugging a preset, I usually use getWebpackOptions which just maps to config.toConfig as @psachs21 mentiond:

module.exports = neutrino => {
  console.log(neutrino.getWebpackOptions());
};

I think having a --debug flag would be nice, and could probably be used to show an object diff between presets:

const alpha = ({ config }) => config.entry('index').add('src/index.js');
const beta = ({ config }) => config.entry('index').prepend('babel-polyfill');
const gamma = ({ config }) => config.entry('index').add('webpack/hot/dev-server');

// Neutrino v5.alpha .use()
neutrino.use(alpha);
neutrino.use(beta);
neutrino.use(gamma);

(Maybe a diff like this would be useful?)

# ––– neutrino.use
- {}
+ {
+   entry: {
+     index: [
+       "src/index.js"
+     ]
+   }
+ }
# ––– neutrino.use
  {
    entry: {
      index: [
+       "babel-polyfill",
        "src/index.js"
      ]
    }
  }
# ––– neutrino.use
  {
    entry: {
      index: [
        "babel-polyfill",
        "src/index.js",
+       "webpack/hot/dev-server
      ]
    }
  }

@SpencerCDixon
Copy link

+1 to having a debug/verbose mode which could just show snapshots of before and after applying middlewares. Even better I think would be showing diffs nicely formatted to reduce noise. What do you think @eliperelman of adding that to the use() func on the neutrino object? Check for a DEBUG=neturino:* env variable and if present show a nice diff

@SpencerCDixon
Copy link

hahahahah wow. Love it :-)

@eliperelman
Copy link
Member

@SpencerCDixon OMG wow

@SpencerCDixon
Copy link

SpencerCDixon commented Mar 6, 2017

So one thing to think about: if I'm trying to debug I probably don't want to see a dif between EVERY preset. But I might want to be able to see the changes between 2 or 3. If possible to use something a tad more advanced than just --debug I think that would be useful. But even just a --debug as a first step would be solid.

@eliperelman
Copy link
Member

@SpencerCDixon I think we can iterate on it later. Maybe --debug config.plugins so you can filter the diff to only plugin changes idk. I'll prototype something for v5.

@wmadden
Copy link
Author

wmadden commented Mar 6, 2017

@eliperelman I like the idea of a coloured diff, although that could easily be generated by existing diff tools as simply as:

neutrino build --debug --presets a,b > before.json
neutrino build --debug --presets a,b,c > after.json
favorite-diff-tool before.json after.json

At a minimum, let's output the result of getWebpackOptions() as you said above.

I think the most important change to make is cultural. Get people - especially newcomers - into the habit of printing the webpack config to see the effects of the presets and options they're enabling, so that neutrino isn't a magic black box (like Grunt, Yeoman and create-react-app) and they actually learn what they're working with.

@eliperelman
Copy link
Member

@wmadden you're totally right on the diffs, this should be handled externally. I had a local implementation working that I just wasn't happy with, so I'm glad you raised this.

Regarding echoing the JSON to stdout, I just need to make sure that there aren't any console.logs that will intermingle with the data, and this should be easy enough. I also think a more appropriate flag is needed, maybe --config-only.

@eliperelman
Copy link
Member

I just realized that we can't spit out JSON, since Webpack configs are code, not necessarily all data. Gonna need to think this through a little more.

@eliperelman
Copy link
Member

In order for this to be solved, we have to avoid conflating two things which we are currently doing:

  1. Outputting a Webpack configuration
  2. Viewing a Webpack configuration

They may seem the same, but the problem lies in that you cannot just echo a Webpack configuration and have it work, since it relies on the scope and context of its creation. So to require a Webpack configuration, you can use the API (proposed v5 syntax):

const Neutrino = require('neutrino');
const api = new Neutrino();

api.use(alpha);
api.use(beta);
api.use(gamma);

// or alternatively by pulling from package.json
require('./package.json').neutrino.presets.map(preset => api.use(preset));

module.exports = api.getWebpackOptions();

Getting a string of the Webpack options is possible from the CLI, but then is not consumable by Webpack.

@wmadden
Copy link
Author

wmadden commented Mar 6, 2017

Fair enough. I think it'd be worthwhile giving people a way to view a representation of the webpack options, even if it's not usable as an input to webpack.

@eliperelman
Copy link
Member

@wmadden agreed, I'm working on it as we speak. Probably under --inspect.

@eliperelman eliperelman added this to the v5 milestone Mar 6, 2017
@eliperelman
Copy link
Member

Resolved with #86.

@timkelty
Copy link
Contributor

Sorry to resurrect an oldie…

In debugging / sanity checks, I've too have found myself wanting a dump of the working webpack config - mostly to determine if I'm dealing with a webpack issue or a neutrino one.

but the problem lies in that you cannot just echo a Webpack configuration and have it work, since it relies on the scope and context of its creation.

@eliperelman I'm sure this is correct, but can you elaborate, or provide an example? Just trying to wrap my head around it. Are you saying an working config output is impossible to generate?

So, I started with something like

cat webpack.config.js | echo "module.exports = " &> webpack.config.js && neutrino build --inspect >> webpack.config.js

…and quickly realized bits like this were going to be a problem:

        babel: {
          transform: function () { [native code] }
        },

Ultimately I was looking for something like neutrino build --dump webpack.config.js

@timkelty timkelty reopened this Dec 13, 2017
@cazacugmihai
Copy link

I did something like this:

var cfg = {
    ...
};
console.log('-----------');
console.log(JSON.stringify(cfg, null, 4));
console.log('-----------');

module.exports = cfg;

@eliperelman
Copy link
Member

I still think this in tricky territory that we just don't have the resources to support. In order to generate a working webpack.config.js from ejection, that means needing to dump into package.json, and get a bunch of references right, as well a string-building a config.

It's entirely possible to dump the config currently, either using --inspect, or adding a middleware at the end with neutrino => console.log(neutrino.config.toConfig()), it's just not usable from a webpack config file.

@edmorley
Copy link
Member

I strongly feel --inspect is a feature we need to improve. I agree an entirely working eject function is likely very hard and not worth the effort - but some tweaks to dump the correct values for plugins (see #328) would go a long way. What is dumped now is not the actual plugin config.

However that's a dupe of #328, which really needs changes in webpack-chain first (which is neutrinojs/webpack-chain#25).

I experimented locally with a few approaches to try and improve the situation, but they were all kind of hacky and I reached my yak shaving allowance for the month before I had time to come up with something better.

@eliperelman
Copy link
Member

Agreed.

edmorley added a commit that referenced this issue Jun 5, 2018
This take advantage of the new webpack-chain `toString()` added in
neutrinojs/webpack-chain#53.

The output from `neutrino --inspect` now lists the correct plugin
declarations and arguments, annotates plugins/loaders with hints
about how to reference them in a custom Neutrino config, and supports
using `__expression` to override the stringified output when needed.

The usage of `deep-sort-object` has been removed since it breaks the
new `toString()` comment annotations, and really if sorted output is
considered important, it should be handled by webpack-chain itself.

Fixes #328.
Refs #96.
@edmorley
Copy link
Member

v8.3.0 has just been released, which backports the upcoming Neutrino 9's improved --inspect feature, as --inspect-new.

@mindplay-dk
Copy link

The command didn't help me for other configurations besides webpack, namely the configuration-builder for jest.

To others looking for an general way to eject from any webpack-chain configuration, here's what I came up with:

const neutrino = require("neutrino")
const Config = require('webpack-chain');

console.log(Config.toString(neutrino().webpack(), { verbose: true }));
console.log(Config.toString(neutrino().jest(), { verbose: true }));
// etc.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Development

No branches or pull requests

9 participants