chore: upgrade to vite 6 (#14363)
Upgrades the frontend toolchain to Vite 6 and tidies up the build config along the way. Behavior is unchanged for end users; this is dev/build infra. ## What changed - `vite` 5.4 → 6.4, `@vitejs/plugin-vue` → 5.2, `vite-plugin-ruby` → 5.2 (with matching `vite_rails`/`vite_ruby` gem bumps). - Dropped the `vite-node` 2.0.1 pnpm override — no longer needed now that vitest 3 runs on Vite 6 directly. - Split the single `vite.config.ts` into: - `vite.config.ts` (app), `vite.lib.config.ts` (SDK), `vite.shared.ts` (aliases / Vue options), `vitest.config.ts` (tests). - `pnpm build:sdk` now selects the SDK config explicitly instead of branching on `BUILD_MODE=library`. SDK output path is unchanged (`public/packs/js/sdk.js`). No changes needed to Docker images, deployment scripts, or CI — Node 24 and pnpm 10 are already past Vite 6's floor, and the rake `assets:precompile` hook still drives the SDK build via `pnpm`. ## How to test - `pnpm dev` and verify the dashboard, widget, and survey routes load and HMR works. - Load a Chatwoot site widget on a test page and confirm `sdk.js` is served and the widget mounts. - `RAILS_ENV=production bundle exec rake assets:precompile` and confirm `public/packs/js/sdk.js` plus the rest of the manifest are produced. - `pnpm test` for the JS suite. --------- Co-authored-by: Sivin Varghese <64252451+iamsivin@users.noreply.github.com> Co-authored-by: Sony Mathew <2040199+sony-mathew@users.noreply.github.com>
This commit is contained in:
114
vite.config.ts
114
vite.config.ts
@@ -1,50 +1,11 @@
|
||||
/// <reference types="vitest" />
|
||||
|
||||
/**
|
||||
What's going on with library mode?
|
||||
|
||||
Glad you asked, here's a quick rundown:
|
||||
|
||||
1. vite-plugin-ruby will automatically bring all the entrypoints like dashbord and widget as input to vite.
|
||||
2. vite needs to be in library mode to build the SDK as a single file. (UMD) format and set `inlineDynamicImports` to true.
|
||||
3. But when setting `inlineDynamicImports` to true, vite will not be able to handle mutliple entrypoints.
|
||||
|
||||
This puts us in a deadlock, now there are two ways around this, either add another separate build pipeline to
|
||||
the app using vanilla rollup or rspack or something. The second option is to remove sdk building from the main pipeline
|
||||
and build it separately using Vite itself, toggled by an ENV variable.
|
||||
|
||||
`BUILD_MODE=library bin/vite build` should build only the SDK and save it to `public/packs/js/sdk.js`
|
||||
`bin/vite build` will build the rest of the app as usual. But exclude the SDK.
|
||||
|
||||
We need to edit the `asset:precompile` rake task to include the SDK in the precompile list.
|
||||
*/
|
||||
import { defineConfig } from 'vite';
|
||||
import ruby from 'vite-plugin-ruby';
|
||||
import path from 'path';
|
||||
import vue from '@vitejs/plugin-vue';
|
||||
import { aliases, vueOptions } from './vite.shared';
|
||||
import yaml from '@rollup/plugin-yaml';
|
||||
|
||||
const isLibraryMode = process.env.BUILD_MODE === 'library';
|
||||
const isTestMode = process.env.TEST === 'true';
|
||||
|
||||
const vueOptions = {
|
||||
template: {
|
||||
compilerOptions: {
|
||||
isCustomElement: tag => ['ninja-keys'].includes(tag),
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
let plugins = [ruby(), vue(vueOptions), yaml()];
|
||||
|
||||
if (isLibraryMode) {
|
||||
plugins = [];
|
||||
} else if (isTestMode) {
|
||||
plugins = [vue(vueOptions), yaml()];
|
||||
}
|
||||
|
||||
export default defineConfig({
|
||||
plugins: plugins,
|
||||
plugins: [ruby(), vue(vueOptions), yaml()],
|
||||
css: {
|
||||
preprocessorOptions: {
|
||||
scss: {
|
||||
@@ -52,74 +13,5 @@ export default defineConfig({
|
||||
},
|
||||
},
|
||||
},
|
||||
build: {
|
||||
rollupOptions: {
|
||||
output: {
|
||||
// [NOTE] when not in library mode, no new keys will be addedd or overwritten
|
||||
// setting dir: isLibraryMode ? 'public/packs' : undefined will not work
|
||||
...(isLibraryMode
|
||||
? {
|
||||
dir: 'public/packs',
|
||||
entryFileNames: chunkInfo => {
|
||||
if (chunkInfo.name === 'sdk') {
|
||||
return 'js/sdk.js';
|
||||
}
|
||||
return '[name].js';
|
||||
},
|
||||
}
|
||||
: {}),
|
||||
inlineDynamicImports: isLibraryMode, // Disable code-splitting for SDK
|
||||
},
|
||||
},
|
||||
lib: isLibraryMode
|
||||
? {
|
||||
entry: path.resolve(__dirname, './app/javascript/entrypoints/sdk.js'),
|
||||
formats: ['iife'], // IIFE format for single file
|
||||
name: 'sdk',
|
||||
}
|
||||
: undefined,
|
||||
},
|
||||
resolve: {
|
||||
alias: {
|
||||
vue: 'vue/dist/vue.esm-bundler.js',
|
||||
components: path.resolve('./app/javascript/dashboard/components'),
|
||||
next: path.resolve('./app/javascript/dashboard/components-next'),
|
||||
v3: path.resolve('./app/javascript/v3'),
|
||||
dashboard: path.resolve('./app/javascript/dashboard'),
|
||||
helpers: path.resolve('./app/javascript/shared/helpers'),
|
||||
shared: path.resolve('./app/javascript/shared'),
|
||||
survey: path.resolve('./app/javascript/survey'),
|
||||
widget: path.resolve('./app/javascript/widget'),
|
||||
assets: path.resolve('./app/javascript/dashboard/assets'),
|
||||
},
|
||||
},
|
||||
test: {
|
||||
environment: 'jsdom',
|
||||
include: ['app/**/*.{test,spec}.?(c|m)[jt]s?(x)'],
|
||||
coverage: {
|
||||
reporter: ['lcov', 'text'],
|
||||
include: ['app/**/*.js', 'app/**/*.vue'],
|
||||
exclude: [
|
||||
'app/**/*.@(spec|stories|routes).js',
|
||||
'**/specs/**/*',
|
||||
'**/i18n/**/*',
|
||||
],
|
||||
},
|
||||
globals: true,
|
||||
outputFile: 'coverage/sonar-report.xml',
|
||||
pool: 'threads',
|
||||
poolOptions: {
|
||||
threads: {
|
||||
singleThread: false,
|
||||
},
|
||||
},
|
||||
server: {
|
||||
deps: {
|
||||
inline: ['tinykeys', '@material/mwc-icon'],
|
||||
},
|
||||
},
|
||||
setupFiles: ['fake-indexeddb/auto', 'vitest.setup.js'],
|
||||
mockReset: true,
|
||||
clearMocks: true,
|
||||
},
|
||||
resolve: { alias: aliases },
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user