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.
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
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;
},
}),
],
});
serverEntry: string
server/main.js
)."server/main.js"
serverConfig
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.
serverConfig.external
["express", "react"]
or true
(to externalize all dependencies).serverConfig.noExternal
["lodash", /^react/], true
serverConfig.output
output: {
format: "esm",
entryFileNames: "server.js",
chunkFileNames: "chunks/[name]-[hash].js",
assetFileNames: "assets/[name].[ext]",
}
serverConfig.minify
true
(to minify), "terser"
(to use the Terser minifier), or "esbuild"
(to use the esbuild minifier).true
, "terser"
, or "esbuild"
serverConfig.target
"esnext"
, "es2015"
, "es2020"
, or any other valid target value from the esbuild configuration."esnext"
serverConfig.outDir
"dist/server"
serverConfig.emptyOutDir: boolean
true
, this option will clean the output directory before building the server.true
serverConfig.privateDir
"private"
serverConfig.define
define: {
"BUILD_ENV": '"production"',
"API_URL": '"https://api.example.com"',
}
serverBuild
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;
},
}),
],
});
clientEntry
clientEntry: "index.html";
clientConfig
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.
clientConfig.externa
["react", "react-dom"]
or a function that returns true
or false
.clientConfig.output
output: {
format: "esm",
entryFileNames: "js/[name]-[hash].js",
chunkFileNames: "chunks/[name]-[hash].js",
assetFileNames: "assets/[name].[ext]",
}
clientConfig.minify
true
(to minify), "terser"
(to use the Terser minifier), or "esbuild"
(to use the esbuild minifier).true
, "terser"
, or "esbuild"
clientConfig.target
"esnext"
, "es2015"
, "es2020"
, or any other valid target value from the esbuild configuration."esnext"
clientConfig.outDir
"dist/client"
clientConfig.emptyOutDir
true
, this option will clean the output directory before building the client.true
clientBuild
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";