Skip to content

Commit

Permalink
backstage: have a go at improving multi-brand storybooks
Browse files Browse the repository at this point in the history
  • Loading branch information
notlee committed Aug 22, 2022
1 parent be3b0e7 commit b80b1fe
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 56 deletions.
2 changes: 1 addition & 1 deletion .ruby-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2.7.4
2.7.6
3 changes: 3 additions & 0 deletions apps/storybook/addons/markdown-tabs/preset.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
const brand = process.env.ORIGAMI_STORYBOOK_BRAND || "core"

module.exports.managerEntries = function managerEntries(entry = []) {
return [
...entry,
Expand All @@ -6,6 +8,7 @@ module.exports.managerEntries = function managerEntries(entry = []) {
}

module.exports.managerWebpack = function managerWebpack(baseConfig) {
baseConfig.output.publicPath = `/brands/${brand}/`
baseConfig.module.rules.push({
test: /\.md$/,
type: "asset/source",
Expand Down
114 changes: 62 additions & 52 deletions apps/storybook/config/main.js
Original file line number Diff line number Diff line change
@@ -1,93 +1,98 @@
const { readFile, access } = require('node:fs/promises');
const {constants } = require('node:fs');
const path = require('node:path');
const process = require('node:process');
const globby = require('globby');
const {readFile, access} = require("node:fs/promises")
const {constants} = require("node:fs")
const path = require("node:path")
const process = require("node:process")
const globby = require("globby")

const brand = process.env.ORIGAMI_STORYBOOK_BRAND || "core";
const brand = process.env.ORIGAMI_STORYBOOK_BRAND || "core"
/**
* Node.JS no longer has an fs.exists method.
* Instead we use the fs.access method and check we can read the file.
* fs.access will throw an error if the file does not exist.
* @param {string} file file-system path to the file you are wanting to check exists or not
* @returns {Promise.<boolean>} Whether the file exists
*/
*/
async function fileExists(file) {
try {
await access(file, constants.R_OK);
return true;
await access(file, constants.R_OK)
return true
} catch (error) {
return false;
return false
}
}

function readIfExists(filePath) {
return fileExists(filePath)
.then(exists => {
if (exists) {
return readFile(filePath, 'utf-8');
} else {
return undefined;
}
});
return fileExists(filePath).then(exists => {
if (exists) {
return readFile(filePath, "utf-8")
} else {
return undefined
}
})
}

function requireIfExists(filePath) {
return readIfExists(filePath)
.then(file => {
return file ? JSON.parse(file) : undefined;
});
return readIfExists(filePath).then(file => {
return file ? JSON.parse(file) : undefined
})
}

function getOrigamiJson(cwd) {
cwd = cwd || process.cwd();
return requireIfExists(path.join(cwd, '/origami.json'));
cwd = cwd || process.cwd()
return requireIfExists(path.join(cwd, "/origami.json"))
}


function getComponentBrands(cwd) {
return getOrigamiJson(cwd)
.then(origamiJson => {
const hasBrandsDefined = origamiJson && origamiJson.brands && Array.isArray(origamiJson.brands) && origamiJson.brands.length > 0;
if (hasBrandsDefined) {
return origamiJson.brands;
}
return ['core', 'internal', 'whitelabel'];
});
return getOrigamiJson(cwd).then(origamiJson => {
const hasBrandsDefined =
origamiJson &&
origamiJson.brands &&
Array.isArray(origamiJson.brands) &&
origamiJson.brands.length > 0
if (hasBrandsDefined) {
return origamiJson.brands
}
return ["core", "internal", "whitelabel"]
})
}

module.exports.core = {
builder: "webpack5",
options: {
lazyCompilation: true,
},
lazyCompilation: true,
},
}

module.exports.stories = (async () => {
const storyPaths = [
"../stories/**/*.stories.mdx",
"../stories/**/*.stories.@(js|jsx|ts|tsx)"
];
"../stories/**/*.stories.@(js|jsx|ts|tsx)",
]

const componentDirectories = await globby(['../../components/**'], {
const componentDirectories = await globby(["../../components/**"], {
gitignore: false,
expandDirectories: false,
onlyDirectories: true,
deep: 1,
});
})

for (const componentDirectory of componentDirectories) {
const brands = await getComponentBrands(componentDirectory);
const storiesForBrand = brands.includes(brand) ? await globby([`${componentDirectory}/stories/**/*.stories.@(mdx|js|jsx|ts|tsx)`], {
gitignore: false,
expandDirectories: false,
deep: 1,
}) : [];
storyPaths.push(...storiesForBrand.map(storyPath => `../${storyPath}`));
const brands = await getComponentBrands(componentDirectory)
const storiesForBrand = brands.includes(brand)
? await globby(
[`${componentDirectory}/stories/**/*.stories.@(mdx|js|jsx|ts|tsx)`],
{
gitignore: false,
expandDirectories: false,
deep: 1,
}
)
: []
storyPaths.push(...storiesForBrand.map(storyPath => `../${storyPath}`))
}

return storyPaths;
})();
return storyPaths
})()

module.exports.addons = [
"@storybook/addon-essentials",
Expand Down Expand Up @@ -130,6 +135,7 @@ module.exports.typescript = {
}

module.exports.webpackFinal = async function webpackFinal(config) {
config.output.publicPath = `/brands/${brand}/`
// i've had to add all this because for some reason storybook doesn't
// understand jsx on heroku unless i do ???
config.module.rules.push({
Expand Down Expand Up @@ -158,12 +164,16 @@ module.exports.webpackFinal = async function webpackFinal(config) {
return config
}

module.exports.managerWebpack = async function managerWebpack(config) {
config.output.publicPath = `/brands/${brand}/`
return config
}

module.exports.env = (config) => ({
...config,
ORIGAMI_STORYBOOK_BRAND: brand
module.exports.env = config => ({
...config,
ORIGAMI_STORYBOOK_BRAND: brand,
})

module.exports.features = {
buildStoriesJson: true
buildStoriesJson: true,
}
6 changes: 3 additions & 3 deletions apps/storybook/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
"sb:core": "start-storybook -p ${PORT:-6969} -c ./config",
"sb:internal": "ORIGAMI_STORYBOOK_BRAND=internal start-storybook -p ${PORT:-6970} -c ./config",
"storybook": "(npm run sb:internal) & (npm run sb:core)",
"build-sb-default": "build-storybook --modern -c ./wrapper -o ../../origami.ft.com/storybook",
"build-sb:core": "ORIGAMI_STORYBOOK_BRAND=core build-storybook --modern -c ./config -o ../../origami.ft.com/brands/core",
"build-sb:internal": "ORIGAMI_STORYBOOK_BRAND=internal build-storybook --modern -c ./config -o ../../origami.ft.com/brands/internal",
"build-sb-default": "build-storybook --modern -c ./wrapper -o ../../origami.ft.com/storybook --preview-url=/storybook/iframe.html --force-build-preview",
"build-sb:core": "ORIGAMI_STORYBOOK_BRAND=core build-storybook --modern -c ./config -o ../../origami.ft.com/brands/core --preview-url=/brands/core/iframe.html --force-build-preview",
"build-sb:internal": "ORIGAMI_brands_BRAND=internal build-storybook --modern -c ./config -o ../../origami.ft.com/brands/internal --preview-url=/brands/internal/iframe.html --force-build-preview",
"build-storybook": "run-p build-sb:* && npm run build-sb-default",
"watch-storybook": "npm run build-storybook -- -w"
},
Expand Down
10 changes: 10 additions & 0 deletions apps/storybook/wrapper/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,16 @@ module.exports.addons = [
"origami-storybook-addon-html/register",
]

module.exports.managerWebpack = async function managerWebpack(config) {
config.output.publicPath = "/storybook/"
return config
}

module.exports.webpackFinal = async function webpackFinal(config) {
config.output.publicPath = "/storybook/"
return config
}

module.exports.refs = (config, {configType}) => {
if (configType === "DEVELOPMENT") {
return {
Expand Down

0 comments on commit b80b1fe

Please sign in to comment.