feat: move from webpack to vite#672
Conversation
|
…i options and useHMR, devtool ima configurations
…to avoid breaking changes
There was a problem hiding this comment.
Pull request overview
This PR migrates the build/dev toolchain from Webpack to Vite across @ima/cli and updates @ima/server to integrate with the Vite dev server (SSR module loading, HTML transforms, stacktrace fixing) while keeping the existing manifest.json-driven resource loading model.
Changes:
- Replaces Webpack config/compiler/dev-server flow in
@ima/cliwith a Vite multi-environment setup (server,legacy,modern) and new manifest/stats generation. - Updates
@ima/serverfactories/templates to work in Vite watch mode (Vite HTML transforms,ssrLoadModule,ssrFixStacktrace) and adjusts runner/polyfill handling. - Removes Webpack-specific loaders/plugins/utilities and updates create-ima-app template defaults to match the Vite-based workflow.
Reviewed changes
Copilot reviewed 61 out of 62 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
| utils/scripts/utils/utils.js | Updates watcher ignore patterns used by local dev scripts. |
| packages/server/polyfill/runner.js | Runner now only loads scripts and triggers hooks (no inlined runtime execution). |
| packages/server/lib/template/devErrorView.ejs | Switches dev error page client script to ESM + Vite HMR event. |
| packages/server/lib/middlewares/memStaticProxyMiddlewareFactory.js | Adjusts when the in-memory static proxy is enabled in watch mode. |
| packages/server/lib/metric/TimingTracker.js | Minor formatting refactor for log marker selection. |
| packages/server/lib/factory/utils/resourcesUtils.js | Adds type="module" to generated script resources. |
| packages/server/lib/factory/utils/tests/snapshots/resourcesUtilsSpec.js.snap | Snapshot updates for script attributes. |
| packages/server/lib/factory/staticPageFactory.js | Makes static render helpers async to await boot config creation. |
| packages/server/lib/factory/serverAppFactory.js | Adds Vite stacktrace fixing and awaits static error page rendering. |
| packages/server/lib/factory/responseUtilsFactory.js | Loads runner polyfill from @ima/server package and transforms HTML via Vite in watch mode. |
| packages/server/lib/factory/hooksFactory.js | Adds Vite stacktrace fixing and awaits async helpers during response lifecycle. |
| packages/server/lib/factory/devUtilsFactory.js | Converts manifest-based server module loading to ssrLoadModule() in watch mode. |
| packages/server/lib/factory/tests/staticPageFactorySpec.js | Updates tests for async static page helpers. |
| packages/server/lib/factory/tests/serverAppFactorySpec.js | Adds watch-mode expectations for stacktrace fixing. |
| packages/server/lib/factory/tests/responseUtilsFactorySpec.js | Updates tests for async processContent. |
| packages/server/lib/factory/tests/snapshots/responseUtilsFactorySpec.js.snap | Snapshot updates for script attributes. |
| packages/server/lib/factory/IMAInternalFactory.js | Makes boot config creation async (awaits language loader) and adapts appFactory usage. |
| packages/server/index.js | Makes appFactory/languageLoader async to support Vite SSR module loading. |
| packages/server/.npmignore | Ensures polyfill/** is published with @ima/server. |
| packages/create-ima-app/template/common/server/app.js | Updates template server middleware (favicon path change). |
| packages/create-ima-app/template/common/package.json | Adds extensionless dependency to the app template. |
| packages/create-ima-app/template/common/app/main.js | Removes Webpack HMR error hook (module.hot). |
| packages/core/src/event/Dispatcher.ts | Formatting-only change in interface extends layout. |
| packages/cli/tsconfig.json | Removes Webpack-related TS type dependencies. |
| packages/cli/src/webpack/utils/findRules.ts | Removes Webpack rule/loader lookup utilities. |
| packages/cli/src/webpack/utils/tests/findRulesSpec.ts | Removes tests for deleted Webpack utilities. |
| packages/cli/src/webpack/plugins/ProgressPlugin.ts | Removes Webpack progress tracking implementation. |
| packages/cli/src/webpack/plugins/ManifestPlugin/options.json | Removes schema for deleted Webpack manifest plugin. |
| packages/cli/src/webpack/plugins/ManifestPlugin/index.ts | Removes Webpack manifest plugin implementation. |
| packages/cli/src/webpack/plugins/GenerateRunnerPlugin/options.json | Removes schema for deleted Webpack runner generator. |
| packages/cli/src/webpack/plugins/GenerateRunnerPlugin/index.ts | Removes Webpack runner generator implementation. |
| packages/cli/src/webpack/loaders/use-server-loader/types.ts | Removes Webpack use server loader types. |
| packages/cli/src/webpack/loaders/use-server-loader/index.ts | Removes Webpack use server loader implementation. |
| packages/cli/src/webpack/loaders/preprocess-loader.ts | Removes Webpack preprocess loader. |
| packages/cli/src/webpack/loaders/null-loader.ts | Removes Webpack null-loader. |
| packages/cli/src/webpack/loaders/js-string-loader.ts | Removes Webpack JS-to-string loader. |
| packages/cli/src/webpack/languages.ts | Removes Webpack language compilation pipeline (replaced by Vite plugin/virtual modules). |
| packages/cli/src/webpack/entries/publicPathEntry.ts | Removes Webpack public path entry. |
| packages/cli/src/webpack/config.ts | Removes the full Webpack configuration generator. |
| packages/cli/src/vite/utils/utils.ts | Introduces Vite-oriented context/config creation and updated defaults. |
| packages/cli/src/vite/plugins/useServerProcessors/stubProcessor.ts | Updates import path for shared UseServerProcessor type. |
| packages/cli/src/vite/plugins/useServerProcessors/serverControllerProcessor.ts | Updates import path for shared UseServerProcessor type. |
| packages/cli/src/vite/plugins/imaUseServerPlugin.ts | Adds Vite plugin replacement for the old Webpack use server loader. |
| packages/cli/src/vite/plugins/imaSkipCssPlugin.ts | Adds Vite plugin to prevent CSS emission in selected environments. |
| packages/cli/src/vite/plugins/imaLanguagesPlugin.ts | Adds virtual-module-based language compilation + HMR for Vite. |
| packages/cli/src/vite/plugins/imaHmrPlugin.ts | Adds custom HMR event emission for dev error view reload behavior. |
| packages/cli/src/vite/languages.ts | Adds shared helpers for generating dictionary TS declarations. |
| packages/cli/src/vite/config.ts | Adds the main Vite config with modern/legacy/server environments and build output structure. |
| packages/cli/src/types.ts | Replaces Webpack types with Vite equivalents and updates CLI/plugin extension points. |
| packages/cli/src/lib/manifest.ts | Adds Vite-based manifest.json generation for dev and build outputs. |
| packages/cli/src/lib/formatStats.ts | Replaces Webpack stats formatting with Vite build output summary formatting. |
| packages/cli/src/lib/compiler.ts | Removes Webpack compiler wrapper utilities. |
| packages/cli/src/lib/cli.ts | Updates config requiring to use Vite utils. |
| packages/cli/src/index.ts | Exposes Vite utilities instead of Webpack utilities. |
| packages/cli/src/dev-server/devServer.ts | Replaces Webpack dev server with a nodemon-restarted Vite dev-server entry. |
| packages/cli/src/dev-server/createViteDevServer.ts | Adds factory to start Vite in middleware mode + error overlay/static endpoints. |
| packages/cli/src/commands/prerender.ts | Updates environment resolution import to Vite utils. |
| packages/cli/src/commands/dev.ts | Replaces Webpack watch + dev server with nodemon-based Vite dev server startup. |
| packages/cli/src/commands/build.ts | Replaces Webpack build with Vite builder + manifest generation + Vite stats output. |
| packages/cli/package.json | Swaps Webpack deps for Vite/Rollup/Babel polyfill tooling. |
| package.json | Adds a vite override pin (beta) for the repo. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
| @@ -132,6 +133,7 @@ function _prepareSources(manifest, language) { | |||
| esScripts: buildResources('client.es', jsFilter, { | |||
| async: '', | |||
| crossorigin: 'anonymous', | |||
| type: 'module', | |||
| }), | |||
There was a problem hiding this comment.
This is already listed as a TODO and will be addressed in followup PRs.
| path.resolve(path.join(__dirname, '../build/static/public/favicon.ico')) | ||
| ) | ||
| ) | ||
| .use(favicon(path.resolve(path.join(__dirname, '../app/public/favicon.ico')))) |
There was a problem hiding this comment.
This is already listed as a TODO and will be addressed in followup PRs.
| "chalk": "4.1.2", | ||
| "chokidar": "^4.0.3", | ||
| "cli-progress": "^3.12.0", | ||
| "compression-webpack-plugin": "^11.1.0", | ||
| "copy-webpack-plugin": "^13.0.1", | ||
| "core-js": "^3.46.0", | ||
| "css-loader": "^7.1.2", | ||
| "css-minimizer-webpack-plugin": "^7.0.2", | ||
| "ejs": "^3.1.10", | ||
| "core-js-pure": "^3.48.0", | ||
| "express-static-gzip": "^3.0.0", | ||
| "fork-ts-checker-webpack-plugin": "^9.1.0", | ||
| "extensionless": "^2.0.6", | ||
| "globby": "11.1.0", | ||
| "kill-port": "^1.6.1", | ||
| "less": "^4.4.2", | ||
| "less-loader": "^12.3.0", | ||
| "less-plugin-glob": "^3.0.0", | ||
| "mini-css-extract-plugin": "^2.9.4", | ||
| "nodemon": "^3.1.11", | ||
| "open-editor": "5.1.0", | ||
| "postcss": "^8.5.6", | ||
| "postcss-flexbugs-fixes": "5.0.2", | ||
| "postcss-loader": "^8.2.0", | ||
| "postcss-preset-env": "^10.4.0", | ||
| "preprocess": "^3.2.0", | ||
| "pretty-bytes": "^5.6.0", | ||
| "pretty-ms": "^7.0.1", | ||
| "react-refresh": "^0.18.0", | ||
| "schema-utils": "4.3.3", | ||
| "source-map-loader": "^5.0.0", | ||
| "swc-loader": "0.2.6", | ||
| "webpack": "^5.102.1", | ||
| "webpack-dev-middleware": "^7.4.5", | ||
| "webpack-hot-middleware": "^2.26.1", | ||
| "vite": "^8.0.0", | ||
| "vite-plugin-compression2": "^2.5.1", | ||
| "vite-plugin-static-copy": "^3.3.0", | ||
| "yargs": "^18.0.0" | ||
| }, | ||
| "devDependencies": { | ||
| "@types/cli-progress": "^3.11.6", | ||
| "@types/ejs": "^3.1.5", | ||
| "@types/express": "^5.0.5" |
There was a problem hiding this comment.
This is already listed as a TODO and will be addressed in followup PRs.
| // compression plugin customizes the applyToEnvironment method internally | ||
| ctx.command === 'build' && imaConfig.compress | ||
| ? compression({ | ||
| exclude: /^server\/(?!runner\.js$)/, |
There was a problem hiding this comment.
Do we still need to exclude this?
fix: remove broken sourcemaps, fix esm build, remove extensionless hacks
feat: migrate from @swc/core to rolldown and go pure ESM with all pac…
The core IMA.js build tooling in
@ima/clihas been migrated from Webpack to Vite.How to test locally
npm run build(@ima/storybook-integrationwill fail as it is not yet migrated to Vite and it is using old imports from@ima/cli, but this does not affect basiccreate-ima-app)npm pack -w @ima/cli -w @ima/core -w @ima/server -w @ima/dev-utils -w @ima/error-overlay -w @ima/helpers -w @ima/hmr-client -w @ima/react-page-renderer -w @ima/storybook-integration -w @ima/testing-library@ima/*deps to the packed tarballs:npm link -w create-ima-appnpx create-ima-app <dir> [--typescript]to create a fresh create-ima-app project with ViteImpact on IMA.js application developers
Breaking changes in
ima.config.jswebpack(config, ctx, imaConfig)hookvite(config, ctx, imaConfig)hookViteConfigWithEnvironmentsinstead of a WebpackConfigurationswc(config, ctx)hookswcVendor(config, ctx)hook@rollup/plugin-babelin thelegacyenvironmentwebpackAliasesoptionviteAliasesoptionsourceMaps: 'cheap-module-source-map'(and other Webpack devtool strings)sourcemap: true | 'inline' | 'hidden'truefor normal source mapstransformVendorPathsoptionexperiments.cssoptionwatchOptions(WebpackWatcherOptions)watchOptions(Chokidar/RollupWatchOptions)prepareConfigurations(contexts[])receives an array of contexts (one per compiler)prepareConfigurations(context)receives a single contextBreaking changes for
ImaCliPluginauthorsplugin.webpack(config, ctx, imaConfig)plugin.vite(config, ctx, imaConfig)plugin.prepareConfigurations(contexts[])plugin.prepareConfigurations(context)— single context, not an arrayRemoved
ima devCLI flags--legacy/--forceLegacy— Vite always serves modern bundles for dev command without an option to force legacy build; if you need this, useima build && ima start--writeToDisk— no longer applicable; Vite always serves from memory during devKey Changes
New Vite configuration (
packages/cli/src/vite/)This is the heart of the PR. The Webpack config has been deleted and replaced by an equivalent Vite-with-Environments setup.
vite/config.ts(renamed fromwebpack/config.ts)modern(client ES2024),legacy(client ES2018 + Babel polyfills),server(Node 18 SSR).vite/utils/utils.ts(renamed fromwebpack/utils/utils.ts)createViteConfig()replacescreateWebpackConfig().createContexts()is simplified: instead of an array of per-compiler contexts it returns a single unified context.vite/languages.tswebpack/languages.ts.vite/plugins/Dev server architecture (
packages/cli/src/dev-server/)The dev server has been redesigned. The old model ran Webpack dev server and the user server in separate processes. The new model is using the same process for both environments since we need to pass
ViteDevServerinstance to@ima/server.dev.ts—ima devnow starts nodemon watchingserver/and executesdevServer.jsas the nodemon entry point.devServer.ts(rewritten) — standalone nodemon-supervised entry. Creates the Vite HMR server, attaches it toglobal.$IMA_SERVER.viteDevServer, thenimport()s the app'sserver/server.js. On changes inserver/, nodemon restarts the whole process (including Vite HMR server and IMA server)createViteDevServer.ts(new) — creates the Vite dev server, most of the code moved here fromdevServer.tsTODOs
This is an initial PR and there will be more to follow, which should address these bullet-points.
npm run devis glitching a bit during the load (especially for bigger apps)client.esis not possible to use as environment name in vite (due to the dot), maybe we should rename these environments completely toserver,legacy,modern?window.__IMA_HMR?There is no guarantee of scripts execution orderI think I misunderstood how this works$IMA.i18nnot being initialized when the app needs itpostcss-flexbugs-fixesandpostcss-preset-env?runner.ejsto @ima/server, it is no longer being minified in production build@ima/storybook-integrationto Viteapp/public/favicon.ico(source code instead of build)?ima dev --forceLegacy(maybeima start --forceLegacy?)createCacheKeyfunction in https://github.com/seznam/ima/blob/master/packages/cli/src/webpack/utils/utils.ts#L100-L142 - it is not being used anywhere, or is it?cli-progress(and@types/cli-progress) in @ima/clinpm run devwith https - maybe review how we startup the dev server, should we use usersserver.jsto give more flexibility how its run? (Just the way it used to be)Old bugs that came to haunt us:
static-contentand added workarounds. Now it is everywhere as Vite is using ESM on server-side. As a workaround, we are definingssr.noExternal: [/@ima/.*/]to bundle the @ima packages and make them work.