Asset Compilation

Introduction

Winter brings first-class support for handling Node-based compilation for frontend assets through the Mix & Vite commands.

Simply use one of the following commands to get started (<package name> refers to either a plugin code (i.e. Winter.Blog) or a theme code (i.e. my-theme)):

Requirements

To take advantage of the CLI asset compilation options, you must have Node and the Node package manager (NPM) installed in your development environment. This will be dependent on your operating system - please review the Download NodeJS page for more information on installing Node.

To make use of Mix, Laravel Mix should also be present in the package.json file for any packages that will be using it (either in dependencies or a devDependencies) but if it is not specified in the project's package.json file then it can be optionally automatically added when running the mix:install command.

Registering a package

Registering for asset compilation through Mix or Vite is very easy. Automatic registration should meet your needs most of the time, and if not there are several methods available to manually register Mix packages.

Automatic registration

By default, Winter will scan all available and enabled modules, plugins and themes for the presence of a config file from a supported compiler under each extension's root folder (i.e. modules/system/config_file.js, plugins/myauthor/myplugin/config_file.js, or themes/mytheme/config_file.js).

If the config file is found, it will be automatically registered as a package with an automatically generated package name, and will show up when running the applicable compiler's commands. Most of the time, this should be all you need to do in order to get started with one of the asset compilers in Winter CMS.

The currently supported config files are:

  • winter.mix.js - for the Mix compiler.
  • vite.config.js - for the Vite compiler.

Supported Asset Compilers

Winter CMS supports the following:

For more information on these compilers, see the links above.

Supported Toolset (Bundles)

When using Vite or Mix, Winter can automatically configure your plugin/theme via the vite:create or mix:create commands. These commands allow you to set up all config files, stub files and register any required npm packages.

More information on the [vite|mix]:create classes can be found here: Vite, Mix.

The toolsets offered by these commands can be dynamically registered or modified.

use System\Classes\Asset\BundleManager;

BundleManager::instance()->registerCallback(function (BundleManager $manager) {
    // Register a new bundle named `winterjs`, this will tell Winter to add these packages when a plugin / theme is configured
    $manager->registerBundle('winterjs', [
        // Define the packages required for the bundle
        'winterjs' => '^1.0.1',
        'example-package' => '^6.1.2'
        // Define compiler only requirements, these will only be installed if the listed compiler is in use
        'vite' => [
            'winterjs-vite-adapter' => '^0.1.0'
        ],
        'mix' => [
            'winterjs-mix-adapter' => '^0.6.3'
        ]
    ]);

    // Register a setup handler, this will allow you to generate any files your bundle may require during the config generation
    // The handler will be run in the context of the `mix|vite:create` command, so `$this` allows access to any methods available on that command and parent classes.
    $manager->registerSetupHandler('winterjs', function (string $packagePath, string $packageType) {
        $this->writeFile(
            $packagePath . '/winterjs.config.js',
            File::get(__DIR__ . '/path/to/fixtures/winterjs.config.example.js')
        );
    });

    // Register a scaffold handler, this will allow you to modify config files generated by winter on the fly
    // `contentType` can be: vite, mix, js, css.
    // The handler will be run in the context of the `mix|vite:create` command, so `$this` allows access to any methods available on that command and parent classes.
    $manager->registerScaffoldHandler('winterjs', function (string $contents, string $contentType) {
         return match ($contentType) {
            // Modify the `mix` contents with a heredoc append
            'mix' => $contents . PHP_EOL . <<<JAVASCRIPT
            console.log('winterjs installed');
            JAVASCRIPT,
            // Modify the `vite` contents with a simple append
            'vite' => $contents . PHP_EOL . '// example',
            // Modify the `css` contents with an append from a file
            'css' => $content . PHP_EOL . File::get(__DIR__ . 'css/winterjs.css.fixture'),
            // Replace the entire contents with the contents from a default fixture (getFixture() loads from system fixtures)
            'js' => $this->getFixture('js/default.js.fixture'),
            // Return the contents unmodified
            default => $contents
        };
    });
});

Once a custom bundle has been registered, it will be accessible via the [vite|mix]:create command as an option flag. I.e. with the above:

php artisan vite:create Acme.Plugin --winterjs

The above can also be used to modify the versions of packages to install, e.g.

BundleManager::instance()->registerBundle('tailwind', [
    'tailwindcss' => 'dev-999.999.999',
    '@tailwindcss/forms' => 'dev-999.999.999',
    '@tailwindcss/typography' => 'dev-999.999.999',
]);

NPM Utilities

Winter offers npm utilities that simplify and improve your development experience. These utilities are all accessible via the artisan interface.

Full documentation of the npm utilities can be found here

Copyright © 2024 Winter CMS