UNPKG

@nx/rspack

Version:

The Nx Plugin for Rspack contains executors and generators that support building applications using Rspack.

207 lines (206 loc) • 8.31 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.createNodesV2 = exports.createDependencies = void 0; const devkit_1 = require("@nx/devkit"); const get_named_inputs_1 = require("@nx/devkit/src/utils/get-named-inputs"); const js_1 = require("@nx/js"); const ts_solution_setup_1 = require("@nx/js/src/utils/typescript/ts-solution-setup"); const fs_1 = require("fs"); const file_hasher_1 = require("nx/src/hasher/file-hasher"); const cache_directory_1 = require("nx/src/utils/cache-directory"); const path_1 = require("path"); const read_rspack_options_1 = require("../utils/read-rspack-options"); const resolve_user_defined_rspack_config_1 = require("../utils/resolve-user-defined-rspack-config"); const util_1 = require("@nx/js/src/plugins/typescript/util"); const pmc = (0, devkit_1.getPackageManagerCommand)(); function readTargetsCache(cachePath) { try { return process.env.NX_CACHE_PROJECT_GRAPH !== 'false' ? (0, devkit_1.readJsonFile)(cachePath) : {}; } catch { return {}; } } function writeTargetsToCache(cachePath, results) { (0, devkit_1.writeJsonFile)(cachePath, results); } const createDependencies = () => { return []; }; exports.createDependencies = createDependencies; const rspackConfigGlob = '**/rspack.config.{js,ts,mjs,mts,cjs,cts}'; exports.createNodesV2 = [ rspackConfigGlob, async (configFilePaths, options, context) => { const optionsHash = (0, file_hasher_1.hashObject)(options); const cachePath = (0, path_1.join)(cache_directory_1.workspaceDataDirectory, `rspack-${optionsHash}.hash`); const targetsCache = readTargetsCache(cachePath); const isTsSolutionSetup = (0, ts_solution_setup_1.isUsingTsSolutionSetup)(); try { return await (0, devkit_1.createNodesFromFiles)((configFile, options, context) => createNodesInternal(configFile, options, context, targetsCache, isTsSolutionSetup), configFilePaths, options, context); } finally { writeTargetsToCache(cachePath, targetsCache); } }, ]; async function createNodesInternal(configFilePath, options, context, targetsCache, isTsSolutionSetup) { const projectRoot = (0, path_1.dirname)(configFilePath); // Do not create a project if package.json and project.json isn't there. const siblingFiles = (0, fs_1.readdirSync)((0, path_1.join)(context.workspaceRoot, projectRoot)); if (!siblingFiles.includes('package.json') && !siblingFiles.includes('project.json')) { return {}; } let packageJson = {}; if (siblingFiles.includes('package.json')) { packageJson = (0, devkit_1.readJsonFile)((0, path_1.join)(context.workspaceRoot, projectRoot, 'package.json')); } const normalizedOptions = normalizeOptions(options); const lockFileHash = (0, file_hasher_1.hashFile)((0, path_1.join)(context.workspaceRoot, (0, js_1.getLockFileName)((0, devkit_1.detectPackageManager)(context.workspaceRoot)))) ?? ''; const nodeHash = (0, file_hasher_1.hashArray)([ (0, file_hasher_1.hashFile)((0, path_1.join)(context.workspaceRoot, configFilePath)), lockFileHash, (0, file_hasher_1.hashObject)({ ...options, isTsSolutionSetup }), (0, file_hasher_1.hashObject)(packageJson), ]); // We do not want to alter how the hash is calculated, so appending the config file path to the hash // to prevent vite/vitest files overwriting the target cache created by the other const hash = `${nodeHash}_${configFilePath}`; targetsCache[hash] ??= await createRspackTargets(configFilePath, projectRoot, normalizedOptions, context, isTsSolutionSetup); const { targets, metadata } = targetsCache[hash]; return { projects: { [projectRoot]: { root: projectRoot, targets, metadata, }, }, }; } async function createRspackTargets(configFilePath, projectRoot, options, context, isTsSolutionSetup) { const namedInputs = (0, get_named_inputs_1.getNamedInputs)(projectRoot, context); const rspackConfig = await (0, resolve_user_defined_rspack_config_1.resolveUserDefinedRspackConfig)((0, path_1.join)(context.workspaceRoot, configFilePath), (0, js_1.getRootTsConfigPath)(), true); const rspackOptions = await (0, read_rspack_options_1.readRspackOptions)(rspackConfig); const outputs = []; for (const config of rspackOptions) { if (config.output?.path) { outputs.push(normalizeOutputPath(config.output.path, projectRoot)); } } const targets = {}; const env = {}; const isTsConfig = ['.ts', '.cts', '.mts'].includes((0, path_1.extname)(configFilePath)); if (isTsConfig) { // https://rspack.dev/config/#using-ts-node env['TS_NODE_COMPILER_OPTIONS'] = JSON.stringify({ module: 'CommonJS', moduleResolution: 'Node10', customConditions: null, }); } targets[options.buildTargetName] = { command: `rspack build`, options: { cwd: projectRoot, args: ['--node-env=production'], env, }, cache: true, dependsOn: [`^${options.buildTargetName}`], inputs: 'production' in namedInputs ? [ 'production', '^production', { externalDependencies: ['@rspack/cli'], }, ] : [ 'default', '^default', { externalDependencies: ['@rspack/cli'], }, ], outputs, }; targets[options.serveTargetName] = { command: `rspack serve`, options: { cwd: projectRoot, args: ['--node-env=development'], env, }, }; targets[options.previewTargetName] = { command: `rspack serve`, options: { cwd: projectRoot, args: ['--node-env=production'], env, }, }; targets[options.serveStaticTargetName] = { executor: '@nx/web:file-server', options: { buildTarget: options.buildTargetName, spa: true, }, }; if (isTsSolutionSetup) { targets[options.buildTargetName].syncGenerators = [ '@nx/js:typescript-sync', ]; targets[options.serveTargetName].syncGenerators = [ '@nx/js:typescript-sync', ]; targets[options.previewTargetName].syncGenerators = [ '@nx/js:typescript-sync', ]; targets[options.serveStaticTargetName].syncGenerators = [ '@nx/js:typescript-sync', ]; } (0, util_1.addBuildAndWatchDepsTargets)(context.workspaceRoot, projectRoot, targets, options, pmc); return { targets, metadata: {} }; } function normalizeOptions(options) { options ??= {}; options.buildTargetName ??= 'build'; options.serveTargetName ??= 'serve'; options.previewTargetName ??= 'preview'; options.serveStaticTargetName ??= 'serve-static'; return options; } function normalizeOutputPath(outputPath, projectRoot) { if (!outputPath) { // If outputPath is undefined, use rspack's default `dist` directory. if (projectRoot === '.') { return `{projectRoot}/dist`; } else { return `{workspaceRoot}/dist/{projectRoot}`; } } else { if ((0, path_1.isAbsolute)(outputPath)) { /** * If outputPath is absolute, we need to resolve it relative to the workspaceRoot first. * After that, we can use the relative path to the workspaceRoot token {workspaceRoot} to generate the output path. */ return `{workspaceRoot}/${(0, path_1.relative)(devkit_1.workspaceRoot, (0, path_1.resolve)(devkit_1.workspaceRoot, outputPath))}`; } else { if (outputPath.startsWith('..')) { return (0, path_1.join)('{workspaceRoot}', (0, path_1.join)(projectRoot, outputPath)); } else { return (0, path_1.join)('{projectRoot}', outputPath); } } } }