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

[Experimental] Presets support #4027

Merged
merged 33 commits into from
Sep 6, 2018
Merged

[Experimental] Presets support #4027

merged 33 commits into from
Sep 6, 2018

Conversation

igor-dv
Copy link
Member

@igor-dv igor-dv commented Aug 16, 2018

Issue

  1. The purpose of presets is to be able to easily integrate to the different points of SB configuration.
    Users will be able to combine different presets in their app and create their own.
    All official presets will be located in the presets monorepo.
  2. Every supported app will contain framework-presets, that will be passed down to the core (e.g. framework-preset-vue)
  3. Core will have core-prests (e.g. core-preset-dev)
  4. In the end, presets will be chained and executed.

API

Each preset may expose some of these methods (We can think of more stuff):

module.exports = {
  babel: (config, options), // extend babel config
  webpack: (config, options), // extend webpack config
  preview: (config, options), // extend preview entry-point
  manager: (config, options), // extend manager entry-point
}

Considering presets.js (or presets.ts) in user's code:

module.exports = [
  '@storybook/preset-typescript',
  {
    name: '@storybook/preset-scss',
    options: {
      cssLoaderOptions: {
        modules: true,
        localIdentName: '[name]__[local]--[hash:base64:5]'
      }
    }
  }
];

Note

  1. presets.js will be a part of the future single configuration file. For now, when loading a cusomt presets.js file, there will be a warning.
  2. We can think of our supported apps as a combination of presets as well Done

@igor-dv
Copy link
Member Author

igor-dv commented Aug 16, 2018

@pksunkara, having in mind your work for vue-cli plugin, can you see what is missing?

@codecov
Copy link

codecov bot commented Aug 17, 2018

Codecov Report

Merging #4027 into master will increase coverage by 48.04%.
The diff coverage is n/a.

Impacted file tree graph

@@             Coverage Diff             @@
##           master    #4027       +/-   ##
===========================================
+ Coverage   40.59%   88.63%   +48.04%     
===========================================
  Files         483        6      -477     
  Lines        5747       44     -5703     
  Branches      770        2      -768     
===========================================
- Hits         2333       39     -2294     
+ Misses       3042        4     -3038     
+ Partials      372        1      -371
Impacted Files Coverage Δ
...toryshots-core/src/frameworks/svelte/renderTree.js
addons/backgrounds/mithril.js
app/riot/src/client/preview/render-riot.js
addons/knobs/src/components/types/Select.js
...yshots/storyshots-core/src/frameworks/rn/loader.js
addons/storysource/src/loader/parsers/index.js
lib/ui/src/modules/ui/configs/handle_routing.js
...ents/stories_panel/stories_tree/tree_decorators.js
...-native/src/preview/components/OnDeviceUI/style.js
app/react-native/src/bin/storybook-build.js
... and 436 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update a2a2a91...e6972e7. Read the comment docs.

}

function getPresets(configDir) {
const presets = serverRequire(path.resolve(configDir, 'presets'));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should move to just a single config file called storybook.config.js which is built out of presets.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I totally agree, and as I wrote in the Misc ☝️ , it should be a part of the single config file.
However, I don't know what will be implemented/published first. Also, I don't want to create PRs with hundreds of changes in them =)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added a warning when using custom presets. It will be only for the presets testing purpose.


return {
extendBabel: config => applyPresets(loadedPresets, config, 'extendBabel'),
extendWebpack: config => applyPresets(loadedPresets, config, 'extendWebpack'),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have you seen https://github.com/mozilla-neutrino/webpack-chain? It would be useful in our architecture.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will check this.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This package looks interesting. Anyway, we can integrate it later. If we will go with it, it will be a main part of the core, so I would like to here other team members opinion as well =)

const loadedPresets = loadPresets(presets);

return {
extendBabel: config => applyPresets(loadedPresets, config, 'extendBabel'),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want to do this? Can't we somehow merge extendWebpack and extendBabel? The webpack-chain I mentioned below should be useful.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's useful to separate different entry points of integration. extendPreview and extendManager technically also could be removed 🤷‍♂️

lib/core/src/server/presets.js Outdated Show resolved Hide resolved

const baseConfig = getBaseConfig({ ...options, babelOptions, presets });
const initialConfig = wrapInitialConfig(baseConfig, configDir);
const config = presets.extendWebpack(initialConfig);
const defaultConfig = wrapDefaultConfig(createDefaultWebpackConfig(config));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should remove these wrappers and rely on presets.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the long run - yes (Also wrote about it in Misc). But again, I would like to start using presets, without a huge refactoring in one PR.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What I think we should do is instead of refactoring, we can support the new method of config without changing anything from the first. And once we are happy with the presets, we can remove the old one.

@ndelangen ndelangen changed the title [WIP] Presets support Presets support Sep 3, 2018
@@ -0,0 +1,72 @@
/* eslint-disable no-param-reassign,no-shadow */
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've opened an issue - neutrinojs/babel-merge#14
In any case, I will move it out of here later.

@pksunkara
Copy link
Member

Looks good! I just have 2 questions.

  1. I am not sure about this because I don't know much about angular. But the only angular apps we support is anglular-cli based?
  2. I thought custom presets.js was supposed to override everything rather than just getting appended to the list of presets.

@ndelangen
Copy link
Member

@pksunkara Right now custom presets are kind of a unsupported feature, so I'm find with this for now.

In the future I think there should just be a complete list of add presets in the (to be created) unified config file.

@igor-dv
Copy link
Member Author

igor-dv commented Sep 6, 2018

I am not sure about this because I don't know much about angular. But the only angular apps we support is anglular-cli based?

That is what all angular people use =) But, IMO you can bootstrap angular app without any starter, and use SB as well, but there will be more manual work to do

@pksunkara
Copy link
Member

This PR is good to be merged. I am just trying to see why tests are failing.

@pksunkara
Copy link
Member

Nevermind, it's been fixed in master.

@pksunkara pksunkara merged commit b2b7359 into master Sep 6, 2018
@pksunkara pksunkara deleted the core/presets branch September 6, 2018 19:58
@igor-dv
Copy link
Member Author

igor-dv commented Sep 6, 2018

Yey 🎆 Work of my life 😭

let babelCore = null;

try {
babelCore = require('@babel/core');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can accidentally resolve to something only accessible from node_modules/@storybook/core/node_modules not from user's app.

We need to add babel-core peerDependency and ask users to install bridge if we need to use Babel directly

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That what I've tried to prevent, but I assume better to have a peer on a bridge. I will do this after the PR to babel-merge

@Hypnosphi Hypnosphi changed the title Presets support [Experimental] Presets support Sep 8, 2018
@Hypnosphi
Copy link
Member

@igor-dv Why do we need to merge Babel configs on our side?

@igor-dv
Copy link
Member Author

igor-dv commented Sep 9, 2018

I wanted to simplify the API for presets, so apps will also use it. And wrapDefaultBabel Config was a pain in the ass for the API. So I thought if we will merge the defaults, it will remove the need of this wrapper.

@Hypnosphi
Copy link
Member

Hypnosphi commented Sep 10, 2018

was a pain in the ass

Can you please provide some examples of this pain? I'm just afraid that maintaining a merger can be a greater one (see all the issues with our webpack merger)

@igor-dv
Copy link
Member Author

igor-dv commented Sep 10, 2018

The pain was to consolidate the API between framework, core and custom presets. Take a look in #4107 - where I tried to kill the wrapper. babel-merge package actually does the merge well. But maybe you have a better idea ?

@Hypnosphi
Copy link
Member

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

Successfully merging this pull request may close these issues.

4 participants