UNPKG

@re-shell/cli

Version:

Full-stack development platform uniting microservices and microfrontends. Build complete applications with .NET (ASP.NET Core Web API, Minimal API), Java (Spring Boot, Quarkus, Micronaut, Vert.x), Rust (Actix-Web, Warp, Rocket, Axum), Python (FastAPI, Dja

290 lines (267 loc) 9 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.BaseTemplate = void 0; class BaseTemplate { constructor(framework, context) { this.framework = framework; this.context = context; } generatePackageJson() { const { normalizedName, org, description, port } = this.context; return { name: `@${org.toLowerCase()}/${normalizedName}`, version: '0.1.0', description, main: 'dist/index.js', scripts: { ...this.framework.scripts, dev: this.framework.scripts.dev.replace('vite', `vite --port ${port}`) }, dependencies: this.framework.dependencies, devDependencies: this.framework.devDependencies, keywords: [ 'microfrontend', this.framework.name, 're-shell' ], author: this.context.team || this.context.org, license: 'MIT', reshell: { framework: this.framework.name, route: this.context.route, port: parseInt(port) } }; } generateViteConfig() { const { normalizedName, port, hasTypeScript } = this.context; const entryExt = this.framework.name.includes('vue') ? (hasTypeScript ? 'ts' : 'js') : (hasTypeScript ? 'tsx' : 'jsx'); let plugins = ''; let imports = ''; switch (this.framework.name) { case 'react': case 'react-ts': imports = "import react from '@vitejs/plugin-react';"; plugins = 'react()'; break; case 'vue': case 'vue-ts': imports = "import vue from '@vitejs/plugin-vue';"; plugins = 'vue()'; break; case 'svelte': case 'svelte-ts': imports = "import { svelte } from '@sveltejs/vite-plugin-svelte';"; plugins = 'svelte()'; break; } return `import { defineConfig } from 'vite'; import { resolve } from 'path'; ${imports} export default defineConfig({ plugins: [${plugins}], build: { lib: { entry: resolve(__dirname, 'src/index.${entryExt}'), name: '${normalizedName.charAt(0).toUpperCase() + normalizedName.slice(1).replace(/-./g, x => x[1].toUpperCase())}', formats: ['umd'], fileName: 'mf' }, rollupOptions: { external: [${this.getExternalDependencies().map(dep => `'${dep}'`).join(', ')}], output: { globals: { ${this.getGlobalMappings()} } } } }, server: { port: ${port}, cors: true, headers: { 'Access-Control-Allow-Origin': '*' } } });`; } getExternalDependencies() { switch (this.framework.name) { case 'react': case 'react-ts': return ['react', 'react-dom', '@re-shell/core']; case 'vue': case 'vue-ts': return ['vue', '@re-shell/core']; case 'svelte': case 'svelte-ts': return ['@re-shell/core']; case 'angular': return ['@angular/core', '@angular/common', '@angular/platform-browser', '@re-shell/core']; default: return ['@re-shell/core']; } } getGlobalMappings() { const mappings = { '@re-shell/core': 'ReShell' }; switch (this.framework.name) { case 'react': case 'react-ts': mappings['react'] = 'React'; mappings['react-dom'] = 'ReactDOM'; break; case 'vue': case 'vue-ts': mappings['vue'] = 'Vue'; break; } return Object.entries(mappings) .map(([key, value]) => ` '${key}': '${value}'`) .join(',\n'); } generateTsConfig() { const baseConfig = { compilerOptions: { target: 'ES2020', lib: ['ES2020', 'DOM', 'DOM.Iterable'], allowJs: true, skipLibCheck: true, esModuleInterop: true, allowSyntheticDefaultImports: true, strict: true, forceConsistentCasingInFileNames: true, moduleResolution: 'node', resolveJsonModule: true, isolatedModules: true, noEmit: true, declaration: true, declarationMap: true, sourceMap: true }, include: ['src'], exclude: ['node_modules', 'dist'] }; // Framework-specific TypeScript configuration switch (this.framework.name) { case 'react-ts': baseConfig.compilerOptions.jsx = 'react-jsx'; break; case 'vue-ts': baseConfig.compilerOptions.jsx = 'preserve'; baseConfig.compilerOptions.types = ['vite/client']; break; case 'svelte-ts': baseConfig.compilerOptions.types = ['svelte', 'vite/client']; break; case 'angular': baseConfig.compilerOptions.experimentalDecorators = true; baseConfig.compilerOptions.emitDecoratorMetadata = true; baseConfig.compilerOptions.types = ['node']; break; } return JSON.stringify(baseConfig, null, 2); } generateEslintConfig() { const config = { env: { browser: true, es2021: true, node: true }, extends: ['eslint:recommended'], parserOptions: { ecmaVersion: 'latest', sourceType: 'module' }, rules: {} }; if (this.context.hasTypeScript) { config.extends.push('@typescript-eslint/recommended'); config.parser = '@typescript-eslint/parser'; config.plugins = ['@typescript-eslint']; } switch (this.framework.name) { case 'react': case 'react-ts': config.extends.push('plugin:react/recommended', 'plugin:react-hooks/recommended'); config.plugins = [...(config.plugins || []), 'react', 'react-hooks']; config.settings = { react: { version: 'detect' } }; config.parserOptions.ecmaFeatures = { jsx: true }; break; case 'vue': case 'vue-ts': config.extends.push('plugin:vue/vue3-recommended'); config.plugins = [...(config.plugins || []), 'vue']; break; case 'svelte': case 'svelte-ts': config.extends.push('plugin:svelte/recommended'); config.plugins = [...(config.plugins || []), 'svelte']; break; } return `module.exports = ${JSON.stringify(config, null, 2)};`; } generateReadme() { const { name, normalizedName, route, team, org } = this.context; return `# ${name} A ${this.framework.displayName} microfrontend for the Re-Shell architecture. ## Overview This microfrontend is built with ${this.framework.displayName} and can be integrated into any Re-Shell application. ## Development ### Prerequisites - Node.js >= 16.0.0 - ${this.context.packageManager} ### Installation \`\`\`bash ${this.context.packageManager} install \`\`\` ### Development Server \`\`\`bash ${this.context.packageManager} run dev \`\`\` The development server will start on port ${this.context.port}. ### Building \`\`\`bash ${this.context.packageManager} run build \`\`\` ### Testing \`\`\`bash ${this.context.packageManager} run test \`\`\` ### Linting \`\`\`bash ${this.context.packageManager} run lint \`\`\` ## Integration This microfrontend can be integrated into a Re-Shell application by adding the following configuration: \`\`\`javascript const microfrontendConfig = { id: '${normalizedName}', name: '${name}', url: '/apps/${normalizedName}/dist/mf.umd.js', containerId: '${normalizedName}-container', route: '${route || `/${normalizedName}`}', team: '${team || org}' }; \`\`\` ## Submodule Usage This project can be used as a Git submodule: \`\`\`bash git submodule add <repository-url> apps/${normalizedName} git submodule update --init --recursive \`\`\` ## Framework: ${this.framework.displayName} This microfrontend uses ${this.framework.displayName} with the following build tools: - Build Tool: ${this.framework.buildTool} - Package Manager: ${this.context.packageManager} - TypeScript: ${this.context.hasTypeScript ? 'Yes' : 'No'} ## License MIT `; } } exports.BaseTemplate = BaseTemplate;