- Issue created by @wotnak
- πΊπΈUnited States mortona2k Seattle
I found some examples:
Using Vite module
https://github.com/ChrisScrumping/drupal-vite-alpine-theme/tree/main
https://github.com/dcavins/vite_drupal_block_example/tree/mainNot using Vite module
https://github.com/sinyayadynya/tailvite
https://github.com/segovia94/drupal-vite-poc
https://github.com/almunnings/drupal-vite-bootstrap - π¬π§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/mainI 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 adist
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/
) asoutput.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 additionaldist/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.