stephencookdev / speed-measure-webpack-plugin

⏱ See how fast (or not) your plugins and loaders are, so you can optimise your builds
MIT License
2.42k stars 79 forks source link

How to use with Neutrino #19

Closed mpolichette closed 6 years ago

mpolichette commented 6 years ago

It looks like this plugin goes in an wraps other plugins by processing the entire webpack config.

I'm looking at using this in neutrino, which uses webpack-chain to perform adjustments on the webpack config. I'm wondering if there are any examples of using this with that set up already... otherwise it looks like I might be putting my one together.

mpolichette commented 6 years ago

This would probably be easier if we could perform wrapping manually also... basically, make this command available from outside the plugin:

https://github.com/stephencookdev/speed-measure-webpack-plugin/blob/master/index.js#L40

const SpeedMeasurePlugin = require("speed-measure-webpack-plugin");
 const smp = new SpeedMeasurePlugin();

... later ...
smp.wrapPlugin(plugin)
...

Thoughts?

stephencookdev commented 6 years ago

No, unfortunately there isn't an "examples" folder or anything atm And I've not looked at integrating with Neutrino at all :( I'll have a poke around webpack-chain and see what looks like the best way to do this. But yeah, if you're having a look at this too, let me know what you find

As for exposing stuff like WrappedPlugin, I'd like to avoid it if possible. SMP does other stuff too, like injecting a custom loader in order to get loader timings. Plus anything else SMP might do would be lost, if people were using parts of it directly. But yeah, doing so would definitely work, if all else fails!

mpolichette commented 6 years ago

:) How about this for an example... just finished it... it works, but it is super hacky...

neutrino.use(neutrino => {
    const SpeedMeasurePlugin = require("speed-measure-webpack-plugin");
    const { WrappedPlugin } = require("speed-measure-webpack-plugin/WrappedPlugin")
    const smp = new SpeedMeasurePlugin();

    console.log('Wrapping plugins:')
    const plugins = neutrino.config.plugins.entries()
    const pluginNames = Object.keys(plugins)
    pluginNames.forEach(name => {
      console.log('Wrapping:', name)
      neutrino.config.plugin(name)
        .init((Plugin, args) => new WrappedPlugin(new Plugin(...args), name, smp))
    })
    // Add the smp plugin
    neutrino.config
      .plugin('SpeedMeasurePlugin')
      .use(SpeedMeasurePlugin)
      .init(() => smp)
  })
stephencookdev commented 6 years ago

Nice

So looking into Neutrino a bit, this also appears to be a (although still fairly hacky) less verbose way to get a similar result

const SpeedMeasurePlugin = require("speed-measure-webpack-plugin");
const smp = new SpeedMeasurePlugin();

module.exports = {
  use: [
    // all other presets etc. here
    "...",
    // perform this smp part last!
    neutrino => {
      const conf = smp.wrap(neutrino.config.toConfig());
      neutrino.config = { toConfig: () => conf };
    }
  ]
}

In theory this is something we could add in the future, so we have something like

module.exports = smp.neutrino.wrap({
  use: [ "..." ]
});

and have it transform the config into my above code sample. This would also let us properly wrap the neutrino.config override hack properly in a Proxy. But I'd definitely want to have a think about how that would work a bit, before dedicating anything

mpolichette commented 6 years ago

Hmm... so it looks your your approach is trying to wrap the config on the way out. Which is cool and probably has the least adjustments to working code, but probably couldn't be written as cleanly as a neutrino preset. I think it would have to be written in a per-project integration...

The neutrino way to do things is by using presets. It also fully expects you to have your presets edit existing webpack config.

Does any of that make sense? :P

I'm still a bit new to neutrino myself, but I think the webpack-chain stuff fits pretty cleanly with what this project is trying to do, which is to dive in and edit webpack config. I think it would be cool to get a preset out that you could just say to include .use('speed-measure)` as your last preset.

stephencookdev commented 6 years ago

There shouldn't be any issue with it being a preset, it would just need to be the last preset.

I'll have a look at how to get it working, but yeah - I don't think there should be any issue in getting to the .use("speed-measure-webpack-plugin") or whatever as a target API :)

stephencookdev commented 6 years ago

Okay, I've added explicit support for this now with v1.1.0 (36487a4c7c2c15472e1c43649a4d117bf603dbcd)

I've also added an examples folder, one example being for a .neutrinorc.js file

But yeah, the syntax is:

module.exports = {
  use: [
    // whatever presets you have here
    "@neutrinojs/airbnb",
    "@neutrinojs/jest",

    // Make sure this is last! This strongly depends on being placed last
    "speed-measure-webpack-plugin/neutrino"
  ]
}

will close this issue, but please re-open / ping me if you're having any issues at all with this :slightly_smiling_face:

mpolichette commented 6 years ago

Dude you rock! Thanks a million!