BREAKING CHANGE When generating projects that use Vite, the Vite configuration will be set to use the ESM format only. Previously, the configuration was set to produce both ESM and CJS, but the dual format was not correctly configured in the libraries' `package.json` files, nor was it producing the correct declaration files. <!-- Please make sure you have read the submission guidelines before posting an PR --> <!-- https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr --> <!-- Please make sure that your commit message follows our format --> <!-- Example: `fix(nx): must begin with lowercase` --> <!-- If this is a particularly complex change or feature addition, you can request a dedicated Nx release for this pull request branch. Mention someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they will confirm if the PR warrants its own release for testing purposes, and generate it for you if appropriate. --> ## Current Behavior <!-- This is the behavior we have today --> ## Expected Behavior <!-- This is the behavior we should expect with the changes in this PR --> ## Related Issue(s) <!-- Please link the issue being fixed so it gets closed when this is merged. --> Fixes #
445 lines
15 KiB
TypeScript
445 lines
15 KiB
TypeScript
import { Tree } from '@nx/devkit';
|
|
import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
|
|
import { tsquery } from '@phenomnomnominal/tsquery';
|
|
import {
|
|
buildOption,
|
|
buildOptionObject,
|
|
conditionalConfig,
|
|
configNoDefineConfig,
|
|
imports,
|
|
hasEverything,
|
|
noBuildOptions,
|
|
noBuildOptionsHasTestOption,
|
|
noContentDefineConfig,
|
|
plugins,
|
|
someBuildOptions,
|
|
someBuildOptionsSomeTestOption,
|
|
testOption,
|
|
testOptionObject,
|
|
} from './test-files/test-vite-configs';
|
|
import { ensureViteConfigIsCorrect } from './vite-config-edit-utils';
|
|
|
|
describe('ensureViteConfigIsCorrect', () => {
|
|
let tree: Tree;
|
|
|
|
beforeEach(() => {
|
|
tree = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });
|
|
});
|
|
|
|
it("should add build options if build options don't exist", () => {
|
|
tree.write('apps/my-app/vite.config.ts', noBuildOptions);
|
|
ensureViteConfigIsCorrect(
|
|
tree,
|
|
'apps/my-app/vite.config.ts',
|
|
buildOption,
|
|
buildOptionObject,
|
|
imports,
|
|
plugins,
|
|
testOption,
|
|
testOptionObject,
|
|
'',
|
|
{ build: false, test: true, serve: false }
|
|
);
|
|
const appFileContent = tree.read('apps/my-app/vite.config.ts', 'utf-8');
|
|
const file = tsquery.ast(appFileContent);
|
|
const buildNode = tsquery.query(
|
|
file,
|
|
'PropertyAssignment:has(Identifier[name="build"])'
|
|
);
|
|
expect(buildNode).toBeDefined();
|
|
expect(appFileContent).toMatchInlineSnapshot(`
|
|
"import dts from 'vite-plugin-dts';
|
|
import { joinPathFragments } from '@nx/devkit'
|
|
import { defineConfig } from 'vite';
|
|
import react from '@vitejs/plugin-react';
|
|
import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin';
|
|
|
|
export default defineConfig({
|
|
|
|
// Configuration for building your library.
|
|
// See: https://vitejs.dev/guide/build.html#library-mode
|
|
build: {
|
|
lib: {
|
|
// Could also be a dictionary or array of multiple entry points.
|
|
entry: 'src/index.ts',
|
|
name: 'my-app',
|
|
fileName: 'index',
|
|
// Change this to the formats you want to support.
|
|
// Don't forget to update your package.json as well.
|
|
formats: ['es']
|
|
},
|
|
rollupOptions: {
|
|
// External packages that should not be bundled into your library.
|
|
external: ['react', 'react-dom', 'react/jsx-runtime']
|
|
}
|
|
},cacheDir: '../../node_modules/.vitest',
|
|
plugins: [react(), nxViteTsPaths(), ],
|
|
|
|
test: {
|
|
globals: true,
|
|
environment: 'jsdom',
|
|
include: ['src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
|
|
},
|
|
|
|
});
|
|
"
|
|
`);
|
|
});
|
|
|
|
it('should add new build options if some build options already exist', () => {
|
|
tree.write('apps/my-app/vite.config.ts', someBuildOptions);
|
|
ensureViteConfigIsCorrect(
|
|
tree,
|
|
'apps/my-app/vite.config.ts',
|
|
buildOption,
|
|
buildOptionObject,
|
|
imports,
|
|
plugins,
|
|
testOption,
|
|
testOptionObject,
|
|
'',
|
|
{ build: false, test: true, serve: false }
|
|
);
|
|
const appFileContent = tree.read('apps/my-app/vite.config.ts', 'utf-8');
|
|
const file = tsquery.ast(appFileContent);
|
|
const buildNode = tsquery.query(
|
|
file,
|
|
'PropertyAssignment:has(Identifier[name="build"])'
|
|
);
|
|
expect(buildNode).toBeDefined();
|
|
expect(appFileContent).toMatchInlineSnapshot(`
|
|
"import dts from 'vite-plugin-dts';
|
|
import { joinPathFragments } from '@nx/devkit'
|
|
import { defineConfig } from 'vite';
|
|
import react from '@vitejs/plugin-react';
|
|
import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin';
|
|
|
|
export default defineConfig({
|
|
cacheDir: '../../node_modules/.vitest',
|
|
plugins: [react(), nxViteTsPaths(), ],
|
|
|
|
test: {
|
|
globals: true,
|
|
environment: 'jsdom',
|
|
include: ['src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
|
|
},
|
|
|
|
build: {
|
|
'my': 'option',
|
|
'lib': {"entry":"src/index.ts","name":"my-app","fileName":"index","formats":["es"]},
|
|
'rollupOptions': {"external":["react","react-dom","react/jsx-runtime"]},
|
|
}
|
|
|
|
});
|
|
"
|
|
`);
|
|
});
|
|
|
|
it('should add build and test options if defineConfig is empty', () => {
|
|
tree.write('apps/my-app/vite.config.ts', noContentDefineConfig);
|
|
ensureViteConfigIsCorrect(
|
|
tree,
|
|
'apps/my-app/vite.config.ts',
|
|
buildOption,
|
|
buildOptionObject,
|
|
imports,
|
|
plugins,
|
|
testOption,
|
|
testOptionObject,
|
|
'',
|
|
{ build: false, test: false, serve: false }
|
|
);
|
|
const appFileContent = tree.read('apps/my-app/vite.config.ts', 'utf-8');
|
|
const file = tsquery.ast(appFileContent);
|
|
const buildNode = tsquery.query(
|
|
file,
|
|
'PropertyAssignment:has(Identifier[name="build"])'
|
|
);
|
|
expect(buildNode).toBeDefined();
|
|
expect(appFileContent).toMatchInlineSnapshot(`
|
|
"import dts from 'vite-plugin-dts';
|
|
import { joinPathFragments } from '@nx/devkit'
|
|
|
|
/// <reference types="vitest" />
|
|
import { defineConfig } from 'vite';
|
|
import react from '@vitejs/plugin-react';
|
|
import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin';
|
|
|
|
export default defineConfig({
|
|
// Configuration for building your library.
|
|
// See: https://vitejs.dev/guide/build.html#library-mode
|
|
plugins: [react(), nxViteTsPaths()],build: {
|
|
lib: {
|
|
// Could also be a dictionary or array of multiple entry points.
|
|
entry: 'src/index.ts',
|
|
name: 'my-app',
|
|
fileName: 'index',
|
|
// Change this to the formats you want to support.
|
|
// Don't forget to update your package.json as well.
|
|
formats: ['es']
|
|
},
|
|
rollupOptions: {
|
|
// External packages that should not be bundled into your library.
|
|
external: ['react', 'react-dom', 'react/jsx-runtime']
|
|
}
|
|
},test: {
|
|
globals: true,
|
|
environment: 'jsdom',
|
|
include: ['src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
|
|
},});
|
|
"
|
|
`);
|
|
});
|
|
|
|
it('should add build options if it is using conditional config - do nothing for test', () => {
|
|
tree.write('apps/my-app/vite.config.ts', conditionalConfig);
|
|
ensureViteConfigIsCorrect(
|
|
tree,
|
|
'apps/my-app/vite.config.ts',
|
|
buildOption,
|
|
buildOptionObject,
|
|
imports,
|
|
plugins,
|
|
testOption,
|
|
testOptionObject,
|
|
'',
|
|
{ build: false, test: false, serve: false }
|
|
);
|
|
const appFileContent = tree.read('apps/my-app/vite.config.ts', 'utf-8');
|
|
const file = tsquery.ast(appFileContent);
|
|
const buildNode = tsquery.query(
|
|
file,
|
|
'PropertyAssignment:has(Identifier[name="build"])'
|
|
);
|
|
expect(buildNode).toBeDefined();
|
|
expect(appFileContent).toMatchSnapshot();
|
|
});
|
|
|
|
it('should add build options if defineConfig is not used', () => {
|
|
tree.write('apps/my-app/vite.config.ts', configNoDefineConfig);
|
|
ensureViteConfigIsCorrect(
|
|
tree,
|
|
'apps/my-app/vite.config.ts',
|
|
buildOption,
|
|
buildOptionObject,
|
|
imports,
|
|
plugins,
|
|
testOption,
|
|
testOptionObject,
|
|
'',
|
|
{ build: false, test: false, serve: false }
|
|
);
|
|
const appFileContent = tree.read('apps/my-app/vite.config.ts', 'utf-8');
|
|
const file = tsquery.ast(appFileContent);
|
|
const buildNode = tsquery.query(
|
|
file,
|
|
'PropertyAssignment:has(Identifier[name="build"])'
|
|
);
|
|
expect(buildNode).toBeDefined();
|
|
expect(appFileContent).toMatchInlineSnapshot(`
|
|
"import dts from 'vite-plugin-dts';
|
|
import { joinPathFragments } from '@nx/devkit'
|
|
import { defineConfig } from 'vite';
|
|
import react from '@vitejs/plugin-react';
|
|
import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin';
|
|
|
|
export default {
|
|
// Configuration for building your library.
|
|
// See: https://vitejs.dev/guide/build.html#library-mode
|
|
build: {
|
|
lib: {
|
|
// Could also be a dictionary or array of multiple entry points.
|
|
entry: 'src/index.ts',
|
|
name: 'my-app',
|
|
fileName: 'index',
|
|
// Change this to the formats you want to support.
|
|
// Don't forget to update your package.json as well.
|
|
formats: ['es']
|
|
},
|
|
rollupOptions: {
|
|
// External packages that should not be bundled into your library.
|
|
external: ['react', 'react-dom', 'react/jsx-runtime']
|
|
}
|
|
},test: {
|
|
globals: true,
|
|
environment: 'jsdom',
|
|
include: ['src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
|
|
},
|
|
plugins: [react(), nxViteTsPaths(), ],
|
|
};
|
|
"
|
|
`);
|
|
});
|
|
|
|
it('should not do anything if cannot understand syntax of vite config', () => {
|
|
tree.write('apps/my-app/vite.config.ts', `console.log('Unknown syntax')`);
|
|
ensureViteConfigIsCorrect(
|
|
tree,
|
|
'apps/my-app/vite.config.ts',
|
|
buildOption,
|
|
buildOptionObject,
|
|
imports,
|
|
plugins,
|
|
testOption,
|
|
testOptionObject,
|
|
'',
|
|
{ build: false, test: false, serve: false }
|
|
);
|
|
const appFileContent = tree.read('apps/my-app/vite.config.ts', 'utf-8');
|
|
expect(appFileContent).toMatchSnapshot();
|
|
});
|
|
|
|
it('should not do anything if project has everything setup already', () => {
|
|
tree.write('apps/my-app/vite.config.ts', hasEverything);
|
|
ensureViteConfigIsCorrect(
|
|
tree,
|
|
'apps/my-app/vite.config.ts',
|
|
buildOption,
|
|
buildOptionObject,
|
|
imports,
|
|
plugins,
|
|
testOption,
|
|
testOptionObject,
|
|
'',
|
|
{ build: true, test: true, serve: true }
|
|
);
|
|
const appFileContent = tree.read('apps/my-app/vite.config.ts', 'utf-8');
|
|
expect(appFileContent).toMatchInlineSnapshot(`
|
|
"
|
|
import { defineConfig } from 'vite';
|
|
import react from '@vitejs/plugin-react';
|
|
import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin';
|
|
import dts from 'vite-plugin-dts';
|
|
import { joinPathFragments } from '@nx/devkit';
|
|
|
|
export default defineConfig({
|
|
cacheDir: '../../node_modules/.vitest',
|
|
plugins: [dts({ entryRoot: 'src', tsConfigFilePath: joinPathFragments(__dirname, 'tsconfig.lib.json'), skipDiagnostics: true }), react(), nxViteTsPaths(), ],
|
|
|
|
// Configuration for building your library.
|
|
// See: https://vitejs.dev/guide/build.html#library-mode
|
|
build: {
|
|
lib: {
|
|
// Could also be a dictionary or array of multiple entry points.
|
|
entry: 'src/index.ts',
|
|
name: 'pure-libs-react-vite',
|
|
fileName: 'index',
|
|
// Change this to the formats you want to support.
|
|
// Don't forget to update your package.json as well.
|
|
formats: ['es'],
|
|
},
|
|
rollupOptions: {
|
|
// External packages that should not be bundled into your library.
|
|
external: ['react', 'react-dom', 'react/jsx-runtime'],
|
|
},
|
|
},
|
|
|
|
test: {
|
|
globals: true,
|
|
environment: 'jsdom',
|
|
include: ['src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
|
|
},
|
|
});
|
|
"
|
|
`);
|
|
});
|
|
|
|
it('should add build option but not update test option if test already setup', () => {
|
|
tree.write('apps/my-app/vite.config.ts', noBuildOptionsHasTestOption);
|
|
ensureViteConfigIsCorrect(
|
|
tree,
|
|
'apps/my-app/vite.config.ts',
|
|
buildOption,
|
|
buildOptionObject,
|
|
imports,
|
|
plugins,
|
|
testOption,
|
|
testOptionObject,
|
|
'',
|
|
{ build: false, test: true, serve: true }
|
|
);
|
|
const appFileContent = tree.read('apps/my-app/vite.config.ts', 'utf-8');
|
|
expect(appFileContent).toMatchInlineSnapshot(`
|
|
"import dts from 'vite-plugin-dts';
|
|
import { joinPathFragments } from '@nx/devkit'
|
|
import { defineConfig } from 'vite';
|
|
import react from '@vitejs/plugin-react';
|
|
import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin';
|
|
|
|
export default defineConfig({
|
|
|
|
|
|
// Configuration for building your library.
|
|
// See: https://vitejs.dev/guide/build.html#library-mode
|
|
build: {
|
|
lib: {
|
|
// Could also be a dictionary or array of multiple entry points.
|
|
entry: 'src/index.ts',
|
|
name: 'my-app',
|
|
fileName: 'index',
|
|
// Change this to the formats you want to support.
|
|
// Don't forget to update your package.json as well.
|
|
formats: ['es']
|
|
},
|
|
rollupOptions: {
|
|
// External packages that should not be bundled into your library.
|
|
external: ['react', 'react-dom', 'react/jsx-runtime']
|
|
}
|
|
},cacheDir: '../../node_modules/.vitest',
|
|
plugins: [react(), nxViteTsPaths(), ],
|
|
|
|
test: {
|
|
globals: true,
|
|
environment: 'jsdom',
|
|
include: ['src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
|
|
},
|
|
|
|
});
|
|
"
|
|
`);
|
|
});
|
|
|
|
it('should update both test and build options - keep existing settings', () => {
|
|
tree.write('apps/my-app/vite.config.ts', someBuildOptionsSomeTestOption);
|
|
ensureViteConfigIsCorrect(
|
|
tree,
|
|
'apps/my-app/vite.config.ts',
|
|
buildOption,
|
|
buildOptionObject,
|
|
imports,
|
|
plugins,
|
|
testOption,
|
|
testOptionObject,
|
|
'',
|
|
{ build: false, test: false, serve: true }
|
|
);
|
|
const appFileContent = tree.read('apps/my-app/vite.config.ts', 'utf-8');
|
|
expect(appFileContent).toMatchInlineSnapshot(`
|
|
"import dts from 'vite-plugin-dts';
|
|
import { joinPathFragments } from '@nx/devkit'
|
|
import { defineConfig } from 'vite';
|
|
import react from '@vitejs/plugin-react';
|
|
import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin';
|
|
|
|
export default defineConfig({
|
|
plugins: [react(), nxViteTsPaths(), ],
|
|
|
|
test: {
|
|
'my': 'option',
|
|
'globals': true,
|
|
'environment': "jsdom",
|
|
'include': ["src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}"],
|
|
},
|
|
|
|
build: {
|
|
'my': 'option',
|
|
'lib': {"entry":"src/index.ts","name":"my-app","fileName":"index","formats":["es"]},
|
|
'rollupOptions': {"external":["react","react-dom","react/jsx-runtime"]},
|
|
}
|
|
|
|
});
|
|
"
|
|
`);
|
|
});
|
|
});
|