Skip to content

Conversation

@jon-ht
Copy link

@jon-ht jon-ht commented Feb 8, 2025

Hi ! First thanks for this project, it looks very promising.

I'd like to use it in my projects, but I encountered some limitations.

When running npm run storybook / yarn storybook, it is expected to have a local PHP binary to run Symfony commands. I don't have PHP on my machine as our projects use Docker Compose.

Internal command can accept options

const prepareSymfonyCommand = (command: string, inputs: string[] = [], options: CommandOptions = {}) => {
const finalOptions = {
...defaultOptions,
...options,
};
return [finalOptions.php, finalOptions.script, command]
.concat([...inputs, '-v'])
.map((part) => `'${part}'`)
.join(' ');
};

But there is no way to provide custom PHP path nor use docker exec commands.


So here I am, with a proposal to not rely on PHP binary, and only use Symfony as we do every day : with cache files.

This PR aims to generate and use a file containing all configurations required by JS scripts. The file structure would be as follow

/path/to/app/var/cache/dev/storybook/symfony_parameters.json
{
  "twig_config": {
    "paths": {
      "\/var\/www\/templates": "Shared",
      "\/var\/www\/apps\/foo\/templates": "Foo"
    }
  },
  "twig_component_config": {
    "defaults": {
      "Front\\Twig\\Components\\": {
        "template_directory": "components\/",
        "name_prefix": "Shared"
      },
      "Front\\Foo\\Twig\\Components\\Bar\\Baz\\": {
        "template_directory": "bar\/baz\/components\/",
        "name_prefix": "Bar:Baz"
      },
      "Front\\Foo\\Twig\\Components\\": {
        "template_directory": "components",
        "name_prefix": ""
      }
    },
    "anonymous_template_directory": "components\/"
  }
}

Every command providing a configuration in symfony.ts is now a distinct entry in this symfony_parameters.json (any better name would be accepted)


WDYT about this ? This is still a draft, and more code should be adjusted in order to remove symfony.ts file and all related processes


TODO

  • Remove remaining types/functions from symfony.ts based on command execution
  • Update symfony.test.ts
  • Remove GeneratePreviewCommand
  • Update docs
  • Update recipe for .storybook/main.ts

@jon-ht jon-ht force-pushed the feat-use-cache-file-to-replace-commands branch from db97903 to 4c5fb18 Compare February 8, 2025 02:46
Comment on lines +28 to +50
private function getConfigForExtension(ExtensionInterface $extension, ContainerBuilder $container)
{
$extensionAlias = $extension->getAlias();

if (isset($this->extensionConfig[$extensionAlias])) {
return $this->extensionConfig[$extensionAlias];
}

$configs = $container->getExtensionConfig($extensionAlias);

$configuration = $extension instanceof ConfigurationInterface ? $extension : $extension->getConfiguration($configs, $container);

return $this->extensionConfig[$extensionAlias] = (new Processor())->processConfiguration($configuration, $configs);
}

private function getConfig(ContainerBuilder $container, ExtensionInterface $extension): array
{
return $container->resolveEnvPlaceholders(
$container->getParameterBag()->resolveValue(
$this->getConfigForExtension($extension, $container)
), true
);
}
Copy link
Author

@jon-ht jon-ht Feb 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This process is based on debug:config command.

I'm not really sure about the implementation. It gives me expected output, but there could be other ways to achieve this. Let me know if it could be improved

Comment on lines +18 to +25
public function __invoke(): Response
{
$this->eventDispatcher->dispatch(new GeneratePreviewEvent());

$content = $this->twig->render('@Storybook/preview.html.twig');

return new Response($content);
}
Copy link
Author

@jon-ht jon-ht Feb 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same process as storybook:generate-preview. This command should be removed before merging

@jon-ht jon-ht force-pushed the feat-use-cache-file-to-replace-commands branch from af6549d to 1c9fe90 Compare February 15, 2025 10:34
join(twigPath, symfonyConfig.twig_component_config.anonymous_template_directory)
);

const runtimeDir = (await getBundleConfig()).runtime_dir;
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure about the usage of runtime_dir. I didn't find anything in source code

@jon-ht jon-ht force-pushed the feat-use-cache-file-to-replace-commands branch from 9ae6e11 to dc17a81 Compare February 25, 2025 21:35
@jon-ht jon-ht marked this pull request as ready for review February 25, 2025 21:51
@jon-ht jon-ht force-pushed the feat-use-cache-file-to-replace-commands branch 2 times, most recently from 26e9f49 to c31f352 Compare February 25, 2025 22:27
@jon-ht jon-ht force-pushed the feat-use-cache-file-to-replace-commands branch from ba2753e to 50ed82a Compare April 8, 2025 13:24
@jon-ht
Copy link
Author

jon-ht commented Apr 8, 2025

Here's my main.ts with last commit

import 'dotenv/config';
import type { StorybookConfig } from '@sensiolabs/storybook-symfony-webpack5';

const config: StorybookConfig = {
    stories: [
        '../templates/components/**/*.stories.[tj]s'
    ],
    addons: [
        '@storybook/addon-webpack5-compiler-swc',
        '@storybook/addon-links',
        '@storybook/addon-essentials',
        '@storybook/addon-interactions',
    ],
    framework: {
        name: '@sensiolabs/storybook-symfony-webpack5',
        options: {
            // 👇 Here configure the framework
            symfony: {
                storybookCachePath: `var/cache/${process.env.APP_ENV}/storybook`,
                server: process.env.ETU_URL,
                proxyPaths: [
                    '/dist',
                ],
                additionalWatchPaths: [
                    '/assets'
                ],
            }
        },
    },
};

export default config;

Now storybook-static/iframe.html only contains minimal options when building for deployment.

Important

symfony.server option is mandatory, either for dev and prod builds. I don't know if it was a requirement before, but without it, Storybook is not able to generate components. I get the following error

Failed to inject Symfony preview template in main iframe.html

window['FRAMEWORK_OPTIONS'] = {"symfony":{"storybookCachePath":"var/cache/dev/storybook","server":"https://localhost:8005","proxyPaths":["/dist"],"additionalWatchPaths":[]}};

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant