UNPKG

@nx/storybook

Version:

The Nx Plugin for Storybook contains executors and generators for allowing your workspace to use the powerful Storybook integration testing & documenting capabilities.

210 lines (207 loc) • 8.05 kB
"use strict"; 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 `; }