@nx/storybook
Version:
210 lines (207 loc) • 8.05 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.Constants = void 0;
exports.storybookMajorVersion = storybookMajorVersion;
exports.getInstalledStorybookVersion = getInstalledStorybookVersion;
exports.safeFileDelete = safeFileDelete;
exports.storybookConfigExistsCheck = storybookConfigExistsCheck;
exports.dedupe = dedupe;
exports.findStorybookAndBuildTargetsAndCompiler = findStorybookAndBuildTargetsAndCompiler;
exports.isTheFileAStory = isTheFileAStory;
exports.getTsSourceFile = getTsSourceFile;
exports.pleaseUpgrade = pleaseUpgrade;
const fs_1 = require("fs");
const js_1 = require("@nx/js");
const ts = require("typescript");
const semver_1 = require("semver");
const path_1 = require("path");
exports.Constants = {
addonDependencies: ['@storybook/addons'],
tsConfigExclusions: ['stories', '**/*.stories.ts'],
pkgJsonScripts: {
storybook: 'start-storybook -p 9001 -c .storybook',
},
jsonIndentLevel: 2,
coreAddonPrefix: '@storybook/addon-',
uiFrameworks7: [
'@storybook/angular',
'@storybook/html-webpack5',
'@storybook/nextjs',
'@storybook/preact-webpack5',
'@storybook/react-webpack5',
'@storybook/react-vite',
'@storybook/server-webpack5',
'@storybook/svelte-webpack5',
'@storybook/svelte-vite',
'@storybook/sveltekit',
'@storybook/vue-webpack5',
'@storybook/vue-vite',
'@storybook/vue3-webpack5',
'@storybook/vue3-vite',
'@storybook/web-components-webpack5',
'@storybook/web-components-vite',
],
};
function storybookMajorVersion() {
try {
const storybookPackageVersion = require((0, path_1.join)('storybook', 'package.json')).version;
return (0, semver_1.major)(storybookPackageVersion);
}
catch {
return undefined;
}
}
function getInstalledStorybookVersion() {
try {
const storybookPackageVersion = require((0, path_1.join)('storybook', 'package.json')).version;
return storybookPackageVersion;
}
catch {
return undefined;
}
}
function safeFileDelete(tree, path) {
if (tree.exists(path)) {
tree.delete(path);
return true;
}
else {
return false;
}
}
function storybookConfigExistsCheck(config, projectName) {
const exists = !!(config && (0, fs_1.statSync)(config).isDirectory());
if (!exists) {
throw new Error(`Could not find Storybook configuration for project ${projectName}.
Please generate Storybook configuration using the following command:
nx g @nx/storybook:configuration --name=${projectName}
`);
}
}
function dedupe(arr) {
return Array.from(new Set(arr));
}
function findStorybookAndBuildTargetsAndCompiler(targets) {
const returnObject = {};
const arrayOfBuilders = [
'@nx/js:babel',
'@nx/js:swc',
'@nx/js:tsc',
'@nx/webpack:webpack',
'@nx/rollup:rollup',
'@nx/vite:build',
'@nx/angular:ng-packagr-lite',
'@nx/angular:package',
'@nx/angular:webpack-browser',
'@nx/esbuild:esbuild',
'@nx/next:build',
'@nxext/vite:build',
'@angular-devkit/build-angular:application',
'@angular-devkit/build-angular:browser',
'@angular-devkit/build-angular:browser-esbuild',
];
for (const target in targets) {
if (arrayOfBuilders.includes(targets[target].executor)) {
if (targets[target].executor === '@angular-devkit/build-angular:browser' ||
targets[target].executor ===
'@angular-devkit/build-angular:browser-esbuild' ||
targets[target].executor === '@angular-devkit/build-angular:application') {
/**
* Not looking for '@nx/angular:ng-packagr-lite' or any other
* @nx/angular:* executors.
* Only looking for '@angular-devkit/build-angular:browser'
* because the '@nx/angular:ng-packagr-lite' executor
* (and maybe the other custom executors)
* does not support styles and extra options, so the user
* will be forced to switch to build-storybook to add extra options.
*
* So we might as well use the build-storybook by default to
* avoid any errors.
*/
returnObject.ngBuildTarget = target;
}
else if (targets[target].executor.includes('vite')) {
returnObject.viteBuildTarget = target;
}
else if (targets[target].executor.includes('next')) {
returnObject.nextBuildTarget = target;
}
else {
returnObject.otherBuildTarget = target;
}
returnObject.compiler = targets[target].options?.compiler;
}
else if (targets[target].executor === '@storybook/angular:start-storybook' ||
targets[target].executor === '@nx/storybook:storybook') {
returnObject.storybookTarget = target;
}
else if (targets[target].executor === '@storybook/angular:build-storybook' ||
targets[target].executor === '@nx/storybook:build') {
returnObject.storybookBuildTarget = target;
}
else if (targets[target].options?.compiler) {
returnObject.otherBuildTarget = target;
returnObject.compiler = targets[target].options?.compiler;
}
}
return returnObject;
}
function isTheFileAStory(tree, path) {
const ext = path.slice(path.lastIndexOf('.'));
let fileIsStory = false;
if (ext === '.tsx' || ext === '.ts') {
const file = getTsSourceFile(tree, path);
const importArray = (0, js_1.findNodes)(file, [ts.SyntaxKind.ImportDeclaration]);
let nodeContainsStorybookImport = false;
let nodeContainsStoryImport = false;
importArray.forEach((importNode) => {
const importPath = (0, js_1.findNodes)(importNode, [ts.SyntaxKind.StringLiteral]);
importPath.forEach((importPath) => {
if (importPath.getText()?.includes('@storybook/')) {
nodeContainsStorybookImport = true;
}
});
const importSpecifiers = (0, js_1.findNodes)(importNode, [
ts.SyntaxKind.ImportSpecifier,
ts.SyntaxKind.NamespaceImport,
]);
importSpecifiers.forEach((importSpecifier) => {
if (importSpecifier.getText() === 'Story' ||
importSpecifier.getText() === 'Meta' ||
importSpecifier.getText() === 'storiesOf' ||
importSpecifier.getText() === 'ComponentStory' ||
importSpecifier.getText().includes('Storybook')) {
nodeContainsStoryImport = true;
}
});
// We place this check within the loop, because we want the
// import combination of Story from @storybook/*
if (nodeContainsStorybookImport && nodeContainsStoryImport) {
fileIsStory = true;
}
});
}
else {
fileIsStory =
(path.endsWith('.js') && path.endsWith('.stories.js')) ||
(path.endsWith('.jsx') && path.endsWith('.stories.jsx'));
}
return fileIsStory;
}
function getTsSourceFile(host, path) {
const buffer = host.read(path);
if (!buffer) {
throw new Error(`Could not read TS file (${path}).`);
}
const content = buffer.toString();
const source = ts.createSourceFile(path, content, ts.ScriptTarget.Latest, true);
return source;
}
function pleaseUpgrade() {
return `
Storybook 7 and lower are no longer maintained, and not supported in Nx.
Please upgrade to Storybook 8.
Here is a guide on how to upgrade:
https://nx.dev/nx-api/storybook/generators/migrate-8
`;
}