CSF story order depends on webpack and breaks with vanilla es module imports
See original GitHub issueDescribe the bug
The order of stories within the code of an index.stories.js
file (in CSF format) determines the order of the storybook menu.
Consider the following example
// orderedNamedExports.js
export const b = 'BB';
export const a = 'AA';
export const c = 'CC';
// start.js
import('./orderedNamedExports.js').then(module => {
console.log(Object.keys(module));
});
When loading this file by going through webpack it will result in
// (3) ["b", "a", "c"]
However, when using a browser native es module import the modules will be sorted.
// (3) ["a", "b", "c"]
It is specified in the es module spec https://tc39.es/ecma262/#sec-modulenamespacecreate
- Let sortedExports be a new List containing the same values as the list exports where the values are ordered as if an Array of the same values had been sorted using Array.prototype.sort using undefined as comparefn.
There are also part of the official platform tests https://github.com/tc39/test262/blob/master/test/language/module-code/namespace/internals/own-property-keys-sort.js
it sort of all started with this tweet so if you are interested there are more details https://twitter.com/daKmoR/status/1204877164233015297?s=20
As this order determines the menu order it will result in “wrong menus” if you are not using webpack[1] - (and possible also when doing production builds with the upcoming es module flag in webpack v5)
To Reproduce
- have a story file like
import { html } from '../../index.js';
export default {
title: 'Has order Paragraph-Heading',
};
export const paragraph = () =>
html`
<p>First Story</p>
`;
export const heading = () =>
html`
<h1>Second Story</h1>
`;
- using webpack results in the following menu
- Paragraph
- Heading
- using vanilla es module imports results in the following menu
- Heading
- Paragraph
Expected behavior Have storybook have the same story order when using webpack and when using es modules.
strawman proposal
We could export a special __exportOrder
array from within story files. This could be automatically done by a loader.
possible addition for the example above
// 1.
export __exportOrder = ['paragraph', 'heading'];
// 2.
export __orderedExports = [paragraph, heading];
with 1. you would sort the * imports via this array and with 2. you would ignore all other imports and just use this ordered array contain all exports.
Personally I think 2. sounds better
What do you all think?
[1]: > A quick check shows the problem is not limited to webpack; Babel & TypeScript also make no attempt to sort exports. tweet
Issue Analytics
- State:
- Created 4 years ago
- Reactions:7
- Comments:14 (14 by maintainers)
Top GitHub Comments
so I tested this and it works actually really nice 👍
one thing to mention is that the current implementation requires the key and the function… so using a simple array is not good enough => e.g. the simples would be to just use an object then 2 line changes in storybook are all that is needed
if we want an array then it would need to be an array of strings which we later use to create a source ordered object out of the alphabetically ordered exports.
imho 1. is good enough 👍 an array seems “cleaner” but not needing to add logic to create a new object out of an array and an object seems overall preferable
sounds good? 🤗
Works for me! 👍
Slightly cleaner: