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

New major version #35

Closed
sokra opened this issue Aug 15, 2017 · 9 comments · Fixed by #37
Closed

New major version #35

sokra opened this issue Aug 15, 2017 · 9 comments · Fixed by #37

Comments

@sokra
Copy link
Member

sokra commented Aug 15, 2017

What about a new major version with more performance and more features?

  • Never use arguments, compile fixed arguments function.
  • Create a function per hooks which makes it monomorphic.
  • Maybe something magic like new Function(`function x(${args}) ...`)
  • Different apply function depending on number of registered plugins
    • no plugins: noop apply for max performance
    • special version to 1 plugin: optimized
    • general version for more plugin
  • You need to register hooks before using them. You need to specify number of arguments and kind (sync/async/parallel/waterfall).
  • Instead of compiler.plugin("before-run", ...) compiler.hooks.beforeRun(...) to allow have typings for these hooks.
  • Each plugin can have a name compiler.hooks.beforeRun("HotModuleReplacementPlugin", () => ...)
  • Insert plugins at specify locations instead of always to the end. hooks.beforeRun({ name: ..., before: "HotModuleReplacementPlugin" }, () => ...)
  • Maybe a middleware api, if this doesn't affect performance: hooks.beforeRun.intercept(...)
    • Would be great of the progress display and profiling.
  • The plugin(...) method can be provided for backward compatibility for plugins.
    • We may generate plugin name from stack trace (depending on performance cost for this)
  • The old applyPluginsXXX methods can also be offered for backward compatibility, but trigger a deprecation.
  • Using a unknown hook name in the plugin or applyPluginsXXX automatically register a compat hook which handle them.
  • The compatibility methods convert dash-case to camelCase.
  • This would be a big breaking change, but I guess acceptable with the compatibility layer.
@TheLarkInn
Copy link
Member

@samccone do you think this would help accomplish what we are wanting?

@robpalme
Copy link

I'd be interested in hearing the architectural goals you're trying to achieve here. The list above is mostly actions and is missing rationale. Hopefully contorting the interface to appease esbench is not the primary driver.

@samccone
Copy link
Member

+1 to @robpalme's question.

My only motivation with changes to tappable is as follows

  1. remove confusing .apply.apply api
  2. make it possible to wrap every hook with timing extractors

@sokra
Copy link
Member Author

sokra commented Aug 24, 2017

remove confusing .apply.apply api

This will be removed. Eventually the Tapable base class will be removed, but it will stay for now because of legacy methods.

make it possible to wrap every hook with timing extractors

There will be a inspect methods will allows you to decorate each hook call for performance. A name for the plugin is now a required parameter when registering a plugin. You'll receive this name in the inspect handler. You can also enumerate all hooks for a class in the new version with Object.keys(compiler.hooks). Keep in mind that inspecting will affect performance a bit.

@sokra
Copy link
Member Author

sokra commented Aug 24, 2017

I'd be interested in hearing the architectural goals you're trying to achieve here. The list above is mostly actions and is missing rationale. Hopefully contorting the interface to appease esbench is not the primary driver.

  • Performance:
  • Easier to use.
  • Typescript/Flow friendly.
  • Remove some hacks in webpack which are needed because of missing features in tapable.
  • Promise support (for plugin authors and webpack)

@TheLarkInn
Copy link
Member

@samccone @robpalme
We also just published an article on medium that talks about this more in depth if you need more context.

https://medium.com/webpack/the-new-plugin-system-week-22-23-c24e3b22e95

@samccone
Copy link
Member

+1 to the blog post, it hits every API pain point that I ran into and provides a solid approach for the future. I am excited for the new version!

One question that I do have though is what will be the story for people to upgrade? If a plugin is old.. what will be the behavior? Will there be a compat layer to make them work with the new version or will developers have to do the upgrade to see these new API wins?

Thanks

@sokra
Copy link
Member Author

sokra commented Sep 19, 2017

There will be a compat layer. Old plugins should continue to work. Old tapable instances are breaking and need to be changed.

Some features are not available in the compat layer, like naming for plugins.

@TheLarkInn
Copy link
Member

@sokra I think this change will open open a larger contribution opportunity once we make this major change for webpack v4+.

Do you think you could outline a few example plugins and how you might convert old to new api so that I can write a few instructional guide examples for contributors to jump in and help with the refactor?

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

Successfully merging a pull request may close this issue.

4 participants