Configure Vite on your Nx workspace
It is recommended that you use the @nx/vite:configuration
generator to set up Vite for your new or existing projects.
The @nx/vite
plugin generators take care of configuring Vite for you. However, you may need to set up Vite manually in some cases. This guide explains how you can configure Vite in your Nx workspace.
TypeScript paths
You need to use the nxViteTsPaths()
plugin to make sure that your TypeScript paths are resolved correctly in your monorepo.
Framework plugins
If you are using React, you need to use the @vitejs/plugin-react
plugin. If you're using Vue, you need to use the @vitejs/plugin-vue
plugin.
Set the root
path
Make sure to set the root: __dirname,
property on your config object. This is necessary to make sure that the paths are resolved correctly in your monorepo.
Set the build outDir
path
Make sure you set the outDir
property on your build
object. Set the path as relative to the workspace root, so for example if your project is located in apps/my-app
, set the outDir
to ../../dist/apps/my-app
. If your project is located in my-app
, set the outDir
to ../dist/my-app
, etc.
DTS plugin
If you are building a library, you need to use the vite-plugin-dts
plugin to generate the .d.ts
files for your library.
Skip diagnostics
If you are building a library, you can set the skipDiagnostics
option to true
to speed up the build. This means that type diagnostic will be skipped during the build process. However, if there are some files with type errors which interrupt the build process, these files will not be emitted and .d.ts
declaration files will not be generated.
If you choose to skip diagnostics, here is what your 'vite-plugin-dts'
plugin setup will look like:
1...
2import dts from 'vite-plugin-dts';
3import { join } from 'path';
4...
5...
6export default defineConfig({
7 plugins: [
8 ...,
9 dts({
10 entryRoot: 'src',
11 tsConfigFilePath: join(__dirname, 'tsconfig.lib.json'),
12 skipDiagnostics: true,
13 }),
14
Do not skip diagnostics
If you are building a library, and you want to make sure that all the files are type checked, you can set the skipDiagnostics
option to false
to make sure that all the files are type checked. This means that type diagnostic will be run during the build process.
If you choose to enable diagnostics, here is what your 'vite-plugin-dts'
plugin setup will look like:
1...
2import dts from 'vite-plugin-dts';
3...
4...
5export default defineConfig({
6 plugins: [
7 ...,
8 dts({
9 root: '../../',
10 entryRoot: 'libs/my-lib/src',
11 tsConfigFilePath: 'libs/my-lib/tsconfig.lib.json',
12 include: ['libs/my-lib/src/**/*.ts'],
13 outputDir: 'dist/libs/my-lib',
14 skipDiagnostics: false,
15 }),
16
You can read more about the configuration options in the vite-plugin-dts
plugin documentation.
Copying assets
If you have assets outside of publicDir
that need to be copied the output folder, then you can use nxCopyAssetsPlugin
from @nx/vite
.
1/// <reference types='vitest' />
2import { defineConfig } from 'vite';
3// ...
4import { nxCopyAssetsPlugin } from '@nx/vite/plugins/nx-copy-assets.plugin';
5
6export default defineConfig({
7 root: __dirname,
8 cacheDir: '../../node_modules/.vite/libs/testlib',
9
10 plugins: [
11 nxViteTsPaths(),
12 nxCopyAssetsPlugin(['*.md']),
13 dts({
14 entryRoot: 'src',
15 tsconfigPath: path.join(__dirname, 'tsconfig.lib.json'),
16 }),
17 ],
18 // ...
19});
20
For testing
If you're using vitest
, make sure your test
object in your vite.config.ts
file looks like this:
1...
2 test: {
3 globals: true,
4 cache: {
5 dir: '../node_modules/.vitest/<project-root>',
6 },
7 environment: 'jsdom',
8 include: ['src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
9 reporters: ['default'],
10 coverage: {
11 reportsDirectory: '../coverage/<project-root>',
12 provider: 'v8',
13 },
14 },
15...
16
Note how we're specifying reporters
and environment
.
How your vite.config.ts
looks like
For applications
Add a vite.config.ts
file to the root of your project. If you are not using React, you can skip adding the react
plugin, of course.
1/// <reference types='vitest' />
2import { defineConfig } from 'vite';
3import react from '@vitejs/plugin-react';
4import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin';
5
6export default defineConfig({
7 root: __dirname,
8 build: {
9 outDir: '../../dist/apps/my-app',
10 reportCompressedSize: true,
11 commonjsOptions: {
12 transformMixedEsModules: true,
13 },
14 },
15 cacheDir: '../../node_modules/.vite/apps/my-app',
16 server: {
17 port: 4200,
18 host: 'localhost',
19 },
20
21 preview: {
22 port: 4300,
23 host: 'localhost',
24 },
25
26 plugins: [react(), nxViteTsPaths()],
27
28 test: {
29 reporters: ['default'],
30 coverage: {
31 reportsDirectory: '../../coverage/apps/my-app',
32 provider: 'v8',
33 },
34 globals: true,
35 cache: {
36 dir: '../../node_modules/.vitest/apps/my-app',
37 },
38 environment: 'jsdom',
39 include: ['src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
40 },
41});
42
For libraries
If you are setting up a library (rather than an application) to use Vite, your vite.config.ts
file should look like this:
1/// <reference types='vitest' />
2import { defineConfig } from 'vite';
3import react from '@vitejs/plugin-react';
4import dts from 'vite-plugin-dts';
5import * as path from 'path';
6import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin';
7
8export default defineConfig({
9 root: __dirname,
10 cacheDir: '../node_modules/.vite/my-lib',
11 plugins: [
12 react(),
13 nxViteTsPaths(),
14 dts({
15 entryRoot: 'src',
16 tsConfigFilePath: path.join(__dirname, 'tsconfig.lib.json'),
17 skipDiagnostics: true,
18 }),
19 ],
20 // Configuration for building your library.
21 // See: https://vitejs.dev/guide/build.html#library-mode
22 build: {
23 outDir: '../dist/libs/my-lib',
24 reportCompressedSize: true,
25 commonjsOptions: {
26 transformMixedEsModules: true,
27 },
28 lib: {
29 // Could also be a dictionary or array of multiple entry points.
30 entry: 'src/index.ts',
31 name: 'my-lib',
32 fileName: 'index',
33 // Change this to the formats you want to support.
34 // Don't forget to update your package.json as well.
35 formats: ['es'],
36 },
37 rollupOptions: {
38 // External packages that should not be bundled into your library.
39 external: ['react', 'react-dom', 'react/jsx-runtime'],
40 },
41 },
42 test: {
43 globals: true,
44 cache: {
45 dir: '../node_modules/.vitest/libs/my-lib',
46 },
47 environment: 'jsdom',
48 include: ['src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
49 reporters: ['default'],
50 coverage: {
51 reportsDirectory: '../coverage/libs/my-lib',
52 provider: 'v8',
53 },
54 },
55});
56
In that config file, you can configure Vite as you would normally do. For more information, see the Vite.js documentation.
Set up file replacements
You can use the replaceFiles()
plugin (@nx/vite/plugins/rollup-replace-files.plugin
) to replace files in your build. You can import the plugin from @nx/vite/plugins/rollup-replace-files.plugin
. And you can set it up like this:
1...
2import { replaceFiles } from '@nx/vite/plugins/rollup-replace-files.plugin';
3
4export default defineConfig({
5 ...
6
7 plugins: [
8 ...
9 replaceFiles([
10 {
11 replace: 'apps/my-app/src/environments/environment.ts',
12 with: 'apps/my-app/src/environments/environment.prod.ts',
13 },
14 ]),
15 ],
16
17 ...
18});
19