Skip to content

Commit

Permalink
feat(remix): add storybook-configuration generator
Browse files Browse the repository at this point in the history
  • Loading branch information
Coly010 committed Jun 20, 2023
1 parent f8d658e commit 935e9d0
Show file tree
Hide file tree
Showing 10 changed files with 293 additions and 3 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
"@nx/react": "16.4.0-beta.10",
"@nx/vite": "16.4.0-beta.10",
"@nx/workspace": "16.4.0-beta.10",
"@nx/storybook": "16.4.0-beta.10",
"@phenomnomnominal/tsquery": "^5.0.1",
"@remix-run/dev": "1.15.0",
"@remix-run/node": "1.15.0",
Expand Down
17 changes: 14 additions & 3 deletions packages/remix/generators.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
"$schema": "http://json-schema.org/schema",
"name": "NxRemix",
"version": "0.0.1",
"extends": ["@nx/react"],
"extends": [
"@nx/react"
],
"generators": {
"preset": {
"implementation": "./src/generators/preset/preset.impl",
Expand All @@ -20,14 +22,18 @@
"implementation": "./src/generators/application/application.impl",
"schema": "./src/generators/application/schema.json",
"description": "Generate a new Remix application",
"aliases": ["app"],
"aliases": [
"app"
],
"x-type": "application"
},
"library": {
"implementation": "./src/generators/library/library.impl",
"schema": "./src/generators/library/schema.json",
"description": "Generate a new library",
"aliases": ["lib"],
"aliases": [
"lib"
],
"x-type": "library"
},
"route": {
Expand Down Expand Up @@ -60,6 +66,11 @@
"schema": "./src/generators/setup-tailwind/schema.json",
"description": "Generates a TailwindCSS configuration for the Remix application"
},
"storybook-configuration": {
"implementation": "./src/generators/storybook-configuration/storybook-configuration.impl",
"schema": "./src/generators/storybook-configuration/schema.json",
"description": "Generates a Storybook configuration for a Remix application"
},
"meta": {
"implementation": "./src/generators/meta/meta.impl",
"schema": "./src/generators/meta/schema.json",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Storybook Configuration it should create a storybook configuration and use react-vite framework with testing framework jest 1`] = `
"const config = {
stories: ['../src/lib/**/*.stories.@(js|jsx|ts|tsx|mdx)'],
addons: ['@storybook/addon-essentials'],
framework: {
name: '@storybook/react-vite',
options: {
builder: {
viteConfigPath: '',
},
},
},
};
export default config;
// To customize your Vite configuration you can use the viteFinal field.
// Check https://storybook.js.org/docs/react/builders/vite#configuration
// and https://nx.dev/packages/storybook/documents/custom-builder-configs
"
`;

exports[`Storybook Configuration it should create a storybook configuration and use react-vite framework with testing framework none 1`] = `
"const config = {
stories: ['../src/lib/**/*.stories.@(js|jsx|ts|tsx|mdx)'],
addons: ['@storybook/addon-essentials'],
framework: {
name: '@storybook/react-vite',
options: {
builder: {
viteConfigPath: '',
},
},
},
};
export default config;
// To customize your Vite configuration you can use the viteFinal field.
// Check https://storybook.js.org/docs/react/builders/vite#configuration
// and https://nx.dev/packages/storybook/documents/custom-builder-configs
"
`;

exports[`Storybook Configuration it should create a storybook configuration and use react-vite framework with testing framework vitest 1`] = `
"const config = {
stories: ['../src/lib/**/*.stories.@(js|jsx|ts|tsx|mdx)'],
addons: ['@storybook/addon-essentials'],
framework: {
name: '@storybook/react-vite',
options: {
builder: {
viteConfigPath: '',
},
},
},
};
export default config;
// To customize your Vite configuration you can use the viteFinal field.
// Check https://storybook.js.org/docs/react/builders/vite#configuration
// and https://nx.dev/packages/storybook/documents/custom-builder-configs
"
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/// <reference types="vitest" />
import {defineConfig} from 'vite';
import react from '@vitejs/plugin-react';
import viteTsConfigPaths from 'vite-tsconfig-paths';

export default defineConfig({
cacheDir: '../../../node_modules/.vite/storybook-generator-test',

plugins: [
react(),
viteTsConfigPaths({
root: '../../../',
}),
],
})
15 changes: 15 additions & 0 deletions packages/remix/src/generators/storybook-configuration/schema.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { Linter } from '@nx/linter';

export interface StorybookConfigurationSchema {
name: string;
configureCypress: boolean;
generateStories?: boolean;
generateCypressSpecs?: boolean;
js?: boolean;
tsConfiguration?: boolean;
linter?: Linter;
cypressDirectory?: string;
ignorePaths?: string[];
configureTestRunner?: boolean;
configureStaticServe?: boolean;
}
96 changes: 96 additions & 0 deletions packages/remix/src/generators/storybook-configuration/schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
{
"$schema": "http://json-schema.org/schema",
"cli": "nx",
"$id": "NxRemixStorybookConfigure",
"title": "Remix Storybook Configuration",
"description": "Set up Storybook for a Remix library.",
"type": "object",
"properties": {
"name": {
"type": "string",
"aliases": [
"project",
"projectName"
],
"description": "Project for which to generate Storybook configuration.",
"$default": {
"$source": "argv",
"index": 0
},
"x-prompt": "For which project do you want to generate Storybook configuration?",
"x-dropdown": "projects",
"x-priority": "important"
},
"configureCypress": {
"type": "boolean",
"description": "Run the cypress-configure generator.",
"x-prompt": "Configure a cypress e2e app to run against the storybook instance?",
"default": true,
"x-priority": "important"
},
"generateStories": {
"type": "boolean",
"description": "Automatically generate `*.stories.ts` files for components declared in this project?",
"x-prompt": "Automatically generate *.stories.ts files for components declared in this project?",
"default": true,
"x-priority": "important"
},
"generateCypressSpecs": {
"type": "boolean",
"description": "Automatically generate test files in the Cypress E2E app generated by the `cypress-configure` generator.",
"x-prompt": "Automatically generate test files in the Cypress E2E app generated by the cypress-configure generator?",
"default": true,
"x-priority": "important"
},
"configureStaticServe": {
"type": "boolean",
"description": "Specifies whether to configure a static file server target for serving storybook. Helpful for speeding up CI build/test times.",
"x-prompt": "Configure a static file server for the storybook instance?",
"default": true,
"x-priority": "important"
},
"cypressDirectory": {
"type": "string",
"description": "A directory where the Cypress project will be placed. Placed at the root by default."
},
"js": {
"type": "boolean",
"description": "Generate JavaScript story files rather than TypeScript story files.",
"default": false
},
"tsConfiguration": {
"type": "boolean",
"description": "Configure your project with TypeScript. Generate main.ts and preview.ts files, instead of main.js and preview.js.",
"default": false
},
"linter": {
"description": "The tool to use for running lint checks.",
"type": "string",
"enum": [
"eslint"
],
"default": "eslint"
},
"ignorePaths": {
"type": "array",
"description": "Paths to ignore when looking for components.",
"items": {
"type": "string",
"description": "Path to ignore."
},
"examples": [
"**/**/src/**/not-stories/**",
"libs/my-lib/**/*.something.ts",
"**/**/src/**/*.other.*",
"libs/my-lib/src/not-stories/**,**/**/src/**/*.other.*,apps/my-app/**/*.something.ts"
]
},
"configureTestRunner": {
"type": "boolean",
"description": "Add a Storybook Test-Runner target."
}
},
"required": [
"name"
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
import libraryGenerator from '../library/library.impl';
import storybookConfigurationGenerator from './storybook-configuration.impl';

describe('Storybook Configuration', () => {
it.each(['jest', 'vitest', 'none'])(
'it should create a storybook configuration and use react-vite framework with testing framework %s',
async (unitTestRunner: 'jest' | 'vitest' | 'none') => {
// ARRANGE
const tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });

await libraryGenerator(tree, {
name: 'storybook-test',
style: 'css',
unitTestRunner,
});

// ACT
await storybookConfigurationGenerator(tree, {
name: 'storybook-test',
configureCypress: false,
configureStaticServe: false,
generateStories: true,
});

// ASSERT
expect(tree.exists(`libs/storybook-test/vite.config.ts`));
expect(
tree.read(`libs/storybook-test/.storybook/main.js`, 'utf-8')
).toMatchSnapshot();
}
);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import {
ensurePackage,
generateFiles,
joinPathFragments,
readProjectConfiguration,
type Tree,
} from '@nx/devkit';
import { join } from 'path';
import { getPackageVersion } from '../../utils/versions';
import type { StorybookConfigurationSchema } from './schema';

export default async function remixStorybookConfiguration(
tree: Tree,
schema: StorybookConfigurationSchema
) {
const { root } = readProjectConfiguration(tree, schema.name);

if (!tree.exists(joinPathFragments(root, 'vite.config.ts'))) {
generateFiles(tree, join(__dirname, 'files'), root, { tpl: '' });
}

const { storybookConfigurationGenerator } = ensurePackage<
typeof import('@nx/react')
>('@nx/react', getPackageVersion(tree, 'nx'));

const task = await storybookConfigurationGenerator(tree, schema);

return task;
}
1 change: 1 addition & 0 deletions packages/remix/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ export * from './generators/meta/meta.impl';
export * from './generators/preset/preset.impl';
export * from './generators/resource-route/resource-route.impl';
export * from './generators/route/route.impl';
export * from './generators/storybook-configuration/storybook-configuration.impl';
export * from './generators/style/style.impl';
export { createWatchPaths } from './utils/create-watch-paths';
22 changes: 22 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1901,6 +1901,13 @@
dependencies:
"@nx/react" "16.4.0-beta.10"

"@nrwl/[email protected]":
version "16.4.0-beta.10"
resolved "https://registry.yarnpkg.com/@nrwl/storybook/-/storybook-16.4.0-beta.10.tgz#01ae1379a2693325fcc06b07e2107240c6ae475a"
integrity sha512-YyMLNmCJCzNKG/DnnLK2TEIG76W04o78Tmst+J43pk8nIHcBS2vLBqjFWXqC9N6PYi/V0XgxYjHoDJAMeQ+HRg==
dependencies:
"@nx/storybook" "16.4.0-beta.10"

"@nrwl/[email protected]":
version "16.4.0-beta.10"
resolved "https://registry.yarnpkg.com/@nrwl/tao/-/tao-16.4.0-beta.10.tgz#02330aa179eedfebb0231d444494fe66b5f02756"
Expand Down Expand Up @@ -2137,6 +2144,21 @@
file-loader "^6.2.0"
minimatch "3.0.5"

"@nx/[email protected]":
version "16.4.0-beta.10"
resolved "https://registry.yarnpkg.com/@nx/storybook/-/storybook-16.4.0-beta.10.tgz#8e4c27b415eac240442640dc9b9dc9f2eaf5d426"
integrity sha512-ee4Iv1+UTINQyP2Tf01ERgKhA5ncvwyJrqpIxnDdJt3BY6LxGGw6K6bNsJtTENrMGiqsUqPNhnMREuI+IAdOTg==
dependencies:
"@nrwl/storybook" "16.4.0-beta.10"
"@nx/cypress" "16.4.0-beta.10"
"@nx/devkit" "16.4.0-beta.10"
"@nx/js" "16.4.0-beta.10"
"@nx/linter" "16.4.0-beta.10"
"@nx/workspace" "16.4.0-beta.10"
"@phenomnomnominal/tsquery" "~5.0.1"
dotenv "~10.0.0"
semver "7.3.4"

"@nx/[email protected]":
version "16.4.0-beta.10"
resolved "https://registry.yarnpkg.com/@nx/vite/-/vite-16.4.0-beta.10.tgz#b3e53d216976e355e3b8f2f7afef32747e7e848c"
Expand Down

0 comments on commit 935e9d0

Please sign in to comment.