diff --git a/.prettierignore b/.prettierignore index b8156aa..77f7bb6 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,14 +1,25 @@ # general +LICENSE .gitignore .keep +# configuration files +.dockerignore +Dockerfile + # package manager pnpm-lock.yaml .npmrc.example # packages .prettierignore +.husky # files *.sh +*.toml *.env* + +# images +*.ico +*.svg diff --git a/packages/builder-rslib/package.json b/packages/builder-rslib/package.json index b7c6ab8..e6edf86 100644 --- a/packages/builder-rslib/package.json +++ b/packages/builder-rslib/package.json @@ -1,6 +1,6 @@ { "name": "@mainset/builder-rslib", - "version": "0.2.0", + "version": "0.3.0-rc.2", "description": "Builder for node packages", "homepage": "https://github.com/mainset/dev-stack-fe/tree/main/packages/builder-rslib", "bugs": { @@ -15,22 +15,24 @@ "type": "module", "sideEffects": false, "files": [ - "dist" + "dist", + "src/@types" ], "exports": { ".": { "types": "./dist/types/index.d.mts", "import": "./dist/esm/index.mjs" - } + }, + "./global-types": "./src/@types/bundler.d.ts" }, "scripts": { "build": "ms-cli source-code --exec compile", "dev": "cross-env NODE_ENV=development ms-cli source-code --exec watch" }, "dependencies": { - "@rsbuild/plugin-react": "^1.4.1", - "@rsbuild/plugin-sass": "^1.4.0", - "@rslib/core": "^0.15.0" + "@rsbuild/plugin-react": "^1.4.5", + "@rsbuild/plugin-sass": "^1.5.0", + "@rslib/core": "^0.20.0" }, "devDependencies": { "@mainset/cli": "workspace:^", diff --git a/packages/builder-rslib/src/@types/bundler.d.ts b/packages/builder-rslib/src/@types/bundler.d.ts new file mode 100644 index 0000000..dc8c2f7 --- /dev/null +++ b/packages/builder-rslib/src/@types/bundler.d.ts @@ -0,0 +1,4 @@ +declare module '*.module.scss' { + const styles: { [className: string]: string }; + export = styles; +} diff --git a/packages/builder-rslib/src/rslib.node-sourcer.config.mts b/packages/builder-rslib/src/rslib.node-sourcer.config.mts index 0a555e7..5c754c5 100644 --- a/packages/builder-rslib/src/rslib.node-sourcer.config.mts +++ b/packages/builder-rslib/src/rslib.node-sourcer.config.mts @@ -16,7 +16,10 @@ const nodeSourcerCommonPresetRslib = defineConfig({ // OutBase: runtimePathById.dist, output: { filename: { - js: 'esm/index.mjs', + js: '[name].mjs', + }, + distPath: { + root: path.join(runtimePathById.dist, 'esm'), }, }, autoExternal: { @@ -32,7 +35,10 @@ const nodeSourcerCommonPresetRslib = defineConfig({ // OutBase: runtimePathById.dist, output: { filename: { - js: 'cjs/index.cjs', + js: '[name].cjs', + }, + distPath: { + root: path.join(runtimePathById.dist, 'cjs'), }, }, autoExternal: { @@ -46,7 +52,10 @@ const nodeSourcerCommonPresetRslib = defineConfig({ ], source: { entry: { - index: [path.join(runtimePathById.src, 'index.mts')], + index: path.join( + runtimePathById.src, + process.env.MS_CLI__RSLIB_BUNDLESS_MODE ? '/**/*' : 'index.mts', + ), }, }, output: { diff --git a/packages/cli/package.json b/packages/cli/package.json index 01dabc3..08e4af0 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@mainset/cli", - "version": "0.4.4", + "version": "0.5.0-rc.2", "description": "A unified CLI tool for accelerating development, based on mainset vision of front-end infrastructure", "homepage": "https://github.com/mainset/dev-stack-fe/tree/main/packages/cli", "bugs": { @@ -15,7 +15,8 @@ "type": "module", "sideEffects": false, "files": [ - "dist" + "dist", + "src/commands/init/templates" ], "exports": { "./runtime": { diff --git a/packages/cli/src/commands/index.mts b/packages/cli/src/commands/index.mts index 5ea353b..de90e2e 100644 --- a/packages/cli/src/commands/index.mts +++ b/packages/cli/src/commands/index.mts @@ -1,3 +1,4 @@ +export * from './init/index.mjs'; export * from './node-sourcer.mjs'; export * from './source-code.mjs'; export * from './web-app.mjs'; diff --git a/packages/cli/src/commands/init/index.mts b/packages/cli/src/commands/init/index.mts new file mode 100644 index 0000000..3fa14c0 --- /dev/null +++ b/packages/cli/src/commands/init/index.mts @@ -0,0 +1 @@ +export * from './init.mjs'; diff --git a/packages/cli/src/commands/init/init.mts b/packages/cli/src/commands/init/init.mts new file mode 100644 index 0000000..13f30c9 --- /dev/null +++ b/packages/cli/src/commands/init/init.mts @@ -0,0 +1,192 @@ +import { Command } from 'commander'; +import { execSync } from 'node:child_process'; +import fs from 'node:fs'; +import path from 'node:path'; +import { stdin as input, stdout as output } from 'node:process'; +import * as readline from 'node:readline/promises'; + +import { runtimePathById } from '../../runtime/index.mjs'; +import { + consoleColorize, + initProcessCatchErrorLogger, +} from '../../utils/index.mjs'; + +async function handleConfigurationDependencies(targetDir: string) { + const rl = readline.createInterface({ input, output }); + + let shouldInstall = true; + try { + const answer = await rl.question( + 'Do you want to install development dependencies (@mainset/dev-stack-fe etc.)? (Y/n) ', + ); + shouldInstall = answer.trim().toLowerCase() !== 'n'; + } catch { + // default true + } + + if (shouldInstall) { + let packageManager = 'npm'; + try { + const answer = await rl.question( + 'Which package manager do you use? (npm/pnpm/yarn/bun/other) [npm]: ', + ); + packageManager = answer.trim().toLowerCase() || 'npm'; + } catch { + // default npm + } + + rl.close(); + + let installCommand = ''; + const packages = [ + '@mainset/dev-stack-fe', + '@mainset/cli', + 'cross-env', + 'eslint', + 'husky', + 'prettier', + 'stylelint', + ].join(' '); + + if (['npm', 'pnpm', 'yarn', 'bun'].includes(packageManager)) { + const cmd = packageManager === 'npm' ? 'install' : 'add'; + installCommand = `${packageManager} ${cmd} -D ${packages}`; + } else { + // assume 'other' is the binary name user typed if not in basic list + installCommand = `${packageManager} i -D ${packages}`; + } + + console.log( + consoleColorize( + 'BLUE', + `\n\nInstalling dependencies with:\n${installCommand}\n`, + ), + ); + + try { + execSync(installCommand, { + cwd: targetDir, + stdio: 'inherit', + env: { ...process.env, NODE_ENV: 'development' }, + }); + console.log( + consoleColorize('BRIGHT_GREEN', 'Dependencies installed successfully.'), + ); + } catch (error) { + console.error( + consoleColorize( + 'BRIGHT_RED', + `\n❌ Failed to install dependencies automatically.`, + ), + ); + console.log( + consoleColorize( + 'BRIGHT_YELLOW', + `Please run the following command manually:\n\n ${installCommand}\n`, + ), + ); + } + // Close readline if not installing + } else { + rl.close(); + } +} + +function registerInitCommand(program: Command) { + program + .command('init [appName]') + .description('Run init project or configuration process') + .option( + '-m, --mode ', + 'Initialization mode: app, package or config', + 'application', + ) + .option('-p, --path ', 'Initialization path', './') + .action(async (appName, options) => { + // Use runtimePathById.root to resolve the target directory relative to the project root + const targetDir = path.resolve( + runtimePathById.root, + options.path, + appName || '', + ); + + if (options.mode === 'application') { + if (!appName) { + console.error( + consoleColorize( + 'BRIGHT_RED', + `\n[mainset cli][init] App name is required for application initialization.`, + ), + ); + process.exit(1); + } + + // ========== Application mode ========== + console.log('\n🏗️ [mainset cli] init: application'); + + try { + // Use runtimePathById.msCLISrc to resolve the template directory relative to the CLI runtime + const templateDir = path.resolve( + runtimePathById.msCLISrc, + '../../../src/commands/init/templates/application', + ); + + if (fs.existsSync(targetDir)) { + console.error( + consoleColorize( + 'BRIGHT_YELLOW', + `\n[mainset cli][init] Directory "${appName}" already exists at "${targetDir}". Aborting.`, + ), + ); + process.exit(1); + } + + fs.cpSync(templateDir, targetDir, { recursive: true }); + + console.log( + `\n✅ Application "${appName}" initialized successfully.\n`, + ); + } catch (error) { + initProcessCatchErrorLogger('init', error, 'application'); + } + } else if (options.mode === 'config') { + // ========== Configuration mode ========== + console.log('\n🏗️ [mainset cli] init: configuration'); + + try { + const templateDir = path.resolve( + runtimePathById.msCLISrc, + '../../../src/commands/init/templates/configuration', + ); + + if (!fs.existsSync(templateDir)) { + console.log( + consoleColorize( + 'BRIGHT_YELLOW', + `\n[mainset cli][init] Configuration template not found at ${templateDir}`, + ), + ); + return; + } + + fs.cpSync(templateDir, targetDir, { recursive: true }); + + console.log('\n✅ Configuration initialized successfully.\n'); + + await handleConfigurationDependencies(targetDir); + } catch (error) { + initProcessCatchErrorLogger('init', error, 'configuration'); + } + } else { + console.error( + consoleColorize( + 'BRIGHT_YELLOW', + `[mainset cli][init] Unknown init mode: "${options.mode}"`, + ), + ); + process.exit(1); + } + }); +} + +export { registerInitCommand }; diff --git a/packages/cli/src/commands/init/templates/application/.env.example b/packages/cli/src/commands/init/templates/application/.env.example new file mode 100644 index 0000000..5a1e770 --- /dev/null +++ b/packages/cli/src/commands/init/templates/application/.env.example @@ -0,0 +1 @@ +API_REMOTE_URL=https://httpbin.org diff --git a/packages/cli/src/commands/init/templates/application/config/proxy.config.d.mts b/packages/cli/src/commands/init/templates/application/config/proxy.config.d.mts new file mode 100644 index 0000000..d22272f --- /dev/null +++ b/packages/cli/src/commands/init/templates/application/config/proxy.config.d.mts @@ -0,0 +1,5 @@ +import type { SSRConfigParams } from '@mainset/cli/ssr-server'; + +declare const proxyConfigByPath: SSRConfigParams['proxyConfigByPath']; + +export default proxyConfigByPath; diff --git a/packages/cli/src/commands/init/templates/application/config/proxy.config.mjs b/packages/cli/src/commands/init/templates/application/config/proxy.config.mjs new file mode 100644 index 0000000..7952dd1 --- /dev/null +++ b/packages/cli/src/commands/init/templates/application/config/proxy.config.mjs @@ -0,0 +1,10 @@ +const proxyConfigByPath = { + '/api-example/': { + context: ['/api-example/'], + target: process.env.API_REMOTE_URL, + pathRewrite: { '^/api-example/': '/' }, + changeOrigin: true, + }, +}; + +export default proxyConfigByPath; diff --git a/packages/cli/src/commands/init/templates/application/config/serve-static.config.mjs b/packages/cli/src/commands/init/templates/application/config/serve-static.config.mjs new file mode 100644 index 0000000..1f0b8ea --- /dev/null +++ b/packages/cli/src/commands/init/templates/application/config/serve-static.config.mjs @@ -0,0 +1,7 @@ +import proxyConfigByPath from './proxy.config.mjs'; + +const serveStaticConfig = { + proxyConfigByPath, +}; + +export default serveStaticConfig; diff --git a/packages/cli/src/commands/init/templates/application/config/ssr-server.config.mts b/packages/cli/src/commands/init/templates/application/config/ssr-server.config.mts new file mode 100644 index 0000000..4e37979 --- /dev/null +++ b/packages/cli/src/commands/init/templates/application/config/ssr-server.config.mts @@ -0,0 +1,57 @@ +import { runtimePathById } from '@mainset/cli/runtime'; +import type { SSRConfigParams } from '@mainset/cli/ssr-server'; +import fs from 'fs'; +import path from 'path'; +import ReactDOMServer from 'react-dom/server'; + +import provideServerReactApp from '../src/app.server'; +// eslint-disable-next-line @typescript-eslint/ban-ts-comment +// @ts-ignore +import proxyConfigByPath from './proxy.config.mjs'; + +const ssrServerConfig: SSRConfigParams = { + serveStatics: [ + { + rootPath: path.join(runtimePathById.dist, 'public'), + }, + ], + proxyConfigByPath, + renderSSRContentByPath: { + '/{*any}': ({ reqUrl, fullUrl }) => + new Promise((resolve, reject) => { + fs.readFile( + path.join(runtimePathById.dist, 'public', 'server.html'), + 'utf8', + async (err, htmlData) => { + if (err) { + return reject(err); + } + + // Const context = {}; // Context to track SSR rendering information + + try { + // Pass both requestUrl (relative) and fullUrl to provider of React App for server-side rendering + const appHtml = await provideServerReactApp({ + reqUrl, + fullUrl, + // Context + }); + + const content = htmlData.replace( + '
', + `
${ReactDOMServer.renderToString( + appHtml, + )}
`, + ); + + return resolve(content); + } catch (error) { + return reject(error); + } + }, + ); + }), + }, +}; + +export default ssrServerConfig; diff --git a/packages/cli/src/commands/init/templates/application/package.json b/packages/cli/src/commands/init/templates/application/package.json new file mode 100644 index 0000000..616a85d --- /dev/null +++ b/packages/cli/src/commands/init/templates/application/package.json @@ -0,0 +1,24 @@ +{ + "engines": { + "node": ">=24.14.0" + }, + "scripts": { + "dev": "cross-env NODE_ENV=development ms-cli web-app --exec serve", + "dev:csr": "cross-env NODE_ENV=development ms-cli web-app --exec serve --serveMode csr", + "build": "ms-cli web-app --exec build", + "build:csr": "ms-cli web-app --exec build --serveMode csr", + "serve": "ms-cli web-app --exec serve-static", + "serve:csr": "ms-cli web-app --exec serve-static --serveMode csr" + }, + "dependencies": { + "react": "^19.2.0", + "react-dom": "^19.2.0" + }, + "devDependencies": { + "@mainset/bundler-webpack": "^0.3.1", + "@mainset/cli": "^0.5.0-rc.1", + "@mainset/dev-stack-fe": "^0.2.0", + "@types/react": "^19.2.2", + "@types/react-dom": "^19.2.1" + } +} diff --git a/packages/cli/src/commands/init/templates/application/src/@types/bundler-webpack.d.ts b/packages/cli/src/commands/init/templates/application/src/@types/bundler-webpack.d.ts new file mode 100644 index 0000000..e59586b --- /dev/null +++ b/packages/cli/src/commands/init/templates/application/src/@types/bundler-webpack.d.ts @@ -0,0 +1 @@ +import '@mainset/bundler-webpack/global-types'; diff --git a/packages/cli/src/commands/init/templates/application/src/app.browser.tsx b/packages/cli/src/commands/init/templates/application/src/app.browser.tsx new file mode 100644 index 0000000..01409b3 --- /dev/null +++ b/packages/cli/src/commands/init/templates/application/src/app.browser.tsx @@ -0,0 +1,7 @@ +import React from 'react'; + +import { HomePage } from './pages'; + +const BrowserReactApp = ; + +export default BrowserReactApp; diff --git a/packages/cli/src/commands/init/templates/application/src/app.server.tsx b/packages/cli/src/commands/init/templates/application/src/app.server.tsx new file mode 100644 index 0000000..f9199d2 --- /dev/null +++ b/packages/cli/src/commands/init/templates/application/src/app.server.tsx @@ -0,0 +1,15 @@ +import BrowserReactApp from './app.browser'; + +type ProvideServerReactAppParams = { + reqUrl: string; + fullUrl: string; + // Context?: Record; +}; + +const provideServerReactApp = (params?: ProvideServerReactAppParams) => { + console.log({ params }); + + return BrowserReactApp; +}; + +export default provideServerReactApp; diff --git a/packages/cli/src/commands/init/templates/application/src/index.csr.ts b/packages/cli/src/commands/init/templates/application/src/index.csr.ts new file mode 100644 index 0000000..7fcfe17 --- /dev/null +++ b/packages/cli/src/commands/init/templates/application/src/index.csr.ts @@ -0,0 +1,9 @@ +import ReactDOMClient from 'react-dom/client'; + +import BrowserReactApp from './app.browser'; + +const targetContainer = document.getElementById('example-react'); + +if (targetContainer) { + ReactDOMClient.createRoot(targetContainer).render(BrowserReactApp); +} diff --git a/packages/cli/src/commands/init/templates/application/src/index.ssr.ts b/packages/cli/src/commands/init/templates/application/src/index.ssr.ts new file mode 100644 index 0000000..afa5e31 --- /dev/null +++ b/packages/cli/src/commands/init/templates/application/src/index.ssr.ts @@ -0,0 +1,9 @@ +import ReactDOMClient from 'react-dom/client'; + +import BrowserReactApp from './app.browser'; + +const targetContainer = document.getElementById('example-react'); + +if (targetContainer) { + ReactDOMClient.hydrateRoot(targetContainer, BrowserReactApp); +} diff --git a/packages/cli/src/commands/init/templates/application/src/index.template.html b/packages/cli/src/commands/init/templates/application/src/index.template.html new file mode 100644 index 0000000..2ed3371 --- /dev/null +++ b/packages/cli/src/commands/init/templates/application/src/index.template.html @@ -0,0 +1,20 @@ + + + + + + + + + + + + +
+ + + + diff --git a/packages/cli/src/commands/init/templates/application/src/pages/Home/HomePage.tsx b/packages/cli/src/commands/init/templates/application/src/pages/Home/HomePage.tsx new file mode 100644 index 0000000..8a8ad89 --- /dev/null +++ b/packages/cli/src/commands/init/templates/application/src/pages/Home/HomePage.tsx @@ -0,0 +1,26 @@ +import React, { useEffect } from 'react'; + +import * as styles from './home-page.module.scss'; + +const HomePage = () => { + const [apiResponse, setApiResponse] = React.useState<{ + origin: string; + } | null>(null); + + useEffect(() => { + fetch('/api-example/ip') + .then((response) => response.json()) + .then((responseAsJson) => { + setApiResponse(responseAsJson); + }); + }, []); + + return ( +
+

Hello world

+

Your IP is: {apiResponse?.origin || '...'}

+
+ ); +}; + +export { HomePage }; diff --git a/packages/cli/src/commands/init/templates/application/src/pages/Home/home-page.module.scss b/packages/cli/src/commands/init/templates/application/src/pages/Home/home-page.module.scss new file mode 100644 index 0000000..cbe7f18 --- /dev/null +++ b/packages/cli/src/commands/init/templates/application/src/pages/Home/home-page.module.scss @@ -0,0 +1,9 @@ +.home-page { + &__welcome-section { + display: flex; + align-items: center; + justify-content: center; + flex-direction: column; + height: 100vh; + } +} diff --git a/packages/cli/src/commands/init/templates/application/src/pages/Home/index.ts b/packages/cli/src/commands/init/templates/application/src/pages/Home/index.ts new file mode 100644 index 0000000..11e53da --- /dev/null +++ b/packages/cli/src/commands/init/templates/application/src/pages/Home/index.ts @@ -0,0 +1 @@ +export * from './HomePage'; diff --git a/packages/cli/src/commands/init/templates/application/src/pages/index.ts b/packages/cli/src/commands/init/templates/application/src/pages/index.ts new file mode 100644 index 0000000..6ef94b3 --- /dev/null +++ b/packages/cli/src/commands/init/templates/application/src/pages/index.ts @@ -0,0 +1 @@ +export { HomePage } from './Home'; diff --git a/packages/cli/src/commands/init/templates/application/src/styles/global.scss b/packages/cli/src/commands/init/templates/application/src/styles/global.scss new file mode 100644 index 0000000..e81d2ea --- /dev/null +++ b/packages/cli/src/commands/init/templates/application/src/styles/global.scss @@ -0,0 +1 @@ +@use './normalize.scss'; diff --git a/packages/cli/src/commands/init/templates/application/src/styles/normalize.scss b/packages/cli/src/commands/init/templates/application/src/styles/normalize.scss new file mode 100644 index 0000000..3404a6e --- /dev/null +++ b/packages/cli/src/commands/init/templates/application/src/styles/normalize.scss @@ -0,0 +1,8 @@ +body, +h1, +h2, +h3, +hr, +p { + margin: 0; +} diff --git a/packages/cli/src/commands/init/templates/application/tsconfig.json b/packages/cli/src/commands/init/templates/application/tsconfig.json new file mode 100644 index 0000000..74dbd57 --- /dev/null +++ b/packages/cli/src/commands/init/templates/application/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": [ + "@mainset/dev-stack-fe/tsconfig--bundler", + "@mainset/dev-stack-fe/tschunk--react" + ], + "compilerOptions": { + "outDir": "./dist/esm" + } +} diff --git a/packages/cli/src/commands/init/templates/configuration/.dockerignore b/packages/cli/src/commands/init/templates/configuration/.dockerignore new file mode 100644 index 0000000..dc157ff --- /dev/null +++ b/packages/cli/src/commands/init/templates/configuration/.dockerignore @@ -0,0 +1,34 @@ +# Include any files or directories that you don't want to be copied to your +# container here (e.g., local build artifacts, temporary files, etc.). +# +# For more help, visit the .dockerignore file reference guide at +# https://docs.docker.com/go/build-context-dockerignore/ + +**/.classpath +**/.dockerignore +**/.env +**/.git +**/.gitignore +**/.project +**/.settings +**/.toolstarget +**/.vs +**/.vscode +**/.next +**/.cache +**/*.*proj.user +**/*.dbmdl +**/*.jfm +**/charts +**/docker-compose* +**/compose.y*ml +**/Dockerfile* +**/node_modules +**/npm-debug.log +**/obj +**/secrets.dev.yaml +**/values.dev.yaml +**/build +**/dist +LICENSE +README.md diff --git a/packages/cli/src/commands/init/templates/configuration/.husky/commit-msg b/packages/cli/src/commands/init/templates/configuration/.husky/commit-msg new file mode 100644 index 0000000..3facaa1 --- /dev/null +++ b/packages/cli/src/commands/init/templates/configuration/.husky/commit-msg @@ -0,0 +1 @@ +npx commitlint@^19 --edit diff --git a/packages/cli/src/commands/init/templates/configuration/.husky/pre-commit b/packages/cli/src/commands/init/templates/configuration/.husky/pre-commit new file mode 100644 index 0000000..dee0e5d --- /dev/null +++ b/packages/cli/src/commands/init/templates/configuration/.husky/pre-commit @@ -0,0 +1 @@ +npx lint-staged@^16 diff --git a/packages/cli/src/commands/init/templates/configuration/.prettierignore b/packages/cli/src/commands/init/templates/configuration/.prettierignore new file mode 100644 index 0000000..77f7bb6 --- /dev/null +++ b/packages/cli/src/commands/init/templates/configuration/.prettierignore @@ -0,0 +1,25 @@ +# general +LICENSE +.gitignore +.keep + +# configuration files +.dockerignore +Dockerfile + +# package manager +pnpm-lock.yaml +.npmrc.example + +# packages +.prettierignore +.husky + +# files +*.sh +*.toml +*.env* + +# images +*.ico +*.svg diff --git a/packages/cli/src/commands/init/templates/configuration/Dockerfile b/packages/cli/src/commands/init/templates/configuration/Dockerfile new file mode 100644 index 0000000..a8f2e23 --- /dev/null +++ b/packages/cli/src/commands/init/templates/configuration/Dockerfile @@ -0,0 +1,93 @@ +# syntax=docker/dockerfile:1 + +# Comments are provided throughout this file to help you get started. +# If you need more help, visit the Dockerfile reference guide at +# https://docs.docker.com/go/dockerfile-reference/ + +# Want to help us make this template better? Share your feedback here: https://forms.gle/ybq9Krt8jtBL3iCk7 + +ARG NODE_VERSION=24.14.0 +ARG PNPM_VERSION=10.30.3 + +FROM node:${NODE_VERSION}-alpine as base + +# Install pnpm. +RUN --mount=type=cache,target=/root/.npm \ + npm install -g pnpm@${PNPM_VERSION} + +WORKDIR /usr/src/web-app--react + +################################################################################ +# Create a stage for installing production dependencies. +FROM base AS install-dependencies + +# Download dependencies as a separate step to take advantage of Docker's caching. +# Leverage a cache mount to /root/.local/share/pnpm/store to speed up subsequent builds. +# Leverage a bind mounts to package.json and pnpm-lock.yaml to avoid having to copy them into +# into this layer. +RUN \ + # mount root files + --mount=type=bind,source=package.json,target=package.json \ + --mount=type=bind,source=pnpm-lock.yaml,target=pnpm-lock.yaml \ + # mount cache and install dependencies + --mount=type=cache,target=/root/.local/share/pnpm/store \ + (\ + # Install dependencies with pnpm + # pnpm install --prod --frozen-lockfile + pnpm install --frozen-lockfile \ + ) + +################################################################################ +# Create a stage for building the packages source code for Server Side Rendering +FROM install-dependencies as build-ssr + +# Copy the rest of the source files into the image. +COPY . . + +# Run the build script. +RUN pnpm run build + +################################################################################ +# Create a new {production} stage that will be running the application +FROM install-dependencies AS production + +# Use production node environment +ENV NODE_ENV production + +# Run the application as a non-root user. +USER node + +# Copy compiled {/dist} code from the {build} Docker stage into the image. +COPY --chown=node:node --from=build-ssr /usr/src/web-app--react/dist ./dist +# Copy other required files and folders to launch the application +COPY ./package.json ./ +COPY ./config ./config + +# Expose the port that the application listens on. +EXPOSE 8080 + +# Run the application. +CMD ["pnpm", "run", "serve"] + +################################################################################ +# Create a new {development} stage that will be running the application +FROM install-dependencies AS development + +# Use production node environment +ENV NODE_ENV development + +# Run the application as a non-root user. +USER node + +# Copy compiled {/dist} code from the {build} Docker stage into the image. +COPY --chown=node:node --from=build-ssr /usr/src/web-app--react/dist ./dist + +# Copy the rest of the source files into the image. +# !IMPORTANT: the {--chown=node:node} required, server crashes on file change, files re-generated with root permissions +COPY --chown=node:node . . + +# Expose the port that the application listens on. +EXPOSE 8080 + +# Run the application. +CMD ["pnpm", "run", "dev"] diff --git a/packages/cli/src/commands/init/templates/configuration/commitlint.config.mjs b/packages/cli/src/commands/init/templates/configuration/commitlint.config.mjs new file mode 100644 index 0000000..49586d4 --- /dev/null +++ b/packages/cli/src/commands/init/templates/configuration/commitlint.config.mjs @@ -0,0 +1,3 @@ +import { mainsetCommitlintConfig } from '@mainset/dev-stack-fe/commitlint'; + +export default mainsetCommitlintConfig; diff --git a/packages/cli/src/commands/init/templates/configuration/compose.yaml b/packages/cli/src/commands/init/templates/configuration/compose.yaml new file mode 100644 index 0000000..03e2c91 --- /dev/null +++ b/packages/cli/src/commands/init/templates/configuration/compose.yaml @@ -0,0 +1,59 @@ +# Comments are provided throughout this file to help you get started. +# If you need more help, visit the Docker Compose reference guide at +# https://docs.docker.com/go/compose-spec-reference/ + +# Here the instructions define your application as a service called "server". +# This service is built from the Dockerfile in the current directory. +# You can add other services your application may depend on here, such as a +# database or a cache. For examples, see the Awesome Compose repository: +# https://github.com/docker/awesome-compose +services: + web-app--react: + build: + context: . + target: production + # NOTE: start production service by default without {--profile} flag + profiles: [prod] + env_file: + - ./.env + ports: + - 8080:8080 + labels: + - 'traefik.enable=true' + - 'traefik.http.routers.web-app--react.rule=Host(`react-boilerplate.mainset.${DEV__DOMAIN_LOCALHOST:-localhost}`)' + - 'traefik.http.services.web-app--react.loadbalancer.server.port=8080' + networks: + - network--dev + web-app--react-dev: + extends: web-app--react + build: + target: development + env_file: + - ./.env.development + volumes: + # Bind Mount code for Live Update + - ./src:/usr/src/web-app--react/src + # !IMPORTANT: ensure that the volume mounting does not overwrite any of the {node_modules} directory + - /usr/src/web-app--react/node_modules + # !IMPORTANT: ensure that the volume mounting does not overwrite any of the {dist} static directory + - /usr/src/web-app--react/dist + profiles: [dev] + + # development service + # make the service available under custom domain on local computer + traefik: + image: traefik:v2.5 + command: + - '--api.insecure=true' + - '--providers.docker=true' + - '--entrypoints.web.address=:80' + ports: + - '80:80' + volumes: + - '/var/run/docker.sock:/var/run/docker.sock:ro' + networks: + - network--dev + +# development +networks: + network--dev: diff --git a/packages/cli/src/commands/init/templates/configuration/eslint.config.mjs b/packages/cli/src/commands/init/templates/configuration/eslint.config.mjs new file mode 100644 index 0000000..395faf2 --- /dev/null +++ b/packages/cli/src/commands/init/templates/configuration/eslint.config.mjs @@ -0,0 +1,6 @@ +import { + defineConfig, + eslintMainsetConfig, +} from '@mainset/dev-stack-fe/eslint'; + +export default defineConfig([...eslintMainsetConfig]); diff --git a/packages/cli/src/commands/init/templates/configuration/lint-staged.config.mjs b/packages/cli/src/commands/init/templates/configuration/lint-staged.config.mjs new file mode 100644 index 0000000..b1a5046 --- /dev/null +++ b/packages/cli/src/commands/init/templates/configuration/lint-staged.config.mjs @@ -0,0 +1,3 @@ +import { mainsetLintStaged } from '@mainset/dev-stack-fe/lint-staged'; + +export default mainsetLintStaged; diff --git a/packages/cli/src/commands/init/templates/configuration/prettier.config.mjs b/packages/cli/src/commands/init/templates/configuration/prettier.config.mjs new file mode 100644 index 0000000..51ff526 --- /dev/null +++ b/packages/cli/src/commands/init/templates/configuration/prettier.config.mjs @@ -0,0 +1,5 @@ +import mainsetPrettierConfig from '@mainset/dev-stack-fe/prettier'; + +export default { + ...mainsetPrettierConfig, +}; diff --git a/packages/cli/src/commands/init/templates/configuration/stylelint.config.mjs b/packages/cli/src/commands/init/templates/configuration/stylelint.config.mjs new file mode 100644 index 0000000..38f7f25 --- /dev/null +++ b/packages/cli/src/commands/init/templates/configuration/stylelint.config.mjs @@ -0,0 +1,6 @@ +import mainsetStylelintConfig from '@mainset/dev-stack-fe/stylelint'; + +/** @type {import('stylelint').Config} */ +export default { + ...mainsetStylelintConfig, +}; diff --git a/packages/cli/src/commands/node-sourcer.mts b/packages/cli/src/commands/node-sourcer.mts index 37fdaed..0771dfd 100644 --- a/packages/cli/src/commands/node-sourcer.mts +++ b/packages/cli/src/commands/node-sourcer.mts @@ -22,8 +22,24 @@ function registerNodeSourcerCommand(program: Command) { .requiredOption('-e, --exec ', 'Execution mode: build or watch') // .option('-b, --builder ', 'Builder tool (default: rslib)', 'rslib') .option('-c, --config ', 'Path to config file', './rslib.config.mts') + .option('-t, --target ', 'Execution mode: node, web, react', 'node') + .option( + '--bundless', + 'Bundleless mode, means that each source file is compiled and built separately.', + ) .action((options) => { // Step 0: determinate command params + const CONFIG_FILE_NAME__BY_TARGET = { + node: 'node-sourcer', + web: 'web-package', + react: 'react', + }; + const configFileName = + CONFIG_FILE_NAME__BY_TARGET[ + (options.target as keyof typeof CONFIG_FILE_NAME__BY_TARGET) || + CONFIG_FILE_NAME__BY_TARGET.node + ]; + const customRslibConfigPath = path.resolve( runtimePathById.root, options.config, @@ -34,7 +50,7 @@ function registerNodeSourcerCommand(program: Command) { runtimePathById.root, // NOTE: possibility to check if package is installed, otherwise throw error 'node_modules', - '@mainset/builder-rslib/dist/esm/rslib.node-sourcer.config.mjs', + `@mainset/builder-rslib/dist/esm/rslib.${configFileName}.config.mjs`, ); if (options.exec === 'build') { @@ -47,7 +63,14 @@ function registerNodeSourcerCommand(program: Command) { // Step 2: build source code console.log('\n📦 Compiling Source Code with Rslib ...'); - execImmediateRslibCLICommand(`build --config ${rslibConfigPath}`); + execImmediateRslibCLICommand( + `build --config ${rslibConfigPath}${options.bundless ? ' --no-bundle' : ''}`, + { + env: { + MS_CLI__RSLIB_BUNDLESS_MODE: options.bundless, + }, + }, + ); // Step 3: build type only execImmediateTypeScriptCompileTypeOnly(); @@ -65,12 +88,20 @@ function registerNodeSourcerCommand(program: Command) { execImmediatePurgeDist(); // Step 2: watch source code - runStreamingRslibCLICommand([ - 'build', - '--config', - rslibConfigPath, - '--watch', - ]); + runStreamingRslibCLICommand( + [ + 'build', + '--config', + rslibConfigPath, + options.bundless ? '--no-bundle' : '', + '--watch', + ], + { + env: { + MS_CLI__RSLIB_BUNDLESS_MODE: options.bundless, + }, + }, + ); // Step 3: watch type only runStreamingTypeScriptCompileTypeOnly(); diff --git a/packages/cli/src/commands/process-runner-chunks/rslib.chunk.mts b/packages/cli/src/commands/process-runner-chunks/rslib.chunk.mts index bdc7408..829a79d 100644 --- a/packages/cli/src/commands/process-runner-chunks/rslib.chunk.mts +++ b/packages/cli/src/commands/process-runner-chunks/rslib.chunk.mts @@ -1,3 +1,5 @@ +import type { ExecSyncOptions, SpawnOptions } from 'child_process'; + import { resolveHostPackageBinForCLICommandPath } from '../../runtime/index.mjs'; import { execImmediateCommand, @@ -13,16 +15,22 @@ function getRslibCLICommandPath() { return rslibCLICommandPath; } -function execImmediateRslibCLICommand(command: string) { +function execImmediateRslibCLICommand( + command: string, + options: ExecSyncOptions = {}, +) { const rslibCLICommandPath = getRslibCLICommandPath(); - return execImmediateCommand(`${rslibCLICommandPath} ${command}`); + return execImmediateCommand(`${rslibCLICommandPath} ${command}`, options); } -function runStreamingRslibCLICommand(commandParams: string[]) { +function runStreamingRslibCLICommand( + commandParams: string[], + options: SpawnOptions = {}, +) { const rslibCLICommandPath = getRslibCLICommandPath(); - return runStreamingCommand(rslibCLICommandPath, [...commandParams]); + return runStreamingCommand(rslibCLICommandPath, [...commandParams], options); } export { execImmediateRslibCLICommand, runStreamingRslibCLICommand }; diff --git a/packages/cli/src/mainset-cli.mts b/packages/cli/src/mainset-cli.mts index 1143289..c0db653 100644 --- a/packages/cli/src/mainset-cli.mts +++ b/packages/cli/src/mainset-cli.mts @@ -2,6 +2,7 @@ import { Command } from 'commander'; import { + registerInitCommand, registerNodeSourcerCommand, registerSourceCodeCommand, registerWebAppCommand, @@ -18,6 +19,7 @@ program .description('CLI to manage frontend tooling and infrastructure') .version('0.1.0'); +registerInitCommand(program); registerSourceCodeCommand(program); registerNodeSourcerCommand(program); registerWebAppCommand(program); diff --git a/packages/cli/tsconfig.build-type.json b/packages/cli/tsconfig.build-type.json index 630f2ae..31efaf1 100644 --- a/packages/cli/tsconfig.build-type.json +++ b/packages/cli/tsconfig.build-type.json @@ -4,5 +4,6 @@ "outDir": "./dist/types", // TODO: review possibility to move into {common} config "target": "es2017" - } + }, + "exclude": ["./src/commands/init/templates/**/*"] } diff --git a/packages/cli/tsconfig.json b/packages/cli/tsconfig.json index 90dd5f3..5e13372 100644 --- a/packages/cli/tsconfig.json +++ b/packages/cli/tsconfig.json @@ -4,5 +4,6 @@ "outDir": "./dist/esm", // TODO: review possibility to move into {common} config "target": "es2017" - } + }, + "exclude": ["./src/commands/init/templates/**/*"] } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index cda1527..1aa6b61 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -52,14 +52,14 @@ importers: packages/builder-rslib: dependencies: '@rsbuild/plugin-react': - specifier: ^1.4.1 - version: 1.4.5(@rsbuild/core@1.5.17) + specifier: ^1.4.5 + version: 1.4.5(@rsbuild/core@2.0.0-beta.8(core-js@3.46.0)) '@rsbuild/plugin-sass': - specifier: ^1.4.0 - version: 1.5.0(@rsbuild/core@1.5.17) + specifier: ^1.5.0 + version: 1.5.0(@rsbuild/core@2.0.0-beta.8(core-js@3.46.0)) '@rslib/core': - specifier: ^0.15.0 - version: 0.15.1(typescript@5.9.3) + specifier: ^0.20.0 + version: 0.20.0(core-js@3.46.0)(typescript@5.9.3) devDependencies: '@mainset/cli': specifier: workspace:^ @@ -1252,6 +1252,9 @@ packages: '@module-federation/webpack-bundler-runtime@0.18.0': resolution: {integrity: sha512-TEvErbF+YQ+6IFimhUYKK3a5wapD90d90sLsNpcu2kB3QGT7t4nIluE25duXuZDVUKLz86tEPrza/oaaCWTpvQ==} + '@napi-rs/wasm-runtime@1.0.7': + resolution: {integrity: sha512-SeDnOO0Tk7Okiq6DbXmmBODgOAb9dp9gjlphokTUxmt8U3liIP1ZsozBahH69j/RJv+Rfs6IwUKHTgQYJ/HBAw==} + '@napi-rs/wasm-runtime@1.1.1': resolution: {integrity: sha512-p64ah1M1ld8xjWv3qbvFwHiFVWrq1yFvV4f7w+mzaqiR4IlSgkqhcRdHwsGgomwzBH51sRY4NEowLxnaBjcW/A==} @@ -1412,10 +1415,15 @@ packages: resolution: {integrity: sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==} engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} - '@rsbuild/core@1.5.17': - resolution: {integrity: sha512-tHa4puv+pEooQvSewu/K5sm270nkVPcP07Ioz1c+fbFCrFpiZWV5XumgznilS80097glUrieN+9xTbIHGXjThQ==} - engines: {node: '>=18.12.0'} + '@rsbuild/core@2.0.0-beta.8': + resolution: {integrity: sha512-MUxbKJPE1agOK3eCHjKvBIiA+CcZ0TJU/ANKDBLMjK2Er+wq4r5c2ne53+Pi7DtIExoMbSSWBx+RP3CMewKGVA==} + engines: {node: ^20.19.0 || >=22.12.0} hasBin: true + peerDependencies: + core-js: '>= 3.0.0' + peerDependenciesMeta: + core-js: + optional: true '@rsbuild/plugin-react@1.4.5': resolution: {integrity: sha512-eS2sXCedgGA/7bLu8yVtn48eE/GyPbXx4Q7OcutB01IQ1D2y8WSMBys4nwfrecy19utvw4NPn4gYDy52316+vg==} @@ -1427,9 +1435,9 @@ packages: peerDependencies: '@rsbuild/core': ^1.3.0 || ^2.0.0-0 - '@rslib/core@0.15.1': - resolution: {integrity: sha512-rNGGHJwxU1g6u2op5Jf2JMgbRCRmMZGCNPU099Ebp5ZgjmknyaU88YMJc8L6trfBU7M6yIYlqgepqg/0L8evew==} - engines: {node: '>=18.12.0'} + '@rslib/core@0.20.0': + resolution: {integrity: sha512-hsRwjMbBla8lyKIVR0gFsK5M3j+LSbFOTafvbT0QR90ehZXwlu+EhpHJv8v/uIRT50RVlgCrcT+LCVr1oU3pbA==} + engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: '@microsoft/api-extractor': ^7 @@ -1445,57 +1453,113 @@ packages: cpu: [arm64] os: [darwin] + '@rspack/binding-darwin-arm64@2.0.0-beta.6': + resolution: {integrity: sha512-FQ8zflthQJJf0cM0vDFnfnXrTOnRvwz886tiafbwu1RO5qmh+pJH+xg1eQaLPnRPqLTlcmnpngyacYFUxw+1AA==} + cpu: [arm64] + os: [darwin] + '@rspack/binding-darwin-x64@1.5.8': resolution: {integrity: sha512-YFOzeL1IBknBcri8vjUp43dfUBylCeQnD+9O9p0wZmLAw7DtpN5JEOe2AkGo8kdTqJjYKI+cczJPKIw6lu1LWw==} cpu: [x64] os: [darwin] + '@rspack/binding-darwin-x64@2.0.0-beta.6': + resolution: {integrity: sha512-Cr4P19anOIaHtK8Z20Hl12PPUcs3LM24ZSQPfs0gPS0etzSOE4JRsqW/79GnnjZd/A+Wola/dZcnMVS44e3c3A==} + cpu: [x64] + os: [darwin] + '@rspack/binding-linux-arm64-gnu@1.5.8': resolution: {integrity: sha512-UAWCsOnpkvy8eAVRo0uipbHXDhnoDq5zmqWTMhpga0/a3yzCp2e+fnjZb/qnFNYb5MeL0O1mwMOYgn1M3oHILQ==} cpu: [arm64] os: [linux] libc: [glibc] + '@rspack/binding-linux-arm64-gnu@2.0.0-beta.6': + resolution: {integrity: sha512-MgTzspaj3v9/4T3KQ/fRuj+cit3BnEcgFe4OP+BvUWlTQvxlckDWpDymVhPuIqpx7pJvLcXwdz8mQhvZ87AD5g==} + cpu: [arm64] + os: [linux] + libc: [glibc] + '@rspack/binding-linux-arm64-musl@1.5.8': resolution: {integrity: sha512-GnSvGT4GjokPSD45cTtE+g7LgghuxSP1MRmvd+Vp/I8pnxTVSTsebRod4TAqyiv+l11nuS8yqNveK9qiOkBLWw==} cpu: [arm64] os: [linux] libc: [musl] + '@rspack/binding-linux-arm64-musl@2.0.0-beta.6': + resolution: {integrity: sha512-5vyjbrj3u8x4Crb77QvFJSZkq7QwOuVJff8oStbS/v7cC+NEAQQYB/6Bl0JwyDFAcMMX8ZRyaDjc1o1qQ0Q31g==} + cpu: [arm64] + os: [linux] + libc: [musl] + '@rspack/binding-linux-x64-gnu@1.5.8': resolution: {integrity: sha512-XLxh5n/pzUfxsugz/8rVBv+Tx2nqEM+9rharK69kfooDsQNKyz7PANllBQ/v4svJ+W0BRHnDL4qXSGdteZeEjA==} cpu: [x64] os: [linux] libc: [glibc] + '@rspack/binding-linux-x64-gnu@2.0.0-beta.6': + resolution: {integrity: sha512-GmNJgFHoK5LFQ2m96HrXIgf1zZNe+4yaaOD/5qqcI163QXRqRflfZprmdr2L4R6VsU2i+YQ2Ap2s20Y/zSt6RQ==} + cpu: [x64] + os: [linux] + libc: [glibc] + '@rspack/binding-linux-x64-musl@1.5.8': resolution: {integrity: sha512-gE0+MZmwF+01p9/svpEESkzkLpBkVUG2o03YMpwXYC/maeRRhWvF8BJ7R3i/Ls/jFGSE87dKX5NbRLVzqksq/w==} cpu: [x64] os: [linux] libc: [musl] + '@rspack/binding-linux-x64-musl@2.0.0-beta.6': + resolution: {integrity: sha512-tI2S3v8yXel5GL3yPnBNnFZ/dye4TyRM2j7mfJ49M6uTWjfRFyAcuxqw7z9Pyvyhsc1AoOnnXejtqqJpZkBQoA==} + cpu: [x64] + os: [linux] + libc: [musl] + '@rspack/binding-wasm32-wasi@1.5.8': resolution: {integrity: sha512-cfg3niNHeJuxuml1Vy9VvaJrI/5TakzoaZvKX2g5S24wfzR50Eyy4JAsZ+L2voWQQp1yMJbmPYPmnTCTxdJQBQ==} cpu: [wasm32] + '@rspack/binding-wasm32-wasi@2.0.0-beta.6': + resolution: {integrity: sha512-Bv9o1zZIDTOzjbliyAwMOGjsL6wiGIPRttJ9CLsdRoKI5XcMTEFHjwlnm1Zs4/EP+zC+bTgseq1EFngIy+nZRg==} + cpu: [wasm32] + '@rspack/binding-win32-arm64-msvc@1.5.8': resolution: {integrity: sha512-7i3ZTHFXKfU/9Jm9XhpMkrdkxO7lfeYMNVEGkuU5dyBfRMQj69dRgPL7zJwc2plXiqu9LUOl+TwDNTjap7Q36g==} cpu: [arm64] os: [win32] + '@rspack/binding-win32-arm64-msvc@2.0.0-beta.6': + resolution: {integrity: sha512-R/j0VTVKn3gU4a0xKAXJUX6jzmanHsuBHtLSpgnRqKW/20csFzsnsqY9PxaiAObTHVPMCrNvTG5KXHYIqYgACg==} + cpu: [arm64] + os: [win32] + '@rspack/binding-win32-ia32-msvc@1.5.8': resolution: {integrity: sha512-7ZPPWO11J+soea1+mnfaPpQt7GIodBM7A86dx6PbXgVEoZmetcWPrCF2NBfXxQWOKJ9L3RYltC4z+ZyXRgMOrw==} cpu: [ia32] os: [win32] + '@rspack/binding-win32-ia32-msvc@2.0.0-beta.6': + resolution: {integrity: sha512-v3Gc+gRFTBNLSmyHAgI6mE30W94T0g8jD7S1qamUfX6i50YjDylyiMG1prG/8i/YVNWQynQeQi4Cjfg+Hi7alQ==} + cpu: [ia32] + os: [win32] + '@rspack/binding-win32-x64-msvc@1.5.8': resolution: {integrity: sha512-N/zXQgzIxME3YUzXT8qnyzxjqcnXudWOeDh8CAG9zqTCnCiy16SFfQ/cQgEoLlD9geQntV6jx2GbDDI5kpDGMQ==} cpu: [x64] os: [win32] + '@rspack/binding-win32-x64-msvc@2.0.0-beta.6': + resolution: {integrity: sha512-PjaKOG2rQqzOwsmu03EAyTb7oA52CrO1I8JXiBT07adrDysHvKV/Gi+P0XPuDLDMnxNpndoGJMmvfxsymRpwyA==} + cpu: [x64] + os: [win32] + '@rspack/binding@1.5.8': resolution: {integrity: sha512-/91CzhRl9r5BIQCgGsS7jA6MDbw1I2BQpbfcUUdkdKl2P79K3Zo/Mw/TvKzS86catwLaUQEgkGRmYawOfPg7ow==} + '@rspack/binding@2.0.0-beta.6': + resolution: {integrity: sha512-oJytPDJT57cz2is0e/e1myWVNxn+ZcII1/fF2Y3TiXVUIihLC/KDm6ISTgaZKr8ZyjTlVIV3V4wSO7IHlYV6aw==} + '@rspack/core@1.5.8': resolution: {integrity: sha512-sUd2LfiDhqYVfvknuoz0+/c+wSpn693xotnG5g1CSWKZArbtwiYzBIVnNlcHGmuoBRsnj/TkSq8dTQ7gwfBroQ==} engines: {node: '>=18.12.0'} @@ -1505,6 +1569,18 @@ packages: '@swc/helpers': optional: true + '@rspack/core@2.0.0-beta.6': + resolution: {integrity: sha512-dvi10ijR9Rr0W75GRFqWvswAEdLBsbXCGhxzm6zXxFNSanNL9s9xPelZ8XfnIU13QZkN2VNHGl9O/8KQEmYdEw==} + engines: {node: ^20.19.0 || >=22.12.0} + peerDependencies: + '@module-federation/runtime-tools': ^0.24.1 || ^2.0.0 + '@swc/helpers': '>=0.5.1' + peerDependenciesMeta: + '@module-federation/runtime-tools': + optional: true + '@swc/helpers': + optional: true + '@rspack/lite-tapable@1.0.1': resolution: {integrity: sha512-VynGOEsVw2s8TAlLf/uESfrgfrq2+rcXB1muPJYBWbsm1Oa6r5qVQhjA5ggM6z/coYPrsVMgovl3Ff7Q7OCp1w==} engines: {node: '>=16.0.0'} @@ -3839,12 +3915,12 @@ packages: resolution: {integrity: sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==} engines: {node: '>= 18'} - rsbuild-plugin-dts@0.15.1: - resolution: {integrity: sha512-RPJK/ycEYECstXYmg1vfboB4oa/yC23J4HzLkhhF8iyNYwHNxC/fSPuHkfikhGbvYyxw4pq52xHO/Y4FqcW+yA==} - engines: {node: '>=18.12.0'} + rsbuild-plugin-dts@0.20.0: + resolution: {integrity: sha512-CnTJTB59zzQFjPVEjpOaaEw5BeK/eTY6kwt4l5Lr9d3HQk3VRDSKfLWY/hpeZMbZzpCk2TqLrqIhS6a+jg7k7g==} + engines: {node: ^20.19.0 || >=22.12.0} peerDependencies: '@microsoft/api-extractor': ^7 - '@rsbuild/core': 1.x + '@rsbuild/core': ^1.0.0 || ^2.0.0-0 '@typescript/native-preview': 7.x typescript: ^5 peerDependenciesMeta: @@ -5855,30 +5931,43 @@ snapshots: '@leichtgewicht/ip-codec@2.0.5': {} - '@module-federation/error-codes@0.18.0': {} + '@module-federation/error-codes@0.18.0': + optional: true '@module-federation/runtime-core@0.18.0': dependencies: '@module-federation/error-codes': 0.18.0 '@module-federation/sdk': 0.18.0 + optional: true '@module-federation/runtime-tools@0.18.0': dependencies: '@module-federation/runtime': 0.18.0 '@module-federation/webpack-bundler-runtime': 0.18.0 + optional: true '@module-federation/runtime@0.18.0': dependencies: '@module-federation/error-codes': 0.18.0 '@module-federation/runtime-core': 0.18.0 '@module-federation/sdk': 0.18.0 + optional: true - '@module-federation/sdk@0.18.0': {} + '@module-federation/sdk@0.18.0': + optional: true '@module-federation/webpack-bundler-runtime@0.18.0': dependencies: '@module-federation/runtime': 0.18.0 '@module-federation/sdk': 0.18.0 + optional: true + + '@napi-rs/wasm-runtime@1.0.7': + dependencies: + '@emnapi/core': 1.8.1 + '@emnapi/runtime': 1.8.1 + '@tybys/wasm-util': 0.10.1 + optional: true '@napi-rs/wasm-runtime@1.1.1': dependencies: @@ -6065,72 +6154,107 @@ snapshots: '@pkgr/core@0.2.9': {} - '@rsbuild/core@1.5.17': + '@rsbuild/core@2.0.0-beta.8(core-js@3.46.0)': dependencies: - '@rspack/core': 1.5.8(@swc/helpers@0.5.19) - '@rspack/lite-tapable': 1.0.1 + '@rspack/core': 2.0.0-beta.6(@swc/helpers@0.5.19) '@swc/helpers': 0.5.19 + optionalDependencies: core-js: 3.46.0 - jiti: 2.6.1 + transitivePeerDependencies: + - '@module-federation/runtime-tools' - '@rsbuild/plugin-react@1.4.5(@rsbuild/core@1.5.17)': + '@rsbuild/plugin-react@1.4.5(@rsbuild/core@2.0.0-beta.8(core-js@3.46.0))': dependencies: - '@rsbuild/core': 1.5.17 + '@rsbuild/core': 2.0.0-beta.8(core-js@3.46.0) '@rspack/plugin-react-refresh': 1.6.1(react-refresh@0.18.0) react-refresh: 0.18.0 transitivePeerDependencies: - webpack-hot-middleware - '@rsbuild/plugin-sass@1.5.0(@rsbuild/core@1.5.17)': + '@rsbuild/plugin-sass@1.5.0(@rsbuild/core@2.0.0-beta.8(core-js@3.46.0))': dependencies: - '@rsbuild/core': 1.5.17 + '@rsbuild/core': 2.0.0-beta.8(core-js@3.46.0) deepmerge: 4.3.1 loader-utils: 2.0.4 postcss: 8.5.8 reduce-configs: 1.1.1 sass-embedded: 1.97.3 - '@rslib/core@0.15.1(typescript@5.9.3)': + '@rslib/core@0.20.0(core-js@3.46.0)(typescript@5.9.3)': dependencies: - '@rsbuild/core': 1.5.17 - rsbuild-plugin-dts: 0.15.1(@rsbuild/core@1.5.17)(typescript@5.9.3) + '@rsbuild/core': 2.0.0-beta.8(core-js@3.46.0) + rsbuild-plugin-dts: 0.20.0(@rsbuild/core@2.0.0-beta.8(core-js@3.46.0))(typescript@5.9.3) optionalDependencies: typescript: 5.9.3 transitivePeerDependencies: + - '@module-federation/runtime-tools' - '@typescript/native-preview' + - core-js '@rspack/binding-darwin-arm64@1.5.8': optional: true + '@rspack/binding-darwin-arm64@2.0.0-beta.6': + optional: true + '@rspack/binding-darwin-x64@1.5.8': optional: true + '@rspack/binding-darwin-x64@2.0.0-beta.6': + optional: true + '@rspack/binding-linux-arm64-gnu@1.5.8': optional: true + '@rspack/binding-linux-arm64-gnu@2.0.0-beta.6': + optional: true + '@rspack/binding-linux-arm64-musl@1.5.8': optional: true + '@rspack/binding-linux-arm64-musl@2.0.0-beta.6': + optional: true + '@rspack/binding-linux-x64-gnu@1.5.8': optional: true + '@rspack/binding-linux-x64-gnu@2.0.0-beta.6': + optional: true + '@rspack/binding-linux-x64-musl@1.5.8': optional: true + '@rspack/binding-linux-x64-musl@2.0.0-beta.6': + optional: true + '@rspack/binding-wasm32-wasi@1.5.8': dependencies: '@napi-rs/wasm-runtime': 1.1.1 optional: true + '@rspack/binding-wasm32-wasi@2.0.0-beta.6': + dependencies: + '@napi-rs/wasm-runtime': 1.0.7 + optional: true + '@rspack/binding-win32-arm64-msvc@1.5.8': optional: true + '@rspack/binding-win32-arm64-msvc@2.0.0-beta.6': + optional: true + '@rspack/binding-win32-ia32-msvc@1.5.8': optional: true + '@rspack/binding-win32-ia32-msvc@2.0.0-beta.6': + optional: true + '@rspack/binding-win32-x64-msvc@1.5.8': optional: true + '@rspack/binding-win32-x64-msvc@2.0.0-beta.6': + optional: true + '@rspack/binding@1.5.8': optionalDependencies: '@rspack/binding-darwin-arm64': 1.5.8 @@ -6143,6 +6267,20 @@ snapshots: '@rspack/binding-win32-arm64-msvc': 1.5.8 '@rspack/binding-win32-ia32-msvc': 1.5.8 '@rspack/binding-win32-x64-msvc': 1.5.8 + optional: true + + '@rspack/binding@2.0.0-beta.6': + optionalDependencies: + '@rspack/binding-darwin-arm64': 2.0.0-beta.6 + '@rspack/binding-darwin-x64': 2.0.0-beta.6 + '@rspack/binding-linux-arm64-gnu': 2.0.0-beta.6 + '@rspack/binding-linux-arm64-musl': 2.0.0-beta.6 + '@rspack/binding-linux-x64-gnu': 2.0.0-beta.6 + '@rspack/binding-linux-x64-musl': 2.0.0-beta.6 + '@rspack/binding-wasm32-wasi': 2.0.0-beta.6 + '@rspack/binding-win32-arm64-msvc': 2.0.0-beta.6 + '@rspack/binding-win32-ia32-msvc': 2.0.0-beta.6 + '@rspack/binding-win32-x64-msvc': 2.0.0-beta.6 '@rspack/core@1.5.8(@swc/helpers@0.5.19)': dependencies: @@ -6151,8 +6289,16 @@ snapshots: '@rspack/lite-tapable': 1.0.1 optionalDependencies: '@swc/helpers': 0.5.19 + optional: true + + '@rspack/core@2.0.0-beta.6(@swc/helpers@0.5.19)': + dependencies: + '@rspack/binding': 2.0.0-beta.6 + optionalDependencies: + '@swc/helpers': 0.5.19 - '@rspack/lite-tapable@1.0.1': {} + '@rspack/lite-tapable@1.0.1': + optional: true '@rspack/plugin-react-refresh@1.6.1(react-refresh@0.18.0)': dependencies: @@ -6926,7 +7072,8 @@ snapshots: core-js@2.6.12: {} - core-js@3.46.0: {} + core-js@3.46.0: + optional: true core-util-is@1.0.3: {} @@ -8710,10 +8857,10 @@ snapshots: transitivePeerDependencies: - supports-color - rsbuild-plugin-dts@0.15.1(@rsbuild/core@1.5.17)(typescript@5.9.3): + rsbuild-plugin-dts@0.20.0(@rsbuild/core@2.0.0-beta.8(core-js@3.46.0))(typescript@5.9.3): dependencies: '@ast-grep/napi': 0.37.0 - '@rsbuild/core': 1.5.17 + '@rsbuild/core': 2.0.0-beta.8(core-js@3.46.0) optionalDependencies: typescript: 5.9.3