UNPKG

@nx/vite

Version:

The Nx Plugin for building and testing applications using Vite

182 lines (181 loc) • 7.17 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.vitePreviewServerExecutor = vitePreviewServerExecutor; const devkit_1 = require("@nx/devkit"); const options_utils_1 = require("../../utils/options-utils"); const path_1 = require("path"); const build_impl_1 = require("../build/build.impl"); const executor_utils_1 = require("../../utils/executor-utils"); async function* vitePreviewServerExecutor(options, context) { 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, preview, resolveConfig } = await (0, executor_utils_1.loadViteDynamicImport)(); const projectRoot = context.projectsConfigurations.projects[context.projectName].root; const target = (0, devkit_1.parseTargetString)(options.buildTarget, context); const targetConfiguration = context.projectsConfigurations.projects[target.project]?.targets[target.target]; if (!targetConfiguration) { throw new Error(`Invalid buildTarget: ${options.buildTarget}`); } const isCustomBuildTarget = targetConfiguration.executor !== '@nx/vite:build' && targetConfiguration.executor !== '@nrwl/vite:build'; // Retrieve the option for the configured buildTarget. const buildTargetOptions = (0, options_utils_1.getNxTargetOptions)(options.buildTarget, context); const { configuration } = (0, devkit_1.parseTargetString)(options.buildTarget, context); const viteConfigPath = (0, options_utils_1.normalizeViteConfigFilePath)(context.root, projectRoot, buildTargetOptions.configFile); const { buildOptions, otherOptions: otherOptionsFromBuild } = await (0, build_impl_1.getBuildExtraArgs)({ ...buildTargetOptions, ...{ // Enable watch mode by default for the build target. watch: options.watch ?? true, }, }); const { previewOptions, otherOptions } = await getExtraArgs(options, configuration, otherOptionsFromBuild); const defaultMode = otherOptions?.mode ?? otherOptionsFromBuild?.mode ?? 'production'; const resolved = await resolveConfig({ configFile: viteConfigPath, mode: defaultMode, }, 'build', defaultMode, process.env.NODE_ENV ?? defaultMode); const outDir = options.staticFilePath ?? (0, devkit_1.joinPathFragments)((0, devkit_1.offsetFromRoot)(projectRoot), buildTargetOptions.outputPath) ?? resolved?.build?.outDir; if (!outDir) { throw new Error(`Could not infer the "outputPath" or "outDir". It should be set in your vite.config.ts, or as a property of the "${options.buildTarget}" buildTarget or provided explicitly as a "staticFilePath" option.`); } const root = projectRoot === '.' ? process.cwd() : (0, path_1.relative)(context.cwd, (0, devkit_1.joinPathFragments)(context.root, projectRoot)); // Merge the options from the build and preview-serve targets. // The latter takes precedence. const mergedOptions = { ...{ watch: {} }, build: { outDir, ...(isCustomBuildTarget ? {} : buildOptions), }, ...(isCustomBuildTarget ? {} : otherOptionsFromBuild), ...otherOptions, preview: { ...(0, options_utils_1.getProxyConfig)(context, otherOptions.proxyConfig), ...previewOptions, }, }; // vite InlineConfig const serverConfig = mergeConfig({ // This should not be needed as it's going to be set in vite.config.ts // but leaving it here in case someone did not migrate correctly root: resolved.root ?? root, configFile: viteConfigPath, }, { ...mergedOptions, }); if (serverConfig.mode === 'production') { console.warn('WARNING: preview is not meant to be run in production!'); } // vite PreviewServer let server; const processOnExit = async () => { await closeServer(server); }; process.once('SIGINT', processOnExit); process.once('SIGTERM', processOnExit); process.once('exit', processOnExit); // Launch the build target. // If customBuildTarget is set to true, do not provide any overrides to it const buildTargetOverrides = isCustomBuildTarget ? {} : mergedOptions; const build = await (0, devkit_1.runExecutor)(target, buildTargetOverrides, context); for await (const result of build) { if (result.success) { try { if (!server) { server = await preview(serverConfig); } server.printUrls(); const resolvedUrls = [ ...server.resolvedUrls.local, ...server.resolvedUrls.network, ]; yield { success: true, baseUrl: resolvedUrls[0] ?? '', }; } catch (e) { console.error(e); yield { success: false, baseUrl: '', }; } } else { yield { success: false, baseUrl: '', }; } } await new Promise((resolve) => { process.once('SIGINT', () => resolve()); process.once('SIGTERM', () => resolve()); process.once('exit', () => resolve()); }); } function closeServer(server) { return new Promise((resolve) => { if (!server) { resolve(); } else { const { httpServer } = server; if (httpServer['closeAllConnections']) { // https://github.com/vitejs/vite/pull/14834 // closeAllConnections was added in Node v18.2.0 // typically is "as http.Server" but no reason // to import http just for this httpServer.closeAllConnections(); } httpServer.close(() => resolve()); } }); } exports.default = vitePreviewServerExecutor; async function getExtraArgs(options, configuration, otherOptionsFromBuildTarget) { // support passing extra args to vite cli const schema = await Promise.resolve().then(() => require('./schema.json')); const extraArgs = {}; for (const key of Object.keys(options)) { if (!schema.properties[key]) { extraArgs[key] = options[key]; } } const previewOptions = {}; const previewSchemaKeys = [ 'port', 'strictPort', 'host', 'https', 'open', 'proxy', 'cors', 'headers', ]; let otherOptions = {}; for (const key of Object.keys(extraArgs)) { if (previewSchemaKeys.includes(key)) { previewOptions[key] = extraArgs[key]; } else { otherOptions[key] = extraArgs[key]; } } if (configuration) { otherOptions = { ...otherOptions, ...(otherOptionsFromBuildTarget ?? {}), }; } return { previewOptions, otherOptions, }; }