From 12a129e3a46a5b7f106f9a21918bcc16eac39b94 Mon Sep 17 00:00:00 2001 From: nberks Date: Fri, 8 May 2020 11:44:40 +0100 Subject: [PATCH] Add ability to specify component generation config parameters --- src/cli/tasks/task-generate.ts | 41 +++++++++++++-------- src/declarations/stencil-public-compiler.ts | 6 +++ 2 files changed, 31 insertions(+), 16 deletions(-) diff --git a/src/cli/tasks/task-generate.ts b/src/cli/tasks/task-generate.ts index 427be4ad385..36d77c01c02 100644 --- a/src/cli/tasks/task-generate.ts +++ b/src/cli/tasks/task-generate.ts @@ -29,14 +29,17 @@ export async function taskGenerate(config: d.Config) { config.flags.unknownArgs.find(arg => !arg.startsWith('-')) || ((await prompt({ name: 'tagName', type: 'text', message: 'Component tag name (dash-case):' })).tagName as string); const { dir, base: componentName } = parse(input); + const prefix = config.componentGeneratorConfig?.prefix; + const componentTag = prefix ? `${prefix}-${componentName}` : `app-${componentName}`; + const styleExt = config.componentGeneratorConfig?.styleFormat || 'css'; - const tagError = validateComponentTag(componentName); + const tagError = validateComponentTag(componentTag); if (tagError) { config.logger.error(tagError); return exit(1); } - const extensionsToGenerate: GeneratableExtension[] = ['tsx', ...(await chooseFilesToGenerate())]; + const extensionsToGenerate: GeneratableExtension[] = ['tsx', ...(await chooseFilesToGenerate(styleExt))]; const testFolder = extensionsToGenerate.some(isTest) ? 'test' @@ -46,7 +49,7 @@ export async function taskGenerate(config: d.Config) { await mkdir(join(outDir, testFolder), { recursive: true }); const writtenFiles = await Promise.all( - extensionsToGenerate.map(extension => writeFileByExtension(outDir, componentName, extension, extensionsToGenerate.includes('css'))), + extensionsToGenerate.map(extension => writeFileByExtension(outDir, componentName, componentTag, extension, extensionsToGenerate.includes('css'), styleExt)), ).catch(error => config.logger.error(error)); if (!writtenFiles) { @@ -65,14 +68,14 @@ export async function taskGenerate(config: d.Config) { /** * Show a checkbox prompt to select the files to be generated. */ -const chooseFilesToGenerate = async () => +const chooseFilesToGenerate = async (styleExt: string) => ( await prompt({ name: 'filesToGenerate', type: 'multiselect', message: 'Which additional files do you want to generate?', choices: [ - { value: 'css', title: 'Stylesheet (.css)', selected: true }, + { value: 'css', title: `Stylesheet (.${styleExt})`, selected: true }, { value: 'spec.tsx', title: 'Spec Test (.spec.tsx)', selected: true }, { value: 'e2e.ts', title: 'E2E Test (.e2e.ts)', selected: true }, ] as any[], @@ -82,12 +85,14 @@ const chooseFilesToGenerate = async () => /** * Get a file's boilerplate by its extension and write it to disk. */ -const writeFileByExtension = async (path: string, name: string, extension: GeneratableExtension, withCss: boolean) => { +const writeFileByExtension = async (path: string, name: string, tag: string, extension: GeneratableExtension, withCss: boolean, styleExt: string) => { if (isTest(extension)) { path = join(path, 'test'); } - const outFile = join(path, `${name}.${extension}`); - const boilerplate = getBoilerplateByExtension(name, extension, withCss); + + const ext = isStyle(extension) ? styleExt : extension; + const outFile = join(path, `${name}.${ext}`); + const boilerplate = getBoilerplateByExtension(name, tag, extension, withCss, styleExt); await writeFile(outFile, boilerplate, { flag: 'wx' }); @@ -98,36 +103,40 @@ const isTest = (extension: string) => { return extension === 'e2e.ts' || extension === 'spec.tsx'; }; +const isStyle = (extension: string) => { + return extension === 'css'; +}; + /** * Get the boilerplate for a file by its extension. */ -const getBoilerplateByExtension = (tagName: string, extension: GeneratableExtension, withCss: boolean) => { +const getBoilerplateByExtension = (componentName: string, tagName: string, extension: GeneratableExtension, withCss: boolean, styleExt: string) => { switch (extension) { case 'tsx': - return getComponentBoilerplate(tagName, withCss); + return getComponentBoilerplate(componentName, tagName, withCss, styleExt); case 'css': return getStyleUrlBoilerplate(); case 'spec.tsx': - return getSpecTestBoilerplate(tagName); + return getSpecTestBoilerplate(componentName, tagName); case 'e2e.ts': return getE2eTestBoilerplate(tagName); default: - throw new Error(`Unkown extension "${extension}".`); + throw new Error(`Unknown extension "${extension}".`); } }; /** * Get the boilerplate for a component. */ -const getComponentBoilerplate = (tagName: string, hasStyle: boolean) => { +const getComponentBoilerplate = (componentName: string, tagName: string, hasStyle: boolean, styleExt: string) => { const decorator = [`{`]; decorator.push(` tag: '${tagName}',`); if (hasStyle) { - decorator.push(` styleUrl: '${tagName}.css',`); + decorator.push(` styleUrl: '${componentName}.${styleExt}',`); } decorator.push(` shadow: true,`); decorator.push(`}`); @@ -161,9 +170,9 @@ const getStyleUrlBoilerplate = () => /** * Get the boilerplate for a spec test. */ -const getSpecTestBoilerplate = (tagName: string) => +const getSpecTestBoilerplate = (componentName: string, tagName: string) => `import { newSpecPage } from '@stencil/core/testing'; -import { ${toPascalCase(tagName)} } from './${tagName}'; +import { ${toPascalCase(tagName)} } from '../${componentName}'; describe('${tagName}', () => { it('renders', async () => { diff --git a/src/declarations/stencil-public-compiler.ts b/src/declarations/stencil-public-compiler.ts index 59e411bc4aa..14d417409b8 100644 --- a/src/declarations/stencil-public-compiler.ts +++ b/src/declarations/stencil-public-compiler.ts @@ -249,6 +249,7 @@ export interface StencilConfig { excludeUnusedDependencies?: boolean; typescriptPath?: string; stencilCoreResolvedId?: string; + componentGeneratorConfig?: ComponentGeneratorConfig; } export interface ConfigExtras { @@ -1872,6 +1873,11 @@ export interface ServiceWorkerConfig { handleFetch?: boolean; } +export interface ComponentGeneratorConfig { + prefix?: string; + styleFormat?: string; +} + export interface LoadConfigInit { config?: Config; configPath?: string;