Leosvel Pérez Espinosa 8d056c9cdb
fix(misc): generate config with output contained within project root (#29850)
Updates some generators to ensure the build tool produces the output
contained within the project root for the TS solution setup.

## Current Behavior

## Expected Behavior

## Related Issue(s)

Fixes #
2025-02-04 09:16:02 -05:00

238 lines
6.6 KiB
TypeScript

import { NormalizedSchema } from '../schema';
import {
addProjectConfiguration,
joinPathFragments,
ProjectConfiguration,
TargetConfiguration,
Tree,
updateProjectConfiguration,
writeJson,
} from '@nx/devkit';
import { hasWebpackPlugin } from '../../../utils/has-webpack-plugin';
import { maybeJs } from '../../../utils/maybe-js';
import { hasRspackPlugin } from '../../../utils/has-rspack-plugin';
export function addProject(host: Tree, options: NormalizedSchema) {
const project: ProjectConfiguration = {
root: options.appProjectRoot,
sourceRoot: `${options.appProjectRoot}/src`,
projectType: 'application',
targets: {},
tags: options.parsedTags,
};
if (options.bundler === 'webpack') {
if (!hasWebpackPlugin(host) || !options.addPlugin) {
project.targets = {
build: createBuildTarget(options),
serve: createServeTarget(options),
};
}
} else if (
options.bundler === 'rspack' &&
(!hasRspackPlugin(host) || !options.addPlugin)
) {
project.targets = {
build: createRspackBuildTarget(options),
serve: createRspackServeTarget(options),
};
}
if (options.isUsingTsSolutionConfig) {
writeJson(host, joinPathFragments(options.appProjectRoot, 'package.json'), {
name: options.projectName,
version: '0.0.1',
private: true,
});
}
if (!options.isUsingTsSolutionConfig || options.alwaysGenerateProjectJson) {
addProjectConfiguration(host, options.projectName, {
...project,
});
} else if (
options.parsedTags?.length ||
Object.keys(project.targets).length
) {
const updatedProject: ProjectConfiguration = {
root: options.appProjectRoot,
targets: project.targets,
tags: options.parsedTags?.length ? options.parsedTags : undefined,
};
updateProjectConfiguration(host, options.projectName, updatedProject);
}
}
function createRspackBuildTarget(
options: NormalizedSchema
): TargetConfiguration {
return {
executor: '@nx/rspack:rspack',
outputs: ['{options.outputPath}'],
defaultConfiguration: 'production',
options: {
outputPath: options.isUsingTsSolutionConfig
? joinPathFragments(options.appProjectRoot, 'dist')
: joinPathFragments(
'dist',
options.appProjectRoot !== '.'
? options.appProjectRoot
: options.projectName
),
index: joinPathFragments(options.appProjectRoot, 'src/index.html'),
baseHref: '/',
main: joinPathFragments(
options.appProjectRoot,
maybeJs(options, `src/main.tsx`)
),
tsConfig: joinPathFragments(options.appProjectRoot, 'tsconfig.app.json'),
assets: [
joinPathFragments(options.appProjectRoot, 'src/favicon.ico'),
joinPathFragments(options.appProjectRoot, 'src/assets'),
],
rspackConfig: joinPathFragments(
options.appProjectRoot,
'rspack.config.js'
),
styles:
options.styledModule || !options.hasStyles
? []
: [
joinPathFragments(
options.appProjectRoot,
`src/styles.${options.style}`
),
],
scripts: [],
configurations: {
development: {
mode: 'development',
},
production: {
mode: 'production',
optimization: true,
sourceMap: false,
outputHashing: 'all',
namedChunks: false,
extractLicenses: true,
vendorChunk: false,
},
},
},
};
}
function createRspackServeTarget(
options: NormalizedSchema
): TargetConfiguration {
return {
executor: '@nx/rspack:dev-server',
defaultConfiguration: 'development',
options: {
buildTarget: `${options.projectName}:build`,
hmr: true,
},
configurations: {
development: {
buildTarget: `${options.projectName}:build:development`,
},
production: {
buildTarget: `${options.projectName}:build:production`,
hmr: false,
},
},
};
}
function createBuildTarget(options: NormalizedSchema): TargetConfiguration {
return {
executor: '@nx/webpack:webpack',
outputs: ['{options.outputPath}'],
defaultConfiguration: 'production',
options: {
compiler: options.compiler ?? 'babel',
outputPath: options.isUsingTsSolutionConfig
? joinPathFragments(options.appProjectRoot, 'dist')
: joinPathFragments(
'dist',
options.appProjectRoot !== '.'
? options.appProjectRoot
: options.projectName
),
index: joinPathFragments(options.appProjectRoot, 'src/index.html'),
baseHref: '/',
main: joinPathFragments(
options.appProjectRoot,
maybeJs(options, `src/main.tsx`)
),
tsConfig: joinPathFragments(options.appProjectRoot, 'tsconfig.app.json'),
assets: [
joinPathFragments(options.appProjectRoot, 'src/favicon.ico'),
joinPathFragments(options.appProjectRoot, 'src/assets'),
],
styles:
options.styledModule || !options.hasStyles
? []
: [
joinPathFragments(
options.appProjectRoot,
`src/styles.${options.style}`
),
],
scripts: [],
webpackConfig: joinPathFragments(
options.appProjectRoot,
'webpack.config.js'
),
},
configurations: {
development: {
extractLicenses: false,
optimization: false,
sourceMap: true,
vendorChunk: true,
},
production: {
fileReplacements: [
{
replace: joinPathFragments(
options.appProjectRoot,
maybeJs(options, `src/environments/environment.ts`)
),
with: joinPathFragments(
options.appProjectRoot,
maybeJs(options, `src/environments/environment.prod.ts`)
),
},
],
optimization: true,
outputHashing: 'all',
sourceMap: false,
namedChunks: false,
extractLicenses: true,
vendorChunk: false,
},
},
};
}
function createServeTarget(options: NormalizedSchema): TargetConfiguration {
return {
executor: '@nx/webpack:dev-server',
defaultConfiguration: 'development',
options: {
buildTarget: `${options.projectName}:build`,
hmr: true,
},
configurations: {
development: {
buildTarget: `${options.projectName}:build:development`,
},
production: {
buildTarget: `${options.projectName}:build:production`,
hmr: false,
},
},
};
}