diff --git a/docs/generated/cli/create-nx-workspace.md b/docs/generated/cli/create-nx-workspace.md index 4619195e94..e09e121bdb 100644 --- a/docs/generated/cli/create-nx-workspace.md +++ b/docs/generated/cli/create-nx-workspace.md @@ -31,6 +31,12 @@ Type: `string` The name of the application when a preset with pregenerated app is selected +### bundler + +Type: `string` + +Bundler to be used to build the application + ### ci Type: `string` diff --git a/docs/generated/packages/nx/documents/create-nx-workspace.md b/docs/generated/packages/nx/documents/create-nx-workspace.md index 4619195e94..e09e121bdb 100644 --- a/docs/generated/packages/nx/documents/create-nx-workspace.md +++ b/docs/generated/packages/nx/documents/create-nx-workspace.md @@ -31,6 +31,12 @@ Type: `string` The name of the application when a preset with pregenerated app is selected +### bundler + +Type: `string` + +Bundler to be used to build the application + ### ci Type: `string` diff --git a/docs/generated/packages/workspace/generators/preset.json b/docs/generated/packages/workspace/generators/preset.json index 8d8290f855..2decaa0503 100644 --- a/docs/generated/packages/workspace/generators/preset.json +++ b/docs/generated/packages/workspace/generators/preset.json @@ -62,6 +62,12 @@ "description": "The framework which the application is using", "type": "string", "enum": ["express", "koa", "fastify", "connect"] + }, + "bundler": { + "description": "The bundler to use for building the application.", + "type": "string", + "enum": ["webpack", "vite"], + "default": "vite" } }, "presets": [] diff --git a/e2e/utils/index.ts b/e2e/utils/index.ts index 28f8281c58..b9ddf2b25f 100644 --- a/e2e/utils/index.ts +++ b/e2e/utils/index.ts @@ -160,6 +160,7 @@ export function runCreateWorkspace( ci, useDetectedPm = false, cwd = e2eCwd, + bundler, }: { preset: string; appName?: string; @@ -171,6 +172,7 @@ export function runCreateWorkspace( ci?: 'azure' | 'github' | 'circleci'; useDetectedPm?: boolean; cwd?: string; + bundler?: 'webpack' | 'vite'; } ) { projName = name; @@ -190,6 +192,10 @@ export function runCreateWorkspace( command += ` --ci=${ci}`; } + if (bundler) { + command += ` --bundler=${bundler}`; + } + if (base) { command += ` --defaultBase="${base}"`; } diff --git a/e2e/workspace-create/src/create-nx-workspace.test.ts b/e2e/workspace-create/src/create-nx-workspace.test.ts index 663a68641d..9afb17e70e 100644 --- a/e2e/workspace-create/src/create-nx-workspace.test.ts +++ b/e2e/workspace-create/src/create-nx-workspace.test.ts @@ -39,6 +39,7 @@ describe('create-nx-workspace', () => { appName: wsName, style: 'css', packageManager, + bundler: 'vite', }); checkFilesExist('package.json'); diff --git a/packages/create-nx-workspace/bin/create-nx-workspace.ts b/packages/create-nx-workspace/bin/create-nx-workspace.ts index d7c136a32e..964d81b8f1 100644 --- a/packages/create-nx-workspace/bin/create-nx-workspace.ts +++ b/packages/create-nx-workspace/bin/create-nx-workspace.ts @@ -43,6 +43,7 @@ type Arguments = { name: string; email: string; }; + bundler: 'vite' | 'webpack'; }; enum Preset { @@ -152,6 +153,10 @@ export const commandsObject: yargs.Argv = yargs describe: chalk.dim`Style option to be used when a preset with pregenerated app is selected`, type: 'string', }) + .option('bundler', { + describe: chalk.dim`Bundler to be used to build the application`, + type: 'string', + }) .option('framework', { describe: chalk.dim`Framework option to be used when the node-server preset is selected`, type: 'string', @@ -313,7 +318,7 @@ async function getConfiguration( argv: yargs.Arguments ): Promise { try { - let name, appName, style, preset, framework; + let name, appName, style, preset, framework, bundler; output.log({ title: @@ -360,6 +365,10 @@ async function getConfiguration( if (preset === Preset.NodeServer) { framework = await determineFramework(preset, argv); } + + if (preset === Preset.ReactStandalone) { + bundler = await determineBundler(argv); + } } else { name = await determineRepoName(argv); appName = await determineAppName(preset, argv); @@ -384,6 +393,7 @@ async function getConfiguration( packageManager, defaultBase, ci, + bundler, }); } catch (e) { console.error(e); @@ -836,6 +846,54 @@ async function determineStyle( return Promise.resolve(parsedArgs.style); } +async function determineBundler( + parsedArgs: yargs.Arguments +): Promise<'vite' | 'webpack'> { + const choices = [ + { + name: 'vite', + message: 'Vite [ https://vitejs.dev/ ]', + }, + { + name: 'webpack', + message: 'Webpack [ https://webpack.js.org/ ]', + }, + ]; + + if (!parsedArgs.bundler) { + return enquirer + .prompt([ + { + name: 'bundler', + message: `Bundler to be used to build the application`, + initial: 'vite' as any, + type: 'autocomplete', + choices: choices, + }, + ]) + .then((a: { bundler: 'vite' | 'webpack' }) => a.bundler); + } + + const foundBundler = choices.find( + (choice) => choice.name === parsedArgs.bundler + ); + + if (foundBundler === undefined) { + output.error({ + title: 'Invalid bundler', + bodyLines: [ + `It must be one of the following:`, + '', + ...choices.map((choice) => choice.name), + ], + }); + + process.exit(1); + } + + return Promise.resolve(parsedArgs.bundler); +} + async function determineNxCloud( parsedArgs: yargs.Arguments ): Promise { diff --git a/packages/workspace/src/generators/preset/__snapshots__/preset.spec.ts.snap b/packages/workspace/src/generators/preset/__snapshots__/preset.spec.ts.snap index 38b8d6ecc3..70687f2bcf 100644 --- a/packages/workspace/src/generators/preset/__snapshots__/preset.spec.ts.snap +++ b/packages/workspace/src/generators/preset/__snapshots__/preset.spec.ts.snap @@ -34,3 +34,43 @@ Array [ "nx-welcome.component.ts", ] `; + +exports[`preset should create files (preset = react-standalone bundler = vite) 1`] = ` +Object { + "configurations": Object { + "development": Object { + "buildTarget": "proj:build:development", + "hmr": true, + }, + "production": Object { + "buildTarget": "proj:build:production", + "hmr": false, + }, + }, + "defaultConfiguration": "development", + "executor": "@nrwl/vite:dev-server", + "options": Object { + "buildTarget": "proj:build", + }, +} +`; + +exports[`preset should create files (preset = react-standalone bundler = webpack) 1`] = ` +Object { + "configurations": Object { + "development": Object { + "buildTarget": "proj:build:development", + }, + "production": Object { + "buildTarget": "proj:build:production", + "hmr": false, + }, + }, + "defaultConfiguration": "development", + "executor": "@nrwl/webpack:dev-server", + "options": Object { + "buildTarget": "proj:build", + "hmr": true, + }, +} +`; diff --git a/packages/workspace/src/generators/preset/preset.spec.ts b/packages/workspace/src/generators/preset/preset.spec.ts index 9bbe923168..b684b1629b 100644 --- a/packages/workspace/src/generators/preset/preset.spec.ts +++ b/packages/workspace/src/generators/preset/preset.spec.ts @@ -1,4 +1,4 @@ -import { Tree, readJson, readProjectConfiguration } from '@nrwl/devkit'; +import { Tree, readProjectConfiguration } from '@nrwl/devkit'; import { createTreeWithEmptyV1Workspace } from '@nrwl/devkit/testing'; import { overrideCollectionResolutionForTesting } from '@nrwl/devkit/ngcli-adapter'; import { presetGenerator } from './preset'; @@ -114,4 +114,36 @@ describe('preset', () => { expect(tree.exists('/apps/proj/src/app/App.tsx')).toBe(true); }); + + it(`should create files (preset = ${Preset.ReactStandalone} bundler = webpack)`, async () => { + await presetGenerator(tree, { + name: 'proj', + preset: Preset.ReactStandalone, + style: 'css', + linter: 'eslint', + cli: 'nx', + standaloneConfig: false, + bundler: 'webpack', + }); + expect(tree.exists('webpack.config.js')).toBe(true); + expect( + readProjectConfiguration(tree, 'proj').targets.serve + ).toMatchSnapshot(); + }); + + it(`should create files (preset = ${Preset.ReactStandalone} bundler = vite)`, async () => { + await presetGenerator(tree, { + name: 'proj', + preset: Preset.ReactStandalone, + style: 'css', + linter: 'eslint', + cli: 'nx', + standaloneConfig: false, + bundler: 'vite', + }); + expect(tree.exists('vite.config.ts')).toBe(true); + expect( + readProjectConfiguration(tree, 'proj').targets.serve + ).toMatchSnapshot(); + }); }); diff --git a/packages/workspace/src/generators/preset/preset.ts b/packages/workspace/src/generators/preset/preset.ts index 1662c3924d..ce7fbb9d99 100644 --- a/packages/workspace/src/generators/preset/preset.ts +++ b/packages/workspace/src/generators/preset/preset.ts @@ -68,7 +68,7 @@ async function createPreset(tree: Tree, options: Schema) { linter: options.linter, standaloneConfig: options.standaloneConfig, rootProject: true, - bundler: 'vite', + bundler: options.bundler ?? 'vite', e2eTestRunner: 'cypress', unitTestRunner: 'vitest', }); diff --git a/packages/workspace/src/generators/preset/schema.d.ts b/packages/workspace/src/generators/preset/schema.d.ts index ea7ed2958b..d8d40db04a 100644 --- a/packages/workspace/src/generators/preset/schema.d.ts +++ b/packages/workspace/src/generators/preset/schema.d.ts @@ -11,4 +11,5 @@ export interface Schema { standaloneConfig?: boolean; framework?: string; packageManager?: PackageManager; + bundler?: 'vite' | 'webpack'; } diff --git a/packages/workspace/src/generators/preset/schema.json b/packages/workspace/src/generators/preset/schema.json index 846d120250..e2b337561d 100644 --- a/packages/workspace/src/generators/preset/schema.json +++ b/packages/workspace/src/generators/preset/schema.json @@ -68,6 +68,12 @@ "description": "The framework which the application is using", "type": "string", "enum": ["express", "koa", "fastify", "connect"] + }, + "bundler": { + "description": "The bundler to use for building the application.", + "type": "string", + "enum": ["webpack", "vite"], + "default": "vite" } } }