From 5c0e36694a49f017a06d0331e45ca384fc5f7677 Mon Sep 17 00:00:00 2001 From: Fracsi Date: Wed, 22 Jan 2025 17:31:51 +0100 Subject: [PATCH] Allow using custom PostCSS configuration file (#80) * PostCss option Add tailwind cli postcss option to the build command * PostCSS config file to config Test added Documentation added * Documentation fix * Reformat services.php * Consistent naming Co-Authored-By: Victor Bocharsky --------- Co-authored-by: Victor Bocharsky --- config/services.php | 11 ++++---- doc/index.rst | 21 +++++++++++++++- src/Command/TailwindBuildCommand.php | 2 ++ src/DependencyInjection/TailwindExtension.php | 5 ++++ src/TailwindBuilder.php | 25 +++++++++++++++++++ tests/TailwindBuilderTest.php | 22 ++++++++++++++++ tests/fixtures/postcss.config.js | 10 ++++++++ 7 files changed, 89 insertions(+), 7 deletions(-) create mode 100644 tests/fixtures/postcss.config.js diff --git a/config/services.php b/config/services.php index 9a7f258..ab9c2f0 100644 --- a/config/services.php +++ b/config/services.php @@ -1,12 +1,11 @@ set('tailwind.command.build', TailwindBuildCommand::class) ->args([ - service('tailwind.builder') + service('tailwind.builder'), ]) ->tag('console.command') @@ -42,11 +42,10 @@ ->set('tailwind.css_asset_compiler', TailwindCssAssetCompiler::class) ->args([ - service('tailwind.builder') + service('tailwind.builder'), ]) ->tag('asset_mapper.compiler', [ // run before core CssAssetUrlCompiler that resolves url() references 'priority' => 10, - ]) - ; + ]); }; diff --git a/doc/index.rst b/doc/index.rst index 6a40d66..9d216e7 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -189,7 +189,7 @@ the default directories, for example, in the ``vendor/`` directory like the .. code-block:: yaml # config/packages/twig.yaml - twig: + twig: form_themes: - 'tailwind_2_layout.html.twig' @@ -234,6 +234,25 @@ if you want to use a different version, you can specify the version to use, set ``binary_version`` option: .. code-block:: yaml + # config/packages/symfonycasts_tailwind.yaml symfonycasts_tailwind: binary_version: 'v3.3.0' + +Using a PostCSS config file +------------------------ + +If you want to use additional PostCSS plugins, you can specify the +PostCSS config file to use, set ``postcss_config_file`` option or +pass the ``--postcss`` option to the ``tailwind:build`` command. + +.. code-block:: yaml + + # config/packages/symfonycasts_tailwind.yaml + symfonycasts_tailwind: + postcss_config_file: 'postcss.config.js' + + +.. code-block:: terminal + + $ php bin/console tailwind:build --postcss='postcss.config.js' diff --git a/src/Command/TailwindBuildCommand.php b/src/Command/TailwindBuildCommand.php index d86ee0b..51b96a1 100644 --- a/src/Command/TailwindBuildCommand.php +++ b/src/Command/TailwindBuildCommand.php @@ -37,6 +37,7 @@ protected function configure(): void ->addOption('watch', 'w', null, 'Watch for changes and rebuild automatically') ->addOption('poll', null, null, 'Use polling instead of filesystem events when watching') ->addOption('minify', 'm', InputOption::VALUE_NONE, 'Minify the output CSS') + ->addOption('postcss', null, InputOption::VALUE_REQUIRED, 'Load custom PostCSS configuration') ; } @@ -50,6 +51,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int poll: $input->getOption('poll'), minify: $input->getOption('minify'), inputFile: $input->getArgument('input_css'), + postCssConfigFile: $input->getOption('postcss'), ); $process->wait(function ($type, $buffer) use ($io) { $io->write($buffer); diff --git a/src/DependencyInjection/TailwindExtension.php b/src/DependencyInjection/TailwindExtension.php index 5bb2912..116ef86 100644 --- a/src/DependencyInjection/TailwindExtension.php +++ b/src/DependencyInjection/TailwindExtension.php @@ -32,6 +32,7 @@ public function load(array $configs, ContainerBuilder $container): void ->replaceArgument(4, $config['binary']) ->replaceArgument(5, $config['binary_version']) ->replaceArgument(6, $config['config_file']) + ->replaceArgument(7, $config['postcss_config_file']) ; } @@ -71,6 +72,10 @@ public function getConfigTreeBuilder(): TreeBuilder ->info('Tailwind CLI version to download - null means the latest version') ->defaultNull() ->end() + ->scalarNode('postcss_config_file') + ->info('Path to PostCSS config file which is passed to the Tailwind CLI') + ->defaultNull() + ->end() ->end(); return $treeBuilder; diff --git a/src/TailwindBuilder.php b/src/TailwindBuilder.php index 2a0a186..7d3fdec 100644 --- a/src/TailwindBuilder.php +++ b/src/TailwindBuilder.php @@ -34,6 +34,7 @@ public function __construct( private readonly ?string $binaryPath = null, private readonly ?string $binaryVersion = null, private readonly string $configPath = 'tailwind.config.js', + private readonly ?string $postCssConfigPath = null, ) { $paths = []; foreach ($inputPaths as $inputPath) { @@ -48,6 +49,7 @@ public function runBuild( bool $poll, bool $minify, ?string $inputFile = null, + ?string $postCssConfigFile = null, ): Process { $binary = $this->createBinary(); @@ -66,6 +68,12 @@ public function runBuild( if ($minify) { $arguments[] = '--minify'; } + + $postCssConfigPath = $this->validatePostCssConfigFile($postCssConfigFile ?? $this->postCssConfigPath); + if ($postCssConfigPath) { + $arguments[] = '--postcss'; + $arguments[] = $postCssConfigPath; + } $process = $binary->createProcess($arguments); if ($watch) { $process->setTimeout(null); @@ -145,6 +153,23 @@ private function validateInputFile(string $inputPath): string throw new \InvalidArgumentException(\sprintf('The input CSS file "%s" does not exist.', $inputPath)); } + private function validatePostCssConfigFile(?string $postCssConfigPath): ?string + { + if (null === $postCssConfigPath) { + return null; + } + + if (is_file($postCssConfigPath)) { + return realpath($postCssConfigPath); + } + + if (is_file($this->projectRootDir.'/'.$postCssConfigPath)) { + return realpath($this->projectRootDir.'/'.$postCssConfigPath); + } + + throw new \InvalidArgumentException(\sprintf('The PostCSS config file "%s" does not exist.', $postCssConfigPath)); + } + private function createBinary(): TailwindBinary { return new TailwindBinary($this->tailwindVarDir, $this->projectRootDir, $this->binaryPath, $this->binaryVersion, $this->cache, $this->output); diff --git a/tests/TailwindBuilderTest.php b/tests/TailwindBuilderTest.php index cb7292e..f5b2054 100644 --- a/tests/TailwindBuilderTest.php +++ b/tests/TailwindBuilderTest.php @@ -106,4 +106,26 @@ public function testBuildProvidedInputFile(): void $outputFileContents = file_get_contents(__DIR__.'/fixtures/var/tailwind/second.built.css'); $this->assertStringContainsString('body{background-color:blue}', $outputFileContents, 'The output file should contain minified CSS.'); } + + public function testIntegrationWithPostcss(): void + { + $builder = new TailwindBuilder( + __DIR__.'/fixtures', + [__DIR__.'/fixtures/assets/styles/app.css'], + __DIR__.'/fixtures/var/tailwind', + new ArrayAdapter(), + null, + null, + __DIR__.'/fixtures/tailwind.config.js', + __DIR__.'/fixtures/postcss.config.js', + ); + $process = $builder->runBuild(watch: false, poll: false, minify: false); + $process->wait(); + + $this->assertTrue($process->isSuccessful()); + $this->assertFileExists(__DIR__.'/fixtures/var/tailwind/app.built.css'); + + $outputFileContents = file_get_contents(__DIR__.'/fixtures/var/tailwind/app.built.css'); + $this->assertStringContainsString('.dummy {}', $outputFileContents, 'The output file should contain the dummy CSS added by the dummy plugin.'); + } } diff --git a/tests/fixtures/postcss.config.js b/tests/fixtures/postcss.config.js new file mode 100644 index 0000000..492f2c5 --- /dev/null +++ b/tests/fixtures/postcss.config.js @@ -0,0 +1,10 @@ +module.exports = { + plugins: [ + { + postcssPlugin: 'dummy', + Once (root) { + root.append('.dummy {}') + }, + }, + ], +}