vite-plugin-builder
is a Vite plugin designed to simplify the setup of dual compilation for Server-Side Rendering (SSR) and Client-Side Rendering (CSR) in Vite projects. It allows you to build both server and client entry points in a single Vite project, streamlining the development of modern web applications that require both SSR and CSR functionality.
- Dual Compilation: Supports compiling both SSR and CSR in a single project.
- Vite Integration: Designed to work seamlessly with Vite, leveraging its fast build system and hot module replacement.
- SPA (Single-Page Application) Support: Makes it easier to manage the SSR and CSR workflows for modern SPAs.
- TypeScript Support: Written in TypeScript, providing full type safety and better developer experience.
- Minimal Setup: Easy to integrate with minimal configuration required.
To install vite-plugin-builder
in your Vite project, you can use npm or yarn:
npm install vite-plugin-builder --save-dev
or
yarn add vite-plugin-builder --dev
- Install the plugin as a dev dependency (as shown above).
- Import and configure the plugin in your
vite.config.ts
file.
import { defineConfig } from "vite";
import path from "path";
import react from "@vitejs/plugin-react-swc";
import builder from "vite-plugin-builder";
// https://vite.dev/config/
export default defineConfig({
base: "/",
plugins: [
react(),
//Simple Configuration
builder({
serverEntry: "server/main.js",
clientEntry: {
main: "index.html",
},
}),
],
});
This configuration genrate this structures
# Server Out
/dist/app.js
/dist/bin/[name]-[hash].[ext]
/dist/assets/[name]-[hash].[ext]
# Client Out
/dist/public/index.html
/dist/public/assets/[name]-[hash].[ext]
/dist/public/chunks/[name]-[hash].[ext]
The plugin accepts the following options for serverEntry:
import { defineConfig } from "vite";
import path from "path";
import react from "@vitejs/plugin-react-swc";
import builder from "vite-plugin-builder";
// https://vite.dev/config/
export default defineConfig({
base: "/",
plugins: [
react(),
builder({
// Path to the server entry file
serverEntry: "server/main.js",
// (optional) Configuration for the server build
serverConfig: {
define: {
"BUILD.BASE": '"/"',
"BUILD.BASE_API": '"/api"',
"BUILD.STATIC_DIR": '"public"',
"BUILD.SERVER_IP": '"0.0.0.0"',
"BUILD.SERVER_PORT": "3001",
},
},
// (optional) Function to modify the server build config
serverBuild: (viteConfig) => {
return viteConfig;
},
}),
],
});
- Description: The path to the server entry file, which is the main entry point for your server-side application. This is typically a JavaScript or TypeScript file (e.g.,
server/main.js
). - Example:
"server/main.js"
This is an optional configuration object for the server build. It contains detailed options for how the server should be built, including external dependencies, output options, minification, and more.
- Description: A list of external dependencies that should be excluded from the bundle. These dependencies will not be bundled into the server output but will be treated as external to the application.
- Example:
["express", "react"]
ortrue
(to externalize all dependencies).
- Description: A list of dependencies that should not be externalized and should be bundled into the server build. You can specify dependencies using strings, regular expressions, or arrays of them.
- Example:
["lodash", /^react/], true
- Description: Rollup's output configuration that determines how the build is emitted. This includes options such as the output format, file names, and more.
- Example:
output: { format: "esm", entryFileNames: "server.js", chunkFileNames: "chunks/[name]-[hash].js", assetFileNames: "assets/[name].[ext]", }
- Description: Specifies whether the server build should be minified. You can choose between
true
(to minify),"terser"
(to use the Terser minifier), or"esbuild"
(to use the esbuild minifier). - Example:
true
,"terser"
, or"esbuild"
- Description: Specifies the target environment for the server build. Possible values include
"esnext"
,"es2015"
,"es2020"
, or any other valid target value from the esbuild configuration. - Example:
"esnext"
- Description: The output directory where the server build will be placed. All built files, including entry files and assets, will be written here.
- Example:
"dist/server"
- Description: If set to
true
, this option will clean the output directory before building the server. - Example:
true
- Description: Directory for private assets that are not served publicly by the server. This can be used to store internal files or configurations.
- Example:
"private"
- Description: A list of global constants or environment variables to define during the build process. These can be used to customize configurations based on build environments.
- Example:
define: { "BUILD_ENV": '"production"', "API_URL": '"https://api.example.com"', }
- Description: An optional function that allows you to modify the server build configuration before the build starts. This can be used to adjust or extend the configuration dynamically.
- Example:
serverBuild: (config: InlineConfig) => { config.plugins.push(someCustomPlugin()); return config; };
The plugin accepts the following options for clientEntry:
import { defineConfig } from "vite";
import path from "path";
import react from "@vitejs/plugin-react-swc";
import builder from "vite-plugin-builder";
// https://vite.dev/config/
export default defineConfig({
base: "/",
plugins: [
react(),
builder({
serverEntry: "server/main.js",
// (optional) Path to the client entry file
clientEntry: {
main: "index.html",
},
// (optional) Configuration for the client build
clientConfig: {
outDir: "dist/public",
},
// (optional) Function to modify the client build config
clientBuild: (viteConfig) => {
return viteConfig;
},
}),
],
});
- Description: The entry point for the client application. This can be an HTML file or JavaScript entry file that starts the client-side bundle.
- Example:
clientEntry: "index.html";
This is an optional configuration object for the client-side build. It contains detailed options for how the client should be built, including external dependencies, output options, and more.
- Description: A list of external dependencies that should be excluded from the client bundle. These dependencies will not be bundled and will be treated as external to the application.
- Example:
["react", "react-dom"]
or a function that returnstrue
orfalse
.
- Description: Rollup's output configuration that determines how the client build is emitted. This includes options such as the output format, file names, chunk splitting, etc.
- Example:
output: { format: "esm", entryFileNames: "js/[name]-[hash].js", chunkFileNames: "chunks/[name]-[hash].js", assetFileNames: "assets/[name].[ext]", }
- Description: Specifies whether the client build should be minified. You can choose between
true
(to minify),"terser"
(to use the Terser minifier), or"esbuild"
(to use the esbuild minifier). - Example:
true
,"terser"
, or"esbuild"
- Description: Specifies the target environment for the client build. Possible values include
"esnext"
,"es2015"
,"es2020"
, or any other valid target value from the esbuild configuration. - Example:
"esnext"
- Description: The output directory where the client build will be placed. All built files, including entry files, chunks, and assets, will be written here.
- Example:
"dist/client"
- Description: If set to
true
, this option will clean the output directory before building the client. - Example:
true
- Description: An optional function that allows you to modify the client build configuration before the build starts. This can be used to adjust or extend the configuration dynamically.
- Example:
clientBuild: (config: InlineConfig) => { config.plugins.push(someCustomPlugin()); return config; };
The plugin supports several modes that determine how the server and client builds are executed. These modes are configured via the mode
option and include:
"server-first"
: This mode first builds the server and then the client. It is useful for SSR setups where the server needs to be built before the client."client-first"
: This mode first builds the client and then the server. It is useful when the client-side application must be prioritized before SSR."parallel"
: This mode builds both the server and client in parallel. It provides faster builds by running the processes concurrently."skip"
: This mode skips the server build entirely, which is useful when you only want to build the client-side assets.
mode: "parallel";