Skip to content

Commit

Permalink
FIX Resolving an issue where no .stories.js file would error
Browse files Browse the repository at this point in the history
Caused by trying to realpath a non-existent file. This commit also updates code docs
  • Loading branch information
ScopeyNZ committed Jul 18, 2019
1 parent 3031cf1 commit c11d0f3
Showing 1 changed file with 35 additions and 20 deletions.
55 changes: 35 additions & 20 deletions .storybook/lib/storyTeller.js
Expand Up @@ -7,21 +7,15 @@ const exec = promisify(require('child_process').exec);

const configName = '.ss-storybook.js';

/**
* Locates modules in the given root (matching the base path and any composer style vendor folder
* within that root) that define a .ss-storybook.js config file.
*
* Note that this function will also generate a .stories.js file that declares module roots in a way
* that can be static analyzed for webpack to build a valid bundle for storybook. This script should
* run before or during the webpack bundle for storybook.
*
* Returns an array of module configuration
*
* @param {string} root Root location to find stories
* @param {bool} generate
* @return {Array<Object>}
*/
module.exports = {
/**
* "Collect" modules within the vendor folder OR the project root to show stories from. This will
* find any `.ss-storybook.js` file that provides configuration for locating stories (and their
* dependencies)
*
* @param {string} root
* @return {Array<Object>} Discovered configuration
*/
collectStoryRoots(root) {
const modules = glob.sync(
[`${root}/${configName}`, `${root}/vendor/**/${configName}`],
Expand Down Expand Up @@ -51,6 +45,13 @@ module.exports = {
return output;
},

/**
* Trigger a `yarn` in modules that have been "collected" but there doesn't appear to be a
* node_modules folder. This is intended for use with `collectStoryRoots`
*
* @param {Array<Object>} storyRoots
* @return {Promise<void>}
*/
async assertYarn(storyRoots) {
const promises = [];

Expand All @@ -66,9 +67,15 @@ module.exports = {
await Promise.all(promises);
},

/**
* Generate a JavaScript file to the given output location that declares what contexts should be
* included when storybook builds bundles with webpack. This is generated as webpack cannot handle
* compiling dynamic routes - it will need to statically analyze file paths.
*
* @param {Array<Object>} storyRoots
* @param {string} output The output filename
*/
generateStoriesLoader(storyRoots, output = `${__dirname}/../.stories.js`) {
const realOutput = fs.realpathSync(output);

const script = `export default [\n${storyRoots.reduce((acc, { src, fileMatcher }) => {
const matcher = fileMatcher instanceof RegExp
? fileMatcher.toString()
Expand All @@ -77,22 +84,30 @@ module.exports = {
return `${acc} require.context('${src}', true, ${matcher}),\n`;
}, '')}];`;

console.log(`Outputting story loader file to "${chalk.yellow(realOutput)}".`);

fs.writeFile(realOutput, script, err => {
fs.writeFile(output, script, err => {
if (err) {
console.log(chalk.bgRed(`Could not export modules: ${err}`));
}
});

console.log(`Outputted story loader file to "${chalk.yellow(fs.realpathSync(output))}".`);
},

/**
* Attempt to determine the project root. This is fairly dumb and will only return the folder that
* is 3 folders up if a vendor folder does not exist in the current directory.
*
* @return {string}
*/
getDefaultRoot() {
// Check if a `vendor` folder exists in the project root.
// Move up to the admin root.
let projectRoot = path.resolve(`${__dirname}/../../`);

try {
// Check if there's a `vendor` folder
fs.accessSync(`${projectRoot}/vendor/`);
} catch (err) {
// Assume that we're already in vendor, so the root must be 3 folders up.
projectRoot = path.resolve(`${projectRoot}/../../../`);
}

Expand Down

0 comments on commit c11d0f3

Please sign in to comment.