Add support for using vite from the root of the project

Created on 7 March 2025, 2 months ago

Problem/Motivation

Currently, the module operates with the assumption that vite is configured per module/theme and resolves paths relative to the module/theme dir. While it works fine, in some cases it would be more convenient to create a single vite configuration for the entire project (instead of separate configs for each module/theme) and place it in the project root.

Proposed resolution

Add new viteRoot configuration option (that will default to theme/module dir) and resolve paths relative to it.

Feature request
Status

Active

Version

1.0

Component

Code

Created by

🇵🇱Poland wotnak

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

  • Issue created by @wotnak
  • 🇵🇱Poland wotnak

    Pushed initial implementation of the proposed solution to MR !22.

    Still needs more testing, some cleanup, docs and automated test.

    It adds a new `viteRoot` config option that defaults to extension directory but can be set to for example, project root. If the value starts with /, then it is resolved relative to drupal root, otherwise relative to the extension dir.
    The vite root path is then used to resolve path to manifest (configured manifest path is treated as relative to vite root) and paths to assets.

    For example, to use setup with vite configured in project root and dist files generated to libraries dir (web/libraries/dist) we just need to set vite root to /.. and manifest path to web/libraries/dist/.vite/manifest.json.

    /vite.config.js
    /web/...
    /web/themes/custom/my_theme/...
    /web/themes/custom/my_theme/ts/script.ts
    
    # settings.php
    $settings['vite']['viteRoot'] = '/..';
    $settings['vite']['manifest'] = 'web/libraries/dist/.vite/manifest.json';
    
    # web/themes/custom/my_theme/my_theme.info.yml
    ...
    vite:
      enableInAllLibraries: true
    
    # web/themes/custom/my_theme/my_theme.libraries.yml
    my_library:
      js:
        ts/script.ts: {}
    
  • 🇵🇱Poland wotnak

    Added another config option `distPath` that should be set to dist directory path relative to vite root, the same as the build.outDir in vite config. The `manifest` config option is now deprecated in favor of `distPath` since vite manifest file is always in the same location in the dist directory.

    Tests currently pass locally but fail in gitlab ci because of the symlinked module source. Will probably need to replace `realpath` usage when resolving paths to skip resolving symlinks.

  • 🇵🇱Poland wotnak

    Recent changes:

    • removed use of realpath function and tests are now passing also in symlinked environment
    • renamed distPath config option to distDir to more closely match Vite's build.outDir config option

    Also updated IS to match the proposed resolution to the current approach and to add remaining tasks.

    I will work on adding tests, but otherwise this should be ready for a review.

  • First commit to issue fork.
  • Pipeline finished with Success
    11 days ago
    Total: 194s
    #483995
  • Tested the changes in a real project with Vite configured in the project root (originally project has multiple webpack setups)
    Seems to work as expected. All entries are properly attached to the page.

    I see the issue is assigned, but I tried to write a test anyway and pushed it in a separate branch just in case.
    One issue I came across. \Drupal\Tests\vite\ViteKernelTestBase::assertLibraryAssetPath expects the file to always be relative to the module root, even if viteRoot is outside the module. That works for libraries since \Drupal\vite\Vite::resolveDistAssetPath makes a library file path relative to the module. But, for components, files are relative to the core directory.
    So I've added an optional parameter for assertLibraryAssetPath to indicate the viteRoot path.

    I think it would be nicer if all paths were absolute, unless I don't see a reason why paths should be relative. Especially with vite in the project root, the links in the HTML look weird, because there is a lot of .. in the path in that case.

  • Pipeline finished with Success
    about 8 hours ago
    Total: 152s
    #493186
  • Status changed to Needs review about 7 hours ago
  • I noticed that @vite/client resolved with the absolute path to the vite contrib module if the vite root is globally configured to another path. For example, if Vite root is modules/custom, the generated link is {devServerUrl}/var/www/html/web/modules/contrib/vite/@vite/client.
    Funny thing, if any CSS is included in the page, it will import the @vite/client itself, so the HMR will work anyway in that case.
    Fixed that in MR !25
    I guess this needs review now.

Production build 0.71.5 2024