feat(node): Add output path to setup docker (#26365)
This PR updates how we generate a DockerFile for inferred and non inferred projects. Now you need to provide a output path.
This commit is contained in:
parent
88161e00c0
commit
9eebe4980a
@ -25,6 +25,10 @@
|
||||
"description": "The name of the build target",
|
||||
"type": "string",
|
||||
"default": "build"
|
||||
},
|
||||
"outputPath": {
|
||||
"description": "The output path for the node application",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"presets": []
|
||||
|
||||
@ -54,6 +54,7 @@ import { logShowProjectCommand } from '@nx/devkit/src/utils/log-show-project-com
|
||||
export interface NormalizedSchema extends Schema {
|
||||
appProjectRoot: string;
|
||||
parsedTags: string[];
|
||||
outputPath: string;
|
||||
}
|
||||
|
||||
function getWebpackBuildConfig(
|
||||
@ -67,10 +68,7 @@ function getWebpackBuildConfig(
|
||||
options: {
|
||||
target: 'node',
|
||||
compiler: 'tsc',
|
||||
outputPath: joinPathFragments(
|
||||
'dist',
|
||||
options.rootProject ? options.name : options.appProjectRoot
|
||||
),
|
||||
outputPath: options.outputPath,
|
||||
main: joinPathFragments(
|
||||
project.sourceRoot,
|
||||
'main' + (options.js ? '.js' : '.ts')
|
||||
@ -101,10 +99,7 @@ function getEsBuildConfig(
|
||||
defaultConfiguration: 'production',
|
||||
options: {
|
||||
platform: 'node',
|
||||
outputPath: joinPathFragments(
|
||||
'dist',
|
||||
options.rootProject ? options.name : options.appProjectRoot
|
||||
),
|
||||
outputPath: options.outputPath,
|
||||
// Use CJS for Node apps for widest compatibility.
|
||||
format: ['cjs'],
|
||||
bundle: false,
|
||||
@ -199,10 +194,7 @@ function addAppFiles(tree: Tree, options: NormalizedSchema) {
|
||||
),
|
||||
webpackPluginOptions: hasWebpackPlugin(tree)
|
||||
? {
|
||||
outputPath: joinPathFragments(
|
||||
'dist',
|
||||
options.rootProject ? options.name : options.appProjectRoot
|
||||
),
|
||||
outputPath: options.outputPath,
|
||||
main: './src/main' + (options.js ? '.js' : '.ts'),
|
||||
tsConfig: './tsconfig.app.json',
|
||||
assets: ['./src/assets'],
|
||||
@ -562,6 +554,10 @@ async function normalizeOptions(
|
||||
unitTestRunner: options.unitTestRunner ?? 'jest',
|
||||
rootProject: options.rootProject ?? false,
|
||||
port: options.port ?? 3000,
|
||||
outputPath: joinPathFragments(
|
||||
'dist',
|
||||
options.rootProject ? options.name : appProjectRoot
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -3,4 +3,5 @@ export interface SetUpDockerOptions {
|
||||
targetName?: string;
|
||||
buildTarget?: string;
|
||||
skipFormat?: boolean;
|
||||
outputPath: string;
|
||||
}
|
||||
|
||||
@ -24,6 +24,10 @@
|
||||
"description": "The name of the build target",
|
||||
"type": "string",
|
||||
"default": "build"
|
||||
},
|
||||
"outputPath": {
|
||||
"description": "The output path for the node application",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,11 +1,6 @@
|
||||
import 'nx/src/internal-testing-utils/mock-project-graph';
|
||||
|
||||
import {
|
||||
ProjectConfiguration,
|
||||
readProjectConfiguration,
|
||||
Tree,
|
||||
} from '@nx/devkit';
|
||||
import { readProjectConfiguration, Tree } from '@nx/devkit';
|
||||
import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
|
||||
import { applicationGenerator } from '../application/application';
|
||||
|
||||
describe('setupDockerGenerator', () => {
|
||||
let tree: Tree;
|
||||
@ -18,15 +13,6 @@ describe('setupDockerGenerator', () => {
|
||||
describe('integrated', () => {
|
||||
it('should create docker assets when --docker is passed', async () => {
|
||||
const projectName = 'integreated-api';
|
||||
// Since we mock the project graph, we need to mock the project configuration as well
|
||||
mockReadCachedProjectConfiguration({
|
||||
name: projectName,
|
||||
root: projectName,
|
||||
});
|
||||
|
||||
const { applicationGenerator } = await import(
|
||||
'../application/application'
|
||||
);
|
||||
|
||||
await applicationGenerator(tree, {
|
||||
name: projectName,
|
||||
@ -56,11 +42,7 @@ describe('setupDockerGenerator', () => {
|
||||
describe('standalone', () => {
|
||||
it('should create docker assets when --docker is passed', async () => {
|
||||
const projectName = 'standalone-api';
|
||||
mockReadCachedProjectConfiguration({ name: projectName, root: '' });
|
||||
|
||||
const { applicationGenerator } = await import(
|
||||
'../application/application'
|
||||
);
|
||||
await applicationGenerator(tree, {
|
||||
name: projectName,
|
||||
framework: 'fastify',
|
||||
@ -86,23 +68,3 @@ describe('setupDockerGenerator', () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
const mockReadCachedProjectConfiguration = (
|
||||
projectConfig: ProjectConfiguration
|
||||
) => {
|
||||
jest.mock('nx/src/project-graph/project-graph', () => {
|
||||
return {
|
||||
...jest.requireActual('nx/src/project-graph/project-graph'),
|
||||
readCachedProjectConfiguration: jest.fn(() => {
|
||||
return {
|
||||
root: projectConfig.root,
|
||||
targets: {
|
||||
build: {
|
||||
outputs: [`dist/${projectConfig.name}`],
|
||||
},
|
||||
},
|
||||
};
|
||||
}),
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
@ -3,8 +3,6 @@ import {
|
||||
generateFiles,
|
||||
GeneratorCallback,
|
||||
joinPathFragments,
|
||||
logger,
|
||||
ProjectConfiguration,
|
||||
readNxJson,
|
||||
readProjectConfiguration,
|
||||
runTasksInSerial,
|
||||
@ -14,8 +12,6 @@ import {
|
||||
|
||||
import { SetUpDockerOptions } from './schema';
|
||||
import { join } from 'path';
|
||||
import { interpolate } from 'nx/src/tasks-runner/utils';
|
||||
import { readCachedProjectConfiguration } from 'nx/src/project-graph/project-graph';
|
||||
|
||||
function normalizeOptions(
|
||||
tree: Tree,
|
||||
@ -30,47 +26,15 @@ function normalizeOptions(
|
||||
}
|
||||
|
||||
function addDocker(tree: Tree, options: SetUpDockerOptions) {
|
||||
// Inferred targets are only available in the project graph
|
||||
const projectConfig = readCachedProjectConfiguration(options.project);
|
||||
|
||||
if (
|
||||
!projectConfig ||
|
||||
!projectConfig.targets ||
|
||||
!projectConfig.targets[options.buildTarget]
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Returns an string like {workspaceRoot}/dist/apps/{projectName}
|
||||
// Non crystalized projects would return {options.outputPath}
|
||||
const tokenizedOutputPath =
|
||||
projectConfig.targets[`${options.buildTarget}`]?.outputs?.[0];
|
||||
const maybeBuildOptions =
|
||||
projectConfig.targets[`${options.buildTarget}`]?.options;
|
||||
|
||||
if (tree.exists(joinPathFragments(projectConfig.root, 'DockerFile'))) {
|
||||
logger.info(
|
||||
`Skipping setup since a Dockerfile already exists inside ${projectConfig.root}`
|
||||
);
|
||||
} else if (!tokenizedOutputPath) {
|
||||
logger.error(
|
||||
`Skipping setup since the output path for the build target ${options.buildTarget} is not defined.`
|
||||
);
|
||||
} else {
|
||||
const outputPath = interpolate(tokenizedOutputPath, {
|
||||
projectName: projectConfig.name,
|
||||
projectRoot: projectConfig.root,
|
||||
workspaceRoot: '',
|
||||
options: maybeBuildOptions || '',
|
||||
});
|
||||
|
||||
generateFiles(tree, join(__dirname, './files'), projectConfig.root, {
|
||||
tmpl: '',
|
||||
app: projectConfig.sourceRoot,
|
||||
buildLocation: outputPath,
|
||||
project: options.project,
|
||||
});
|
||||
const projectConfig = readProjectConfiguration(tree, options.project);
|
||||
if (!projectConfig) {
|
||||
throw new Error(`Cannot find project configuration for ${options.project}`);
|
||||
}
|
||||
generateFiles(tree, join(__dirname, './files'), projectConfig.root, {
|
||||
tmpl: '',
|
||||
buildLocation: options.outputPath,
|
||||
project: options.project,
|
||||
});
|
||||
}
|
||||
|
||||
export function updateProjectConfig(tree: Tree, options: SetUpDockerOptions) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user