diff --git a/docs/generated/packages/react.json b/docs/generated/packages/react.json index 66edd8e954cdd3..d70ec3980ee9af 100644 --- a/docs/generated/packages/react.json +++ b/docs/generated/packages/react.json @@ -48,6 +48,11 @@ "type": "boolean", "default": false }, + "skipBabelConfig": { + "description": "Do not generate a root babel.config.json (if babel is not needed).", + "type": "boolean", + "default": false + }, "js": { "type": "boolean", "default": false, @@ -243,7 +248,7 @@ "bundler": { "description": "The bundler to use.", "enum": ["vite", "webpack"], - "x-prompt": "Which bundler do you want to use?", + "x-prompt": "Which bundler do you want to use to build the application?", "default": "webpack" } }, @@ -418,11 +423,16 @@ "description": "Split the project configuration into `/project.json` rather than including it inside `workspace.json`.", "type": "boolean" }, + "bundler": { + "description": "The bundler to use.", + "enum": ["vite", "rollup"], + "default": "rollup" + }, "compiler": { "type": "string", "enum": ["babel", "swc"], "default": "babel", - "description": "Which compiler to use." + "description": "Which compiler to use. Does not apply if bundler is set to Vite." }, "skipPackageJson": { "description": "Do not add dependencies to `package.json`.", diff --git a/docs/generated/packages/vite.json b/docs/generated/packages/vite.json index 5d9932dd397988..999d9fbc48a3eb 100644 --- a/docs/generated/packages/vite.json +++ b/docs/generated/packages/vite.json @@ -60,6 +60,12 @@ "x-dropdown": "project", "x-prompt": "What is the name of the project to set up a webpack for?" }, + "includeLib": { + "type": "boolean", + "description": "Add a library build option.", + "default": false, + "x-prompt": "Does this project contain a buildable library?" + }, "uiFramework": { "type": "string", "description": "UI Framework to use for Vite.", diff --git a/docs/generated/packages/web.json b/docs/generated/packages/web.json index aba85caa4b0e63..d614412071f40a 100644 --- a/docs/generated/packages/web.json +++ b/docs/generated/packages/web.json @@ -53,6 +53,11 @@ "description": "Do not add dependencies to `package.json`.", "type": "boolean", "default": false + }, + "skipBabelConfig": { + "description": "Do not generate a root babel.config.json (if babel is not needed).", + "type": "boolean", + "default": false } }, "required": [], diff --git a/e2e/react/src/react-package.test.ts b/e2e/react/src/react-package.test.ts index 89e39cf70a6492..a25810d88d2598 100644 --- a/e2e/react/src/react-package.test.ts +++ b/e2e/react/src/react-package.test.ts @@ -252,4 +252,20 @@ export async function h() { return 'c'; } }).toThrow(); }, 250000); }); + + it('should support bundling with Vite', async () => { + const libName = uniq('lib'); + + runCLI( + `generate @nrwl/react:lib ${libName} --buildable --bundler=vite --no-interactive` + ); + + const result = await runCLIAsync(`build ${libName}`); + + expect(result).toMatch(/Vite builder finished/); + checkFilesExist( + `dist/libs/${libName}/index.js`, + `dist/libs/${libName}/index.mjs` + ); + }); }); diff --git a/packages/react/src/generators/application/application.spec.ts b/packages/react/src/generators/application/application.spec.ts index 8c612c41d1736a..247cd596521f2d 100644 --- a/packages/react/src/generators/application/application.spec.ts +++ b/packages/react/src/generators/application/application.spec.ts @@ -19,7 +19,6 @@ describe('app', () => { compiler: 'babel', e2eTestRunner: 'cypress', skipFormat: false, - unitTestRunner: 'jest', name: 'myApp', linter: Linter.EsLint, style: 'css', diff --git a/packages/react/src/generators/application/application.ts b/packages/react/src/generators/application/application.ts index cf5ffe7c68e55a..1504bf5cb7b1b2 100644 --- a/packages/react/src/generators/application/application.ts +++ b/packages/react/src/generators/application/application.ts @@ -77,6 +77,7 @@ export async function applicationGenerator(host: Tree, schema: Schema) { const initTask = await reactInitGenerator(host, { ...options, skipFormat: true, + skipBabelConfig: options.bundler === 'vite', }); tasks.push(initTask); @@ -108,9 +109,11 @@ export async function applicationGenerator(host: Tree, schema: Schema) { const cypressTask = await addCypress(host, options); tasks.push(cypressTask); - const jestTask = await addJest(host, options); - tasks.push(jestTask); - updateSpecConfig(host, options); + if (options.unitTestRunner === 'jest') { + const jestTask = await addJest(host, options); + tasks.push(jestTask); + updateSpecConfig(host, options); + } const styledTask = addStyledModuleDependencies(host, options.styledModule); tasks.push(styledTask); const routingTask = addRouting(host, options); diff --git a/packages/react/src/generators/application/lib/normalize-options.ts b/packages/react/src/generators/application/lib/normalize-options.ts index 27e3a60ddd3cbb..cffc5efb7f8646 100644 --- a/packages/react/src/generators/application/lib/normalize-options.ts +++ b/packages/react/src/generators/application/lib/normalize-options.ts @@ -40,20 +40,7 @@ export function normalizeOptions( assertValidStyle(options.style); - if (options.bundler === 'vite') { - options.unitTestRunner = 'vitest'; - } - - options.routing = options.routing ?? false; - options.strict = options.strict ?? true; - options.classComponent = options.classComponent ?? false; - options.unitTestRunner = options.unitTestRunner ?? 'jest'; - options.e2eTestRunner = options.e2eTestRunner ?? 'cypress'; - options.compiler = options.compiler ?? 'babel'; - options.bundler = options.bundler ?? 'webpack'; - options.devServerPort ??= findFreePort(host); - - return { + const normalized = { ...options, name: names(options.name).fileName, projectName: appProjectName, @@ -63,5 +50,18 @@ export function normalizeOptions( fileName, styledModule, hasStyles: options.style !== 'none', - }; + } as NormalizedSchema; + + normalized.routing = normalized.routing ?? false; + normalized.strict = normalized.strict ?? true; + normalized.classComponent = normalized.classComponent ?? false; + normalized.compiler = normalized.compiler ?? 'babel'; + normalized.bundler = normalized.bundler ?? 'webpack'; + normalized.unitTestRunner = + normalized.unitTestRunner ?? + (normalized.bundler === 'vite' ? 'vitest' : 'jest'); + normalized.e2eTestRunner = normalized.e2eTestRunner ?? 'cypress'; + normalized.devServerPort ??= findFreePort(host); + + return normalized; } diff --git a/packages/react/src/generators/application/lib/set-defaults.ts b/packages/react/src/generators/application/lib/set-defaults.ts index 435b9b130753bc..d91fc48782d3ec 100644 --- a/packages/react/src/generators/application/lib/set-defaults.ts +++ b/packages/react/src/generators/application/lib/set-defaults.ts @@ -30,6 +30,7 @@ export function setDefaults(host: Tree, options: NormalizedSchema) { style: options.style, unitTestRunner: options.unitTestRunner, linter: options.linter, + bundler: options.bundler, ...prev.application, }, component: { @@ -40,6 +41,7 @@ export function setDefaults(host: Tree, options: NormalizedSchema) { style: options.style, unitTestRunner: options.unitTestRunner, linter: options.linter, + bundler: options.bundler, ...prev.library, }, }, diff --git a/packages/react/src/generators/application/schema.d.ts b/packages/react/src/generators/application/schema.d.ts index 7d5f4e49c6b07a..ead0831abf0917 100644 --- a/packages/react/src/generators/application/schema.d.ts +++ b/packages/react/src/generators/application/schema.d.ts @@ -7,7 +7,7 @@ export interface Schema { skipFormat: boolean; directory?: string; tags?: string; - unitTestRunner: 'jest' | 'vitest' | 'none'; + unitTestRunner?: 'jest' | 'vitest' | 'none'; inSourceTests?: boolean; /** * @deprecated @@ -41,4 +41,5 @@ export interface NormalizedSchema extends Schema { fileName: string; styledModule: null | SupportedStyles; hasStyles: boolean; + unitTestRunner: 'jest' | 'vitest' | 'none'; } diff --git a/packages/react/src/generators/application/schema.json b/packages/react/src/generators/application/schema.json index 040af31521bd6f..85b2c93bbaa2da 100644 --- a/packages/react/src/generators/application/schema.json +++ b/packages/react/src/generators/application/schema.json @@ -184,7 +184,7 @@ "bundler": { "description": "The bundler to use.", "enum": ["vite", "webpack"], - "x-prompt": "Which bundler do you want to use?", + "x-prompt": "Which bundler do you want to use to build the application?", "default": "webpack" } }, diff --git a/packages/react/src/generators/init/schema.d.ts b/packages/react/src/generators/init/schema.d.ts index 7fccc4697c21c4..65431d3fac869c 100644 --- a/packages/react/src/generators/init/schema.d.ts +++ b/packages/react/src/generators/init/schema.d.ts @@ -1,6 +1,7 @@ export interface InitSchema { unitTestRunner?: 'jest' | 'vitest' | 'none'; e2eTestRunner?: 'cypress' | 'none'; + skipBabelConfig?: boolean; skipFormat?: boolean; skipPackageJson?: boolean; js?: boolean; diff --git a/packages/react/src/generators/init/schema.json b/packages/react/src/generators/init/schema.json index 7fe840439b54f9..458ee719ee2b6b 100644 --- a/packages/react/src/generators/init/schema.json +++ b/packages/react/src/generators/init/schema.json @@ -28,6 +28,11 @@ "type": "boolean", "default": false }, + "skipBabelConfig": { + "description": "Do not generate a root babel.config.json (if babel is not needed).", + "type": "boolean", + "default": false + }, "js": { "type": "boolean", "default": false, diff --git a/packages/react/src/generators/library/files/lib/README.md b/packages/react/src/generators/library/files/common/README.md similarity index 100% rename from packages/react/src/generators/library/files/lib/README.md rename to packages/react/src/generators/library/files/common/README.md diff --git a/packages/react/src/generators/library/files/lib/package.json__tmpl__ b/packages/react/src/generators/library/files/common/package.json__tmpl__ similarity index 100% rename from packages/react/src/generators/library/files/lib/package.json__tmpl__ rename to packages/react/src/generators/library/files/common/package.json__tmpl__ diff --git a/packages/react/src/generators/library/files/lib/src/index.ts__tmpl__ b/packages/react/src/generators/library/files/common/src/index.ts__tmpl__ similarity index 100% rename from packages/react/src/generators/library/files/lib/src/index.ts__tmpl__ rename to packages/react/src/generators/library/files/common/src/index.ts__tmpl__ diff --git a/packages/react/src/generators/library/files/lib/tsconfig.json__tmpl__ b/packages/react/src/generators/library/files/common/tsconfig.json__tmpl__ similarity index 100% rename from packages/react/src/generators/library/files/lib/tsconfig.json__tmpl__ rename to packages/react/src/generators/library/files/common/tsconfig.json__tmpl__ diff --git a/packages/react/src/generators/library/files/lib/tsconfig.lib.json__tmpl__ b/packages/react/src/generators/library/files/common/tsconfig.lib.json__tmpl__ similarity index 100% rename from packages/react/src/generators/library/files/lib/tsconfig.lib.json__tmpl__ rename to packages/react/src/generators/library/files/common/tsconfig.lib.json__tmpl__ diff --git a/packages/react/src/generators/library/files/lib/.babelrc__tmpl__ b/packages/react/src/generators/library/files/rollup-babel/.babelrc__tmpl__ similarity index 100% rename from packages/react/src/generators/library/files/lib/.babelrc__tmpl__ rename to packages/react/src/generators/library/files/rollup-babel/.babelrc__tmpl__ diff --git a/packages/react/src/generators/library/files/vite/index.html__tmpl__ b/packages/react/src/generators/library/files/vite/index.html__tmpl__ new file mode 100644 index 00000000000000..4c4c81ceb583c2 --- /dev/null +++ b/packages/react/src/generators/library/files/vite/index.html__tmpl__ @@ -0,0 +1,15 @@ + + + + + <%= className %> Demo + + + + + + +
+ + + diff --git a/packages/react/src/generators/library/files/vite/src/demo.tsx__tmpl__ b/packages/react/src/generators/library/files/vite/src/demo.tsx__tmpl__ new file mode 100644 index 00000000000000..617f6a880e9acf --- /dev/null +++ b/packages/react/src/generators/library/files/vite/src/demo.tsx__tmpl__ @@ -0,0 +1,19 @@ +/* + * This a a demo file that can be helpful when developing components by serving and interacting with them in the browser. + */ +<% if (component) { %> +import * as ReactDOM from 'react-dom/client'; +import { <%= className %> } from './index'; + +const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement); +root.render( + <<%= className %> /> +); +<% } else { %> +import * as ReactDOM from 'react-dom/client'; + +const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement); +root.render( +

<%= className %> Demo

+); +<% } %> \ No newline at end of file diff --git a/packages/react/src/generators/library/library.ts b/packages/react/src/generators/library/library.ts index 25d4c356b7fcc3..83a0e834a920cd 100644 --- a/packages/react/src/generators/library/library.ts +++ b/packages/react/src/generators/library/library.ts @@ -44,10 +44,10 @@ import { typesReactRouterDomVersion, } from '../../utils/versions'; import componentGenerator from '../component/component'; -import init from '../init/init'; +import initGenerator from '../init/init'; import { Schema } from './schema'; import { updateJestConfigContent } from '../../utils/jest-utils'; -import { vitestGenerator } from '@nrwl/vite'; +import { viteConfigurationGenerator, vitestGenerator } from '@nrwl/vite'; export interface NormalizedSchema extends Schema { name: string; fileName: string; @@ -72,10 +72,11 @@ export async function libraryGenerator(host: Tree, schema: Schema) { options.style = 'none'; } - const initTask = await init(host, { + const initTask = await initGenerator(host, { ...options, e2eTestRunner: 'none', skipFormat: true, + skipBabelConfig: options.bundler === 'vite', }); tasks.push(initTask); @@ -90,6 +91,17 @@ export async function libraryGenerator(host: Tree, schema: Schema) { updateBaseTsConfig(host, options); } + if (options.buildable && options.bundler === 'vite') { + const viteTask = await viteConfigurationGenerator(host, { + uiFramework: 'react', + project: options.name, + newProject: true, + includeLib: true, + includeVitest: true, + }); + tasks.push(viteTask); + } + if (options.unitTestRunner === 'jest') { const jestTask = await jestProjectGenerator(host, { ...options, @@ -110,7 +122,10 @@ export async function libraryGenerator(host: Tree, schema: Schema) { ); host.write(jestConfigPath, updatedContent); } - } else if (options.unitTestRunner === 'vitest') { + } else if ( + options.unitTestRunner === 'vitest' && + options.bundler !== 'vite' // tests are already configured if bundler is vite + ) { const vitestTask = await vitestGenerator(host, { uiFramework: 'react', project: options.name, @@ -299,22 +314,37 @@ function updateBaseTsConfig(host: Tree, options: NormalizedSchema) { } function createFiles(host: Tree, options: NormalizedSchema) { + const substitutions = { + ...options, + ...names(options.name), + tmpl: '', + offsetFromRoot: offsetFromRoot(options.projectRoot), + rootTsConfigPath: getRelativePathToRootTsConfig(host, options.projectRoot), + }; + generateFiles( host, - joinPathFragments(__dirname, './files/lib'), + joinPathFragments(__dirname, './files/common'), options.projectRoot, - { - ...options, - ...names(options.name), - tmpl: '', - offsetFromRoot: offsetFromRoot(options.projectRoot), - rootTsConfigPath: getRelativePathToRootTsConfig( - host, - options.projectRoot - ), - } + substitutions ); + if (options.bundler === 'vite') { + generateFiles( + host, + joinPathFragments(__dirname, './files/vite'), + options.projectRoot, + substitutions + ); + } else if (options.bundler === 'rollup' && options.compiler === 'babel') { + generateFiles( + host, + joinPathFragments(__dirname, './files/rollup-babel'), + options.projectRoot, + substitutions + ); + } + if (!options.publishable && !options.buildable) { host.delete(`${options.projectRoot}/package.json`); } @@ -435,6 +465,9 @@ function normalizeOptions(host: Tree, options: Schema): NormalizedSchema { const normalized: NormalizedSchema = { ...options, + buildable: options.buildable || options.publishable, + compiler: options.compiler ?? 'babel', + bundler: options.bundler ?? 'rollup', fileName, routePath: `/${name}`, name: projectName, @@ -444,6 +477,12 @@ function normalizeOptions(host: Tree, options: Schema): NormalizedSchema { importPath, }; + // If lib is not buildable then there is no reason to use a bundler or compiler. + if (!normalized.buildable) { + delete normalized.compiler; + delete normalized.bundler; + } + if (options.appProject) { const appProjectConfig = getProjects(host).get(options.appProject); diff --git a/packages/react/src/generators/library/schema.d.ts b/packages/react/src/generators/library/schema.d.ts index 9adde64ac382d8..0a9cd0bbe805a0 100644 --- a/packages/react/src/generators/library/schema.d.ts +++ b/packages/react/src/generators/library/schema.d.ts @@ -24,5 +24,6 @@ export interface Schema { setParserOptionsProject?: boolean; standaloneConfig?: boolean; compiler?: 'babel' | 'swc'; + bundler?: 'rollup' | 'vite'; skipPackageJson?: boolean; } diff --git a/packages/react/src/generators/library/schema.json b/packages/react/src/generators/library/schema.json index ff4ade44655507..f0efb39396bae8 100644 --- a/packages/react/src/generators/library/schema.json +++ b/packages/react/src/generators/library/schema.json @@ -161,11 +161,16 @@ "description": "Split the project configuration into `/project.json` rather than including it inside `workspace.json`.", "type": "boolean" }, + "bundler": { + "description": "The bundler to use.", + "enum": ["vite", "rollup"], + "default": "rollup" + }, "compiler": { "type": "string", "enum": ["babel", "swc"], "default": "babel", - "description": "Which compiler to use." + "description": "Which compiler to use. Does not apply if bundler is set to Vite." }, "skipPackageJson": { "description": "Do not add dependencies to `package.json`.", diff --git a/packages/vite/src/generators/configuration/configuration.spec.ts b/packages/vite/src/generators/configuration/configuration.spec.ts index c95a8b30d49205..d64756800e1296 100644 --- a/packages/vite/src/generators/configuration/configuration.spec.ts +++ b/packages/vite/src/generators/configuration/configuration.spec.ts @@ -1,4 +1,9 @@ -import { addDependenciesToPackageJson, readJson, Tree } from '@nrwl/devkit'; +import { + addDependenciesToPackageJson, + addProjectConfiguration, + readJson, + Tree, +} from '@nrwl/devkit'; import { createTreeWithEmptyV1Workspace } from '@nrwl/devkit/testing'; import { nxVersion } from '../../utils/versions'; @@ -116,4 +121,27 @@ describe('@nrwl/vite:configuration', () => { expect(viteConfig).toContain('test'); }); }); + + describe('library mode', () => { + beforeEach(async () => { + tree = createTreeWithEmptyV1Workspace(); + addProjectConfiguration(tree, 'my-lib', { + root: 'my-lib', + }); + }); + + it('should add config for building library', async () => { + await viteConfigurationGenerator(tree, { + uiFramework: 'react', + mode: 'lib', + project: 'my-lib', + newProject: true, + }); + + const viteConfig = tree.read('my-lib/vite.config.ts').toString(); + + expect(viteConfig).toMatch('build: {'); + expect(viteConfig).toMatch("external: ['react']"); + }); + }); }); diff --git a/packages/vite/src/generators/configuration/schema.d.ts b/packages/vite/src/generators/configuration/schema.d.ts index 40b05c200d841c..9533d025cff33e 100644 --- a/packages/vite/src/generators/configuration/schema.d.ts +++ b/packages/vite/src/generators/configuration/schema.d.ts @@ -4,4 +4,5 @@ export interface Schema { newProject?: boolean; includeVitest?: boolean; inSourceTests?: boolean; + includeLib?: boolean; } diff --git a/packages/vite/src/generators/configuration/schema.json b/packages/vite/src/generators/configuration/schema.json index 1aab0f1df1336b..c48db6c5e745a4 100644 --- a/packages/vite/src/generators/configuration/schema.json +++ b/packages/vite/src/generators/configuration/schema.json @@ -16,6 +16,12 @@ "x-dropdown": "project", "x-prompt": "What is the name of the project to set up a webpack for?" }, + "includeLib": { + "type": "boolean", + "description": "Add a library build option.", + "default": false, + "x-prompt": "Does this project contain a buildable library?" + }, "uiFramework": { "type": "string", "description": "UI Framework to use for Vite.", diff --git a/packages/vite/src/generators/vitest/vitest.spec.ts b/packages/vite/src/generators/vitest/vitest.spec.ts index 9d2eb82821ae7d..e3cec79a5d7610 100644 --- a/packages/vite/src/generators/vitest/vitest.spec.ts +++ b/packages/vite/src/generators/vitest/vitest.spec.ts @@ -116,6 +116,7 @@ describe('vitest generator', () => { }), ], + test: { globals: true, environment: 'jsdom', diff --git a/packages/vite/src/utils/generator-utils.ts b/packages/vite/src/utils/generator-utils.ts index 46623ffc3a38f2..f52bbf260910cf 100644 --- a/packages/vite/src/utils/generator-utils.ts +++ b/packages/vite/src/utils/generator-utils.ts @@ -150,21 +150,23 @@ export function addOrChangeBuildTarget( options: buildOptions, configurations: { development: {}, - production: { - fileReplacements: [ - { - replace: joinPathFragments( - project.sourceRoot, - 'environments/environment.ts' - ), - with: joinPathFragments( - project.sourceRoot, - 'environments/environment.prod.ts' - ), + production: options.includeLib + ? {} + : { + fileReplacements: [ + { + replace: joinPathFragments( + project.sourceRoot, + 'environments/environment.ts' + ), + with: joinPathFragments( + project.sourceRoot, + 'environments/environment.prod.ts' + ), + }, + ], + sourceMap: false, }, - ], - sourceMap: false, - }, }, }; } @@ -356,17 +358,40 @@ export function writeViteConfig(tree: Tree, options: Schema) { let viteConfigContent = ''; - const testOption = `test: { + const testOption = options.includeVitest + ? `test: { globals: true, environment: 'jsdom', ${ options.inSourceTests ? `includeSource: ['src/**/*.{js,ts,jsx,tsx}']` : '' } - },`; + },` + : ''; - const defineOption = `define: { + const defineOption = options.inSourceTests + ? `define: { 'import.meta.vitest': undefined - },`; + },` + : ''; + + const buildOption = options.includeLib + ? ` + // Configuration for building your library. + // See: https://vitejs.dev/guide/build.html#library-mode + build: { + lib: { + // Could also be a dictionary or array of multiple entry points. + entry: 'src/index.ts', + name: '${options.project}', + fileName: 'index', + formats: ['es', 'cjs'] + }, + rollupOptions: { + // External packages that should not be bundled into your library. + external: [${options.uiFramework === 'react' ? "'react'" : ''}] + } + },` + : ''; switch (options.uiFramework) { case 'react': @@ -384,8 +409,9 @@ ${options.includeVitest ? '/// ' : ''} projects: ['tsconfig.base.json'], }), ], - ${options.inSourceTests ? defineOption : ''} - ${options.includeVitest ? testOption : ''} + ${buildOption} + ${defineOption} + ${testOption} });`; break; case 'none': @@ -401,8 +427,9 @@ ${options.includeVitest ? '/// ' : ''} projects: ['tsconfig.base.json'], }), ], - ${options.inSourceTests ? defineOption : ''} - ${options.includeVitest ? testOption : ''} + ${buildOption} + ${defineOption} + ${testOption} });`; break; default: diff --git a/packages/web/src/generators/application/application.ts b/packages/web/src/generators/application/application.ts index 3e658531b5cde1..70dbf01dad3d0e 100644 --- a/packages/web/src/generators/application/application.ts +++ b/packages/web/src/generators/application/application.ts @@ -192,6 +192,8 @@ export async function applicationGenerator(host: Tree, schema: Schema) { const webTask = await webInitGenerator(host, { ...options, skipFormat: true, + // Vite does not use babel by default + skipBabelConfig: options.bundler === 'vite', }); tasks.push(webTask); diff --git a/packages/web/src/generators/init/init.ts b/packages/web/src/generators/init/init.ts index 3df5faf8b426c9..dfa1ba21492eab 100644 --- a/packages/web/src/generators/init/init.ts +++ b/packages/web/src/generators/init/init.ts @@ -42,14 +42,16 @@ function updateDependencies(tree: Tree, schema: Schema) { ); } -function initRootBabelConfig(tree: Tree) { +function initRootBabelConfig(tree: Tree, schema: Schema) { if (tree.exists('/babel.config.json') || tree.exists('/babel.config.js')) { return; } - writeJson(tree, '/babel.config.json', { - babelrcRoots: ['*'], // Make sure .babelrc files other than root can be loaded in a monorepo - }); + if (!schema.skipBabelConfig) { + writeJson(tree, '/babel.config.json', { + babelrcRoots: ['*'], // Make sure .babelrc files other than root can be loaded in a monorepo + }); + } const workspaceConfiguration = readWorkspaceConfiguration(tree); @@ -80,7 +82,7 @@ export async function webInitGenerator(tree: Tree, schema: Schema) { const installTask = updateDependencies(tree, schema); tasks.push(installTask); } - initRootBabelConfig(tree); + initRootBabelConfig(tree, schema); if (!schema.skipFormat) { await formatFiles(tree); } diff --git a/packages/web/src/generators/init/schema.d.ts b/packages/web/src/generators/init/schema.d.ts index 00c2cc6a747670..7276adf217146c 100644 --- a/packages/web/src/generators/init/schema.d.ts +++ b/packages/web/src/generators/init/schema.d.ts @@ -4,4 +4,5 @@ export interface Schema { e2eTestRunner?: 'cypress' | 'none'; skipFormat?: boolean; skipPackageJson?: boolean; + skipBabelConfig?: boolean; } diff --git a/packages/web/src/generators/init/schema.json b/packages/web/src/generators/init/schema.json index 93f02a32fe7afa..8e7a8daab5367f 100644 --- a/packages/web/src/generators/init/schema.json +++ b/packages/web/src/generators/init/schema.json @@ -33,6 +33,11 @@ "description": "Do not add dependencies to `package.json`.", "type": "boolean", "default": false + }, + "skipBabelConfig": { + "description": "Do not generate a root babel.config.json (if babel is not needed).", + "type": "boolean", + "default": false } }, "required": []