From 6348e3edb645d75d7c3b1c55bf9307ab0998a8aa Mon Sep 17 00:00:00 2001 From: Adam Bradley Date: Mon, 24 May 2021 11:14:40 -0500 Subject: [PATCH] feat(cli): add priority to framework detection --- cli/src/definitions.ts | 8 +++++++ cli/src/framework-configs.ts | 33 +++++++++++++++++++--------- cli/test/framework-detection.spec.ts | 5 ++++- 3 files changed, 35 insertions(+), 11 deletions(-) diff --git a/cli/src/definitions.ts b/cli/src/definitions.ts index f588e7abea..0c56683ce1 100644 --- a/cli/src/definitions.ts +++ b/cli/src/definitions.ts @@ -123,4 +123,12 @@ export interface FrameworkConfig { name: string; isMatch: (config: Config) => boolean; webDir: string; + /** + * Specific UI libraries (Ionic) and higher-level frameworks (NextJs/Gatsby) + * should be prioritorized over a more generic framework like React/Angular/Vue. + * Lower the priorty number the more important it is (1 has more priority over 2). + * This helps to make sure a specific framework like "NextJs" is chosen before + * the more generic "React". + */ + priority: number; } diff --git a/cli/src/framework-configs.ts b/cli/src/framework-configs.ts index 27bb6e1134..2d6abe6387 100644 --- a/cli/src/framework-configs.ts +++ b/cli/src/framework-configs.ts @@ -3,75 +3,88 @@ import type { Config, FrameworkConfig } from './definitions'; const FRAMEWORK_CONFIGS: FrameworkConfig[] = [ { name: 'Angular', - isMatch: config => - hasDependency(config, '@angular/cli') && - !hasDependency(config, '@ionic/angular'), + isMatch: config => hasDependency(config, '@angular/cli'), webDir: 'dist', + priority: 3, }, { name: 'Create React App', - isMatch: config => - hasDependency(config, 'react-scripts') && - !hasDependency(config, '@ionic/react'), + isMatch: config => hasDependency(config, 'react-scripts'), webDir: 'build', + priority: 3, }, { name: 'Ember', isMatch: config => hasDependency(config, 'ember-cli'), webDir: 'dist', + priority: 3, }, { name: 'Gatsby', isMatch: config => hasDependency(config, 'gatsby'), webDir: 'public', + priority: 2, }, { name: 'Ionic Angular', isMatch: config => hasDependency(config, '@ionic/angular'), webDir: 'www', + priority: 1, }, { name: 'Ionic React', isMatch: config => hasDependency(config, '@ionic/react'), webDir: 'build', + priority: 1, }, { name: 'Ionic Vue', isMatch: config => hasDependency(config, '@ionic/vue'), webDir: 'public', + priority: 1, }, { name: 'Next', isMatch: config => hasDependency(config, 'next'), webDir: 'public', + priority: 2, }, { name: 'Preact', isMatch: config => hasDependency(config, 'preact-cli'), webDir: 'build', + priority: 3, }, { name: 'Stencil', isMatch: config => hasDependency(config, '@stencil/core'), webDir: 'www', + priority: 3, }, { name: 'Svelte', isMatch: config => hasDependency(config, 'svelte') && hasDependency(config, 'sirv-cli'), webDir: 'public', + priority: 3, }, { name: 'Vue', - isMatch: config => - hasDependency(config, '@vue/cli-service') && - !hasDependency(config, '@ionic/vue'), + isMatch: config => hasDependency(config, '@vue/cli-service'), webDir: 'dist', + priority: 3, }, ]; export function detectFramework(config: Config): FrameworkConfig | undefined { - return FRAMEWORK_CONFIGS.find(f => f.isMatch(config)); + const frameworks = FRAMEWORK_CONFIGS.filter(f => f.isMatch(config)).sort( + (a, b) => { + if (a.priority < b.priority) return -1; + if (a.priority > b.priority) return 1; + return 0; + }, + ); + return frameworks[0]; } function hasDependency(config: Config, depName: string): boolean { diff --git a/cli/test/framework-detection.spec.ts b/cli/test/framework-detection.spec.ts index e6318fc253..9893cd1887 100644 --- a/cli/test/framework-detection.spec.ts +++ b/cli/test/framework-detection.spec.ts @@ -39,7 +39,7 @@ describe('framework detection', () => { expect(f?.webDir).toBe('dist'); }); - it.only('Create React App', () => { + it('Create React App', () => { addDep(config, 'react-scripts'); const f = detectFramework(config); expect(f?.name).toBe('Create React App'); @@ -54,6 +54,7 @@ describe('framework detection', () => { }); it('Gatsby', () => { + addDep(config, 'react-scripts'); addDep(config, 'gatsby'); const f = detectFramework(config); expect(f?.name).toBe('Gatsby'); @@ -77,6 +78,7 @@ describe('framework detection', () => { it('Ionic React', () => { addDep(config, '@ionic/react'); + addDep(config, 'react-scripts'); const f = detectFramework(config); expect(f?.name).toBe('Ionic React'); expect(f?.webDir).toBe('build'); @@ -108,6 +110,7 @@ describe('framework detection', () => { it('Next', () => { addDep(config, 'next'); + addDep(config, 'react-scripts'); const f = detectFramework(config); expect(f?.name).toBe('Next'); expect(f?.webDir).toBe('public');