@stencil/react-output-target
Version:
React output target for @stencil/core components.
1 lines • 14.1 kB
Source Map (JSON)
{"version":3,"file":"wizard.cjs","sources":["../src/wizard.ts"],"sourcesContent":["import type { StencilWizardPlugin, WizardContext } from '@stencil/cli';\nimport { access, mkdir, writeFile } from 'node:fs/promises';\nimport { join, relative, dirname } from 'node:path';\n\n// ---------------------------------------------------------------------------\n// Wrapper package scaffolding\n// ---------------------------------------------------------------------------\n\nasync function pathExists(p: string): Promise<boolean> {\n try {\n await access(p);\n return true;\n } catch {\n return false;\n }\n}\n\nasync function scaffoldWrapperPackage(\n wrapperDir: string,\n packageName: string,\n corePackageName: string,\n corePkgVersion: string\n): Promise<void> {\n await mkdir(join(wrapperDir, 'src'), { recursive: true });\n\n const pkgJson = {\n name: packageName,\n version: '0.0.1',\n type: 'module',\n main: './dist/index.js',\n types: './dist/index.d.ts',\n exports: { '.': { types: './dist/index.d.ts', import: './dist/index.js' } },\n scripts: { build: 'tsc', dev: 'tsc --watch' },\n peerDependencies: {\n react: '^18 || ^19',\n 'react-dom': '^18 || ^19',\n },\n dependencies: { [corePackageName]: corePkgVersion },\n devDependencies: { typescript: '>=4 <7' },\n };\n\n const tsConfig = {\n compilerOptions: {\n target: 'ES2022',\n module: 'esnext',\n moduleResolution: 'bundler',\n declaration: true,\n rootDir: 'src',\n outDir: 'dist',\n strict: true,\n skipLibCheck: true,\n },\n include: ['src/**/*.ts', 'src/**/*.tsx'],\n };\n\n // components.ts lives at src/components.ts — generated by stencil build\n const indexTs =\n `// Re-exports React wrappers generated by @stencil/react-output-target.\\n` +\n `// src/components.ts is populated by \\`stencil build\\` — do not edit manually.\\n` +\n `export * from './components.js';\\n`;\n\n await Promise.all([\n writeFile(join(wrapperDir, '.gitignore'), 'dist/\\nnode_modules/\\n', 'utf8'),\n writeFile(join(wrapperDir, 'package.json'), JSON.stringify(pkgJson, null, 2) + '\\n', 'utf8'),\n writeFile(join(wrapperDir, 'tsconfig.json'), JSON.stringify(tsConfig, null, 2) + '\\n', 'utf8'),\n writeFile(join(wrapperDir, 'src', 'index.ts'), indexTs, 'utf8'),\n ]);\n}\n\n// ---------------------------------------------------------------------------\n// Wizard\n// ---------------------------------------------------------------------------\n\nexport const wizard = {\n init: {\n id: '@stencil/react-output-target',\n displayName: 'React',\n description: 'Type-safe React wrappers for your Stencil components',\n\n async run({ config, workspaceRoot, prompts, nypm, openStencilConfig }: WizardContext): Promise<void> {\n const { intro, outro, text, confirm, spinner, isCancel, cancel, log } = prompts;\n\n intro('React output target');\n\n // Guard: already configured?\n const editor = await openStencilConfig();\n const alreadyConfigured = editor.outputTargetsContains('reactOutputTarget(');\n\n if (alreadyConfigured) {\n const redo = await confirm({\n message: 'reactOutputTarget is already in stencil.config.ts — reconfigure?',\n initialValue: false,\n });\n if (isCancel(redo) || !redo) {\n cancel('Skipping React setup.');\n return;\n }\n }\n\n // Where should the wrapper package live?\n let wrapperDir: string;\n let wrapperPackageName = `${config.fsNamespace}-react`;\n\n if (workspaceRoot) {\n const rawName = await text({\n message: 'Wrapper package name?',\n placeholder: wrapperPackageName,\n defaultValue: wrapperPackageName,\n });\n if (isCancel(rawName)) {\n cancel('Setup cancelled.');\n return;\n }\n wrapperPackageName = rawName as string;\n // Directory is already namespaced by living under packages/, so keep it\n // short rather than repeating the fsNamespace prefix from the package name.\n wrapperDir = join(dirname(config.rootDir), 'react');\n } else {\n const defaultRel = `../${config.fsNamespace}-react`;\n const rawDir = await text({\n message: 'Wrapper package directory? (relative to stencil.config.ts)',\n placeholder: defaultRel,\n defaultValue: defaultRel,\n });\n if (isCancel(rawDir)) {\n cancel('Setup cancelled.');\n return;\n }\n wrapperDir = join(config.rootDir, rawDir as string);\n }\n\n // Derive the stencil.config-relative outDir from the wrapper location\n const outDir = relative(config.rootDir, join(wrapperDir, 'src')).replace(/\\\\/g, '/');\n\n // SSR\n const enableSsr = await confirm({ message: 'Enable server-side rendering (SSR)?', initialValue: false });\n if (isCancel(enableSsr)) {\n cancel('Setup cancelled.');\n return;\n }\n\n // When not in a known monorepo, ask for the npm package name separately if SSR needs it\n if (enableSsr && !workspaceRoot) {\n const rawPkgName = await text({\n message: 'React wrapper npm package name? (used as clientModule in the SSR config)',\n placeholder: wrapperPackageName,\n defaultValue: wrapperPackageName,\n });\n if (isCancel(rawPkgName)) {\n cancel('Setup cancelled.');\n return;\n }\n wrapperPackageName = rawPkgName as string;\n }\n\n // Scaffold wrapper package if the directory doesn't exist yet\n const shouldScaffold = !(await pathExists(wrapperDir));\n if (shouldScaffold) {\n const s = spinner();\n s.start(`Scaffolding wrapper package at ${relative(workspaceRoot ?? config.rootDir, wrapperDir)}`);\n try {\n // workspace:* only resolves under pnpm/yarn-berry/bun — npm and yarn classic reject\n // the protocol outright (even for devDependencies that are never installed), so only\n // use it when the detected package manager actually understands it.\n const pm = workspaceRoot ? await nypm.detectPackageManager(workspaceRoot) : undefined;\n const supportsWorkspaceProtocol =\n pm?.name === 'pnpm' || pm?.name === 'bun' || (pm?.name === 'yarn' && pm.majorVersion !== '1');\n const corePkgVersion = supportsWorkspaceProtocol\n ? 'workspace:*'\n : `file:${relative(wrapperDir, config.rootDir).replace(/\\\\/g, '/')}`;\n await scaffoldWrapperPackage(wrapperDir, wrapperPackageName, config.fsNamespace, corePkgVersion);\n s.stop('Wrapper package scaffolded');\n } catch (e) {\n s.stop('Scaffolding failed — continuing');\n log.warn(`Could not scaffold wrapper package: ${e}`);\n }\n }\n\n // Build the output target code\n const targetCode = enableSsr\n ? `reactOutputTarget({\\n outDir: '${outDir}',\\n hydrateModule: '${config.fsNamespace}/dist/ssr',\\n clientModule: '${wrapperPackageName}',\\n })`\n : `reactOutputTarget({ outDir: '${outDir}' })`;\n\n // Amend stencil.config.ts\n try {\n editor.addImport('@stencil/react-output-target', ['reactOutputTarget']);\n\n const hasStandalone =\n editor.outputTargetsContains(\"type: 'standalone'\") ||\n editor.outputTargetsContains('type: \"standalone\"') ||\n editor.outputTargetsContains(\"type: 'dist-custom-elements'\") ||\n editor.outputTargetsContains('type: \"dist-custom-elements\"');\n if (!hasStandalone) editor.addOutputTarget(\"{ type: 'standalone' }\");\n\n if (enableSsr) {\n const hasSSR =\n editor.outputTargetsContains(\"type: 'ssr'\") ||\n editor.outputTargetsContains('type: \"ssr\"') ||\n editor.outputTargetsContains(\"type: 'dist-hydrate-script'\") ||\n editor.outputTargetsContains('type: \"dist-hydrate-script\"');\n if (!hasSSR) editor.addOutputTarget(\"{ type: 'ssr' }\");\n }\n\n if (!editor.replaceOutputTarget('reactOutputTarget(', targetCode)) {\n editor.addOutputTarget(targetCode);\n }\n\n await editor.save();\n log.success('stencil.config.ts updated');\n } catch (e) {\n log.warn(\n `Could not automatically update stencil.config.ts (${e}). Add manually:\\n\\n` +\n `import { reactOutputTarget } from '@stencil/react-output-target';\\n` +\n `// in outputTargets:\\n${targetCode}` +\n (enableSsr ? `\\n{ type: 'ssr' }` : '')\n );\n }\n\n // Install @stencil/react-output-target as a devDep of the core package\n log.info('Installing @stencil/react-output-target...');\n await nypm.addDependency(['@stencil/react-output-target'], { cwd: config.rootDir, dev: true });\n log.success('Installed @stencil/react-output-target');\n\n // Install React peer deps in the wrapper package\n if (shouldScaffold && (await pathExists(wrapperDir))) {\n log.info('Installing React peer dependencies in wrapper package...');\n await nypm.addDependency(['@stencil/react-output-target'], { cwd: wrapperDir, dev: true });\n await nypm.addDependency(['react', 'react-dom', '@types/react', '@types/react-dom', 'typescript'], {\n cwd: wrapperDir,\n dev: true,\n });\n log.success('React peer dependencies installed');\n }\n\n outro('React output target configured');\n },\n },\n} satisfies StencilWizardPlugin;\n"],"names":["pathExists","p","access","scaffoldWrapperPackage","wrapperDir","packageName","corePackageName","corePkgVersion","mkdir","join","pkgJson","tsConfig","writeFile","wizard","config","workspaceRoot","prompts","nypm","openStencilConfig","intro","outro","text","confirm","spinner","isCancel","cancel","log","editor","redo","wrapperPackageName","rawName","dirname","defaultRel","rawDir","outDir","relative","enableSsr","rawPkgName","shouldScaffold","s","pm","e","targetCode"],"mappings":"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"}