fix(vite): environments api support in executor (#30183)
## Current Behavior `@nx/vite:build` executor does not support Vite 6 Environments API ## Expected Behavior `@nx/vite:build` executor builds all environments when Vite 6 is detected
This commit is contained in:
parent
320709f66f
commit
6fcb310e54
@ -58,6 +58,12 @@
|
||||
"skipPackageManager": {
|
||||
"type": "boolean",
|
||||
"description": "Do not add a `packageManager` entry to the generated package.json file. Only works in conjunction with `generatePackageJson` option."
|
||||
},
|
||||
"useEnvironmentsApi": {
|
||||
"alias": "app",
|
||||
"type": "boolean",
|
||||
"description": "Use the new Environments API for building multiple environments at once. Only works with Vite 6.0.0 or higher.",
|
||||
"default": false
|
||||
}
|
||||
},
|
||||
"definitions": {},
|
||||
|
||||
@ -89,6 +89,103 @@ describe('Vite Plugin', () => {
|
||||
}, 200_000);
|
||||
});
|
||||
});
|
||||
|
||||
describe('set up new React app with --bundler=vite option and use environments api', () => {
|
||||
let myApp;
|
||||
|
||||
beforeAll(() => {
|
||||
myApp = uniq('my-app');
|
||||
runCLI(
|
||||
`generate @nx/react:app ${myApp} --bundler=vite --unitTestRunner=vitest`
|
||||
);
|
||||
updateJson(`${myApp}/project.json`, (json) => {
|
||||
json.targets.build.options.useEnvironmentsApi = true;
|
||||
return json;
|
||||
});
|
||||
updateFile(
|
||||
`${myApp}/vite.config.ts`,
|
||||
`/// <reference types='vitest' />
|
||||
import { defineConfig } from 'vite';
|
||||
import react from '@vitejs/plugin-react';
|
||||
import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin';
|
||||
import { nxCopyAssetsPlugin } from '@nx/vite/plugins/nx-copy-assets.plugin';
|
||||
|
||||
export default defineConfig({
|
||||
root: __dirname,
|
||||
cacheDir: './node_modules/.vite/${myApp}',
|
||||
server: {
|
||||
port: 4200,
|
||||
host: 'localhost',
|
||||
},
|
||||
preview: {
|
||||
port: 4300,
|
||||
host: 'localhost',
|
||||
},
|
||||
plugins: [react(), nxViteTsPaths(), nxCopyAssetsPlugin(['*.md'])],
|
||||
// Uncomment this if you are using workers.
|
||||
// worker: {
|
||||
// plugins: [ nxViteTsPaths() ],
|
||||
// },
|
||||
builder: {},
|
||||
environments: {
|
||||
ssr: {
|
||||
build: {
|
||||
rollupOptions: {
|
||||
input: '${myApp}/src/main.server.tsx'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
build: {
|
||||
outDir: './dist/${myApp}',
|
||||
emptyOutDir: false,
|
||||
reportCompressedSize: true,
|
||||
commonjsOptions: {
|
||||
transformMixedEsModules: true,
|
||||
},
|
||||
},
|
||||
test: {
|
||||
watch: false,
|
||||
globals: true,
|
||||
environment: 'jsdom',
|
||||
include: ['src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
|
||||
reporters: ['default'],
|
||||
coverage: {
|
||||
reportsDirectory: './coverage/${myApp}',
|
||||
provider: 'v8',
|
||||
},
|
||||
},
|
||||
});
|
||||
`
|
||||
);
|
||||
updateFile(
|
||||
`${myApp}/src/main.server.tsx`,
|
||||
`import React from 'react'
|
||||
import ReactDOMServer from 'react-dom/server'
|
||||
import App from './app/app';
|
||||
|
||||
export default async function render(_url: string, document: string) {
|
||||
const html = ReactDOMServer.renderToString(
|
||||
<React.StrictMode>
|
||||
<App />
|
||||
</React.StrictMode>
|
||||
)
|
||||
return document.replace('<!--app-html-->', html);
|
||||
}`
|
||||
);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
rmDist();
|
||||
});
|
||||
|
||||
it('should build application', async () => {
|
||||
runCLI(`build ${myApp}`);
|
||||
expect(readFile(`dist/${myApp}/favicon.ico`)).toBeDefined();
|
||||
expect(readFile(`dist/${myApp}/index.html`)).toBeDefined();
|
||||
expect(readFile(`dist/${myApp}/main.server.mjs`)).toBeDefined();
|
||||
}, 200_000);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Vite on Web apps', () => {
|
||||
|
||||
@ -20,7 +20,10 @@ import {
|
||||
} from '@nx/js';
|
||||
import { existsSync, writeFileSync } from 'fs';
|
||||
import { relative, resolve } from 'path';
|
||||
import { createAsyncIterable } from '@nx/devkit/src/utils/async-iterable';
|
||||
import {
|
||||
combineAsyncIterables,
|
||||
createAsyncIterable,
|
||||
} from '@nx/devkit/src/utils/async-iterable';
|
||||
import {
|
||||
createBuildableTsConfig,
|
||||
loadViteDynamicImport,
|
||||
@ -35,7 +38,8 @@ export async function* viteBuildExecutor(
|
||||
) {
|
||||
process.env.VITE_CJS_IGNORE_WARNING = 'true';
|
||||
// Allows ESM to be required in CJS modules. Vite will be published as ESM in the future.
|
||||
const { mergeConfig, build, resolveConfig } = await loadViteDynamicImport();
|
||||
const { mergeConfig, build, resolveConfig, createBuilder } =
|
||||
await loadViteDynamicImport();
|
||||
const projectRoot =
|
||||
context.projectsConfigurations.projects[context.projectName].root;
|
||||
const tsConfigForBuild = createBuildableTsConfig(
|
||||
@ -50,7 +54,7 @@ export async function* viteBuildExecutor(
|
||||
options.configFile
|
||||
);
|
||||
const root =
|
||||
projectRoot === '.'
|
||||
projectRoot === '.' || projectRoot === ''
|
||||
? process.cwd()
|
||||
: relative(context.cwd, joinPathFragments(context.root, projectRoot));
|
||||
|
||||
@ -100,7 +104,25 @@ export async function* viteBuildExecutor(
|
||||
});
|
||||
}
|
||||
|
||||
const watcherOrOutput = await build(buildConfig);
|
||||
const builder =
|
||||
createBuilder !== undefined && options.useEnvironmentsApi
|
||||
? await createBuilder(buildConfig)
|
||||
: // This is needed to ensure support for Vite 5
|
||||
{
|
||||
build: (inlineConfig) => build(inlineConfig),
|
||||
environments: { build: buildConfig },
|
||||
};
|
||||
|
||||
let iterables: AsyncIterable<{ success: boolean; outfile?: string }>[] = [];
|
||||
for (const env of Object.values(builder.environments)) {
|
||||
// This is needed to overwrite the resolve build config with executor options in Vite 6
|
||||
if (env.config?.build) {
|
||||
env.config.build = {
|
||||
...env.config.build,
|
||||
...buildConfig.build,
|
||||
};
|
||||
}
|
||||
const watcherOrOutput = await builder.build(env as any);
|
||||
|
||||
const libraryPackageJson = resolve(projectRoot, 'package.json');
|
||||
const rootPackageJson = resolve(context.root, 'package.json');
|
||||
@ -177,8 +199,11 @@ export async function* viteBuildExecutor(
|
||||
);
|
||||
}
|
||||
|
||||
const iterable = createAsyncIterable<{
|
||||
success: boolean;
|
||||
outfile?: string;
|
||||
}>(({ next, done }) => {
|
||||
if ('on' in watcherOrOutput) {
|
||||
const iterable = createAsyncIterable<{ success: boolean }>(({ next }) => {
|
||||
let success = true;
|
||||
watcherOrOutput.on('event', (event) => {
|
||||
if (event.code === 'START') {
|
||||
@ -194,14 +219,18 @@ export async function* viteBuildExecutor(
|
||||
event.result.close();
|
||||
}
|
||||
});
|
||||
});
|
||||
yield* iterable;
|
||||
} else {
|
||||
const output = watcherOrOutput?.['output'] || watcherOrOutput?.[0]?.output;
|
||||
const output =
|
||||
watcherOrOutput?.['output'] || watcherOrOutput?.[0]?.output;
|
||||
const fileName = output?.[0]?.fileName || 'main.cjs';
|
||||
const outfile = resolve(outDirRelativeToWorkspaceRoot, fileName);
|
||||
yield { success: true, outfile };
|
||||
next({ success: true, outfile });
|
||||
done();
|
||||
}
|
||||
});
|
||||
iterables.push(iterable);
|
||||
}
|
||||
return yield* combineAsyncIterables(iterables.shift(), ...(iterables ?? []));
|
||||
}
|
||||
|
||||
export async function getBuildExtraArgs(
|
||||
|
||||
@ -9,4 +9,5 @@ export interface ViteBuildExecutorOptions {
|
||||
skipTypeCheck?: boolean;
|
||||
tsConfig?: string;
|
||||
watch?: boolean;
|
||||
useEnvironmentsApi?: boolean;
|
||||
}
|
||||
|
||||
@ -67,6 +67,12 @@
|
||||
"skipPackageManager": {
|
||||
"type": "boolean",
|
||||
"description": "Do not add a `packageManager` entry to the generated package.json file. Only works in conjunction with `generatePackageJson` option."
|
||||
},
|
||||
"useEnvironmentsApi": {
|
||||
"alias": "app",
|
||||
"type": "boolean",
|
||||
"description": "Use the new Environments API for building multiple environments at once. Only works with Vite 6.0.0 or higher.",
|
||||
"default": false
|
||||
}
|
||||
},
|
||||
"definitions": {},
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user