vite-plugin-builder
Version:
A Vite plugin that creates a dual compilation setup for SSR (Server-Side Rendering) and CSR (Client-Side Rendering) to build both server and client entry points in one project.
298 lines (227 loc) • 10.8 kB
Markdown
# vite-plugin-builder
[](https://opensource.org/licenses/MIT)
[](https://travis-ci.org/yracnet/vite-plugin-builder)
`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.
## Features
- **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.
## Installation
To install `vite-plugin-builder` in your Vite project, you can use npm or yarn:
```bash
npm install vite-plugin-builder --save-dev
```
or
```bash
yarn add vite-plugin-builder --dev
```
## Usage
### Basic Setup
1. Install the plugin as a dev dependency (as shown above).
2. Import and configure the plugin in your `vite.config.ts` file.
```ts
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
```bash
# 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]
```
### Plugin Server Options
The plugin accepts the following options for serverEntry:
```ts
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;
},
}),
],
});
```
### Server Configuration Options
#### `serverEntry: string`
- **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"`
#### `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`
- **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"]` or `true` (to externalize all dependencies).
##### `serverConfig.noExternal`
- **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`
##### `serverConfig.output`
- **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**:
```javascript
output: {
format: "esm",
entryFileNames: "server.js",
chunkFileNames: "chunks/[name]-[hash].js",
assetFileNames: "assets/[name].[ext]",
}
```
##### `serverConfig.minify`
- **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"`
##### `serverConfig.target`
- **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"`
##### `serverConfig.outDir`
- **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"`
##### `serverConfig.emptyOutDir: boolean`
- **Description**: If set to `true`, this option will clean the output directory before building the server.
- **Example**: `true`
##### `serverConfig.privateDir`
- **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"`
##### `serverConfig.define`
- **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**:
```javascript
define: {
"BUILD_ENV": '"production"',
"API_URL": '"https://api.example.com"',
}
```
#### `serverBuild`
- **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**:
```javascript
serverBuild: (config: InlineConfig) => {
config.plugins.push(someCustomPlugin());
return config;
};
```
### Plugin Client Options
The plugin accepts the following options for clientEntry:
```ts
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;
},
}),
],
});
```
### Client Configuration Options
#### `clientEntry`
- **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**:
```javascript
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`
- **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 returns `true` or `false`.
##### `clientConfig.output`
- **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**:
```javascript
output: {
format: "esm",
entryFileNames: "js/[name]-[hash].js",
chunkFileNames: "chunks/[name]-[hash].js",
assetFileNames: "assets/[name].[ext]",
}
```
##### `clientConfig.minify`
- **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"`
##### `clientConfig.target`
- **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"`
##### `clientConfig.outDir`
- **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"`
##### `clientConfig.emptyOutDir`
- **Description**: If set to `true`, this option will clean the output directory before building the client.
- **Example**: `true`
#### `clientBuild`
- **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**:
```javascript
clientBuild: (config: InlineConfig) => {
config.plugins.push(someCustomPlugin());
return config;
};
```
## Mode Options
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.
### Example:
```ts
mode: "parallel";
```