Example configurations/starting points

Created on 21 March 2023, over 1 year ago
Updated 26 June 2024, 5 months ago

Problem/Motivation

Using the module requires configuring assets building with vitejs as well as integration between the module and vite dev server. While required steps are described on the module page β†’ some practical examples/starting points could be useful and make getting started with the module easier.

Proposed resolution

Implement example configurations/starting points for some basic use cases.
For example:
- custom theme with scss and typescript support (maybe as a stater-kit theme β†’ ),
- custom decoupled block with vue/react app,
- ...

πŸ“Œ Task
Status

Active

Version

1.0

Component

Documentation

Created by

πŸ‡΅πŸ‡±Poland wotnak

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

Comments & Activities

  • Issue created by @wotnak
  • πŸ‡¬πŸ‡§United Kingdom chrisscrumping

    I have archived this repo now as it was an experiment and was created pre this module supporting Vite 5
    https://github.com/ChrisScrumping/drupal-vite-alpine-theme/tree/main

    I might bring it back at some point but no time to update at the moment.

    I have Vite 5 and components working great now inside my theme folder however I am also interested in the recommended way to use this module with components in the theme and modules.

    Are you supposed to have several instances of vite or one instance that compiles everything across modules and theme folders?

  • πŸ‡¦πŸ‡ΉAustria mvonfrie

    @ChrisScrumping even if your module is not up to date, it still looks helpful. What I'm trying to achieve at the moment is a Drupal site with two themes and one module all using Vite together. That would mean having vite.config.js in the repo root instead of the theme's or module's folder, especially as it would be much easier to run only a single Vite dev server and not multiple ones in DDEV.

  • πŸ‡¬πŸ‡§United Kingdom chrisscrumping

    @mvonfire Glad its helpful, although I do it quite differently now.

    Now this module supports SDC and we have the https://www.drupal.org/project/storybook β†’ module my setup is much simpler. Although yes my Vite config is in the theme folder as per the docs https://git.drupalcode.org/project/vite/-/blob/1.x/README.md

    My vite config looks like

    import {defineConfig} from 'vite'
    import postcssNesting from 'postcss-nesting';
    import postcssImport from 'postcss-import';
    import postcssCustomMedia from 'postcss-custom-media';
    import glob from 'glob';
    
    export default defineConfig({
      build: {
        manifest: true,
        rollupOptions: {
          input: [
            'assets/css/main.pcss',
            ...glob.sync('components/**/**/*.pcss'),
          ]
        }
      },
      css: {
        postcss: {
          plugins: [
            postcssNesting,
            postcssImport,
            postcssCustomMedia
          ],
        },
      },
      server: {
        host: '192.168.64.100',
        port: 5173,
      },
    })
    

    Which means all the component-style.pcss files compile to .css and Drupal takes care of the rest and I don't need gulp.

    Not sure if it would work the same moving Vite to the root but it might/should so long as the paths are correct and the Vite module can find the devServerUrl?

  • πŸ‡ΊπŸ‡ΈUnited States mortona2k Seattle

    I have been thinking about how to include modules and theme code.

    Considering moving vite to the project root.

    Also want to look into foxy: https://www.drupal.org/project/foxy β†’

  • πŸ‡¦πŸ‡ΉAustria mvonfrie

    I spent over 8 hours to get Vite working in the project root. It is not possible, at least not yet. Maybe it will be in the future with the new Vite 6 Environment API.

    <root> means the Vite project root, not the Drupal one. By default Vite generates the output in a dist folder, which would be in <root>/dist/. Even if I change it to <root>/web/dist/ to have the generated files in Drupal's web-root I have no chance to get the files where they need to be (<root>/web/[modules|themes]/custom/[module_name|theme_name]/dist/) as output.entryFileNames, output.assetFileNames etc. must not contain ../ to get out of the dist folder.

    error during build:
    Invalid pattern "../themes/custom/theme_name/components/title/style" for "output.entryFileNames", patterns can be neither absolute nor relative paths. If you want your files to be stored in a subdirectory, write its name without a leading slash like this: subdirectory/pattern.

  • πŸ‡¬πŸ‡§United Kingdom chrisscrumping

    @mvonfire Annoying, maybe webpack would be more configurable in this instance? This theme uses webpack https://git.drupalcode.org/project/prototype but again this is a single theme so might not be that helpful in your case.

    Would be good if we can support all themes and modules from a single Vite server, as you say this will hopefully be possible with Vite 6.

  • πŸ‡¦πŸ‡ΉAustria mvonfrie

    @ChrisScrumping I have a working webpack configuration in other projects. What I don't like with webpack is, that it builds dev and prod outputs into the same folder & files, which often leads to stupid git diffs (especially during development, even if you don't commit the changes). When you commit only prod builds, during development almost all generated files appear as changed because for prod they get minified and for dev not.

    Of course there should be a configuration to create dist/style.css as non-minified during dev and prod build and an additional dist/style.min.css during prod build. But then still you do not have solved the issue which file Drupal should take (style.css or style.min.css) right now because the library definition is static. This is where the Vite module comes in very handy.

    And integrating webpack with storybook might be another topic...

  • πŸ‡¦πŸ‡ΉAustria mvonfrie

    I found a solution using Yarn workspaces. In addition I'm using Typescript.

    In each module/theme you need the following files:

    package.json
    Eventually it makes sense to remove a common prefix from [module_or_theme_name] in the package.json. If i.e. all modules start with myproject_ like myproject_ui I would name the package @myproject/ui. The package names just need to be unique though.

    {
      "name": "@myproject/[module_or_theme_name]",
      "type": "module",
      "engines": {
        "node": "^20.14",
        "yarn": "^4.3"
      },
      "private": true,
      "scripts": {
        "dev": "vite",
        "build": "tsc && vite build"
      },
      "devDependencies": {
        "@rollup/plugin-node-resolve": "^15.2.3",
        "@types/node": "^20.14.8",
        "fast-glob": "^3.3.2",
        "typescript": "^5.2.2",
        "vite": "^5.3.1"
      }
    }
    

    vite.config.ts

    in the vite config the server part is important, so we skip the rest of the file here for simplicity:

    export default defineConfig({
      server: {
        host: true, // "Set this to 0.0.0.0 or true to listen on all addresses, including LAN and public addresses." --> Needed for DDEV.
        port: xyz, // Every module/theme needs its own port, and all of them must be exposed from DDEV or Docker in general. We start with the default port 5173.
        strictPort: true // Ensure that every module/theme uses it's own port. "Set to true to exit if port is already in use, instead of automatically trying the next available port." --> If something doesn't work/some ports are already in use lets fail here as our dev servers would not be reachable.
      }
    })
    

    tsconfig.json
    The tsconfig file for the module/theme (Vite application). To not duplicate all the settings, compiler options etc. we extend it from a base tsconfig in the project root.

    Here the important part is the includes.

    {
      "extends": "../../../../tsconfig.base",
      "include": [
        "components/**/*",
        "src/**/*"
      ],
      "references": [
        {
          "path": "tsconfig.node.json"
        }
      ]
    }
    

    tsconfig.node.json
    The tsconfig file for the Vite config compilation step (this is only using for compiling the vite.config.ts).

    {
      "compilerOptions": {
        "composite": true,
        "module": "ESNext",
        "moduleResolution": "Node",
        "allowSyntheticDefaultImports": true
      },
      "include": ["vite.config.ts"]
    }
    

    Root package.json
    The Yarn workspace definition.

    {
      "name": "@myproject/workspace",
      "type": "module",
      "packageManager": "yarn@4.3.0",
      "engines": {
        "node": "^20.14",
        "yarn": "^4.3"
      },
      "private": true,
      "scripts": {
        "dev": "yarn workspaces foreach -Rpi --topological-dev --from '@myproject/*' run dev",
        "build": "yarn workspaces foreach -Rp --topological-dev --from '@myproject/*' run build"
      },
      "workspaces": [
        "web/modules/custom/*",
        "web/themes/custom/*"
      ]
    }
    

    In the global dev and build scripts we run the corresponding scripts of all workspaces recursively (-R) in parallel (-p). We restrict them to a scope (--from '@myproject/*', the root package will be automatically excluded as Yarn detects that it would lead to an endless recursion). With --topological-dev Yarn will only run the command after all workspaces that it depends on through the dependencies and devDependencies field have successfully finished executing. This way the themes for example can depend on any of the modules.

    In the dev script we additionally print the lines from the output as it receives them with the -i option. Without it (as in the build script) Yarn buffer the output from each process and print the resulting buffers only after their source processes have exited which makes more sense for scripts executed by a CI pipeline for example.

Production build 0.71.5 2024