Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 84 additions & 0 deletions .scripts/dev-setup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
#!/usr/bin/env node

/**
* Development Setup Script
*
* Automatically builds foundational packages if they don't exist.
* This ensures a smooth development experience for new contributors.
*/

const { existsSync } = require("fs");
const { execSync } = require("child_process");
const path = require("path");

const foundationalPackages = [
{
name: "@nimbus-ds/tokens",
distPath: "packages/core/tokens/dist",
buildCommand: "yarn build:tokens",
description: "Design tokens (colors, spacing, typography, etc.)",
},
{
name: "@nimbus-ds/icons",
distPath: "packages/icons/dist",
buildCommand: "yarn build:icons",
description: "Icon components and SVG assets",
},
];

function checkAndBuildFoundationalPackages() {
console.log("πŸ” Checking foundational packages...\n");

const packagesToBuild = [];

// Check which packages need building
foundationalPackages.forEach((pkg) => {
const distExists = existsSync(path.join(process.cwd(), pkg.distPath));
if (!distExists) {
packagesToBuild.push(pkg);
console.log(`❌ ${pkg.name}: Missing dist folder`);
} else {
console.log(`βœ… ${pkg.name}: Already built`);
}
});

// Build missing packages
if (packagesToBuild.length > 0) {
console.log(
`\nπŸ”¨ Building ${packagesToBuild.length} foundational package(s)...\n`
);

packagesToBuild.forEach((pkg) => {
console.log(`βš™οΈ Building ${pkg.name} (${pkg.description})...`);
try {
execSync(pkg.buildCommand, { stdio: "inherit", cwd: process.cwd() });
console.log(`βœ… ${pkg.name} built successfully\n`);
} catch (error) {
console.error(`❌ Failed to build ${pkg.name}:`, error.message);
process.exit(1);
}
});
Comment on lines +51 to +60
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

πŸ› οΈ Refactor suggestion

Build failures should be more informative

When a build fails, only the error message is logged. Consider preserving and displaying the full error output to help developers diagnose issues.

       try {
         execSync(pkg.buildCommand, { stdio: "inherit", cwd: process.cwd() });
         console.log(`βœ… ${pkg.name} built successfully\n`);
       } catch (error) {
-        console.error(`❌ Failed to build ${pkg.name}:`, error.message);
+        console.error(`❌ Failed to build ${pkg.name}:`);
+        console.error(`  Command: ${pkg.buildCommand}`);
+        console.error(`  Error: ${error.message}`);
+        if (error.stdout) console.error(`  Output: ${error.stdout.toString()}`);
         process.exit(1);
       }
πŸ“ Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
packagesToBuild.forEach((pkg) => {
console.log(`βš™οΈ Building ${pkg.name} (${pkg.description})...`);
try {
execSync(pkg.buildCommand, { stdio: "inherit", cwd: process.cwd() });
console.log(`βœ… ${pkg.name} built successfully\n`);
} catch (error) {
console.error(`❌ Failed to build ${pkg.name}:`, error.message);
process.exit(1);
}
});
packagesToBuild.forEach((pkg) => {
console.log(`βš™οΈ Building ${pkg.name} (${pkg.description})...`);
try {
execSync(pkg.buildCommand, { stdio: "inherit", cwd: process.cwd() });
console.log(`βœ… ${pkg.name} built successfully\n`);
} catch (error) {
console.error(`❌ Failed to build ${pkg.name}:`);
console.error(` Command: ${pkg.buildCommand}`);
console.error(` Error: ${error.message}`);
if (error.stdout) console.error(` Output: ${error.stdout.toString()}`);
process.exit(1);
}
});
πŸ€– Prompt for AI Agents
In .scripts/dev-setup.js around lines 51 to 60, the catch block only logs
error.message which loses command output; modify the catch to log the full
failure details by printing error.stdout and error.stderr (if present) and
fallback to error.stack or the entire error.toString(), e.g. capture and
console.error the stdout/stderr buffers (convert to string) and the stack, so
maintain process.exit(1) after logging the detailed output.


console.log("πŸŽ‰ All foundational packages are ready!\n");
} else {
console.log("\n✨ All foundational packages are already built!\n");
}
}

function startStorybook() {
console.log("πŸš€ Starting Storybook development server...\n");
try {
execSync("storybook dev -p 6006", { stdio: "inherit", cwd: process.cwd() });
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick (assertive)

Hardcoded Storybook command limits flexibility

The Storybook command is hardcoded with specific options. Consider making this configurable via environment variables or package.json scripts.

-    execSync("storybook dev -p 6006", { stdio: "inherit", cwd: process.cwd() });
+    const storybookPort = process.env.STORYBOOK_PORT || "6006";
+    const storybookCmd = process.env.STORYBOOK_CMD || `storybook dev -p ${storybookPort}`;
+    execSync(storybookCmd, { stdio: "inherit", cwd: process.cwd() });
πŸ“ Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
execSync("storybook dev -p 6006", { stdio: "inherit", cwd: process.cwd() });
// Allow overriding the Storybook port and full command via environment variables
const storybookPort = process.env.STORYBOOK_PORT || "6006";
const storybookCmd = process.env.STORYBOOK_CMD || `storybook dev -p ${storybookPort}`;
execSync(storybookCmd, { stdio: "inherit", cwd: process.cwd() });
πŸ€– Prompt for AI Agents
In .scripts/dev-setup.js around line 71 the Storybook start command is hardcoded
as "storybook dev -p 6006" which reduces flexibility; modify the script to read
the command and options from environment variables (e.g., STORYBOOK_CMD or
STORYBOOK_PORT) or from package.json scripts and fall back to the current
default, then use those values when calling execSync so callers can override the
command/port without editing the file.

} catch (error) {
console.error("❌ Failed to start Storybook:", error.message);
process.exit(1);
}
}

// Main execution
if (require.main === module) {
checkAndBuildFoundationalPackages();
startStorybook();
}

module.exports = { checkAndBuildFoundationalPackages };
17 changes: 17 additions & 0 deletions .scripts/setup-foundations.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#!/usr/bin/env node

/**
* Setup Foundations Script
*
* Builds only the foundational packages without starting the development server.
* Useful for CI/CD or when you just want to ensure dependencies are built.
*/

const { checkAndBuildFoundationalPackages } = require("./dev-setup");

console.log("πŸ—οΈ Setting up Nimbus Design System foundational packages...\n");

checkAndBuildFoundationalPackages();

console.log("✨ Foundational packages setup complete!");
console.log('πŸ’‘ Run "yarn start:dev" to start the development server.');
Comment on lines +10 to +17
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fail fast with clear errors (wrap call, set exit code).

Current script logs success regardless of failures in the invoked function.

Apply this diff:

-const { checkAndBuildFoundationalPackages } = require("./dev-setup");
+const { checkAndBuildFoundationalPackages } = require("./dev-setup");

-console.log("πŸ—οΈ  Setting up Nimbus Design System foundational packages...\n");
-
-checkAndBuildFoundationalPackages();
-
-console.log("✨ Foundational packages setup complete!");
-console.log('πŸ’‘ Run "yarn start:dev" to start the development server.');
+console.log("πŸ—οΈ  Setting up Nimbus Design System foundational packages...\n");
+try {
+  checkAndBuildFoundationalPackages();
+  console.log("✨ Foundational packages setup complete!");
+  console.log('πŸ’‘ Run "yarn start:dev" to start the development server.');
+} catch (err) {
+  console.error("❌ Foundations setup failed.\n", err?.stderr?.toString?.() || err?.message || err);
+  process.exitCode = 1;
+}
πŸ“ Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const { checkAndBuildFoundationalPackages } = require("./dev-setup");
console.log("πŸ—οΈ Setting up Nimbus Design System foundational packages...\n");
checkAndBuildFoundationalPackages();
console.log("✨ Foundational packages setup complete!");
console.log('πŸ’‘ Run "yarn start:dev" to start the development server.');
const { checkAndBuildFoundationalPackages } = require("./dev-setup");
console.log("πŸ—οΈ Setting up Nimbus Design System foundational packages...\n");
try {
checkAndBuildFoundationalPackages();
console.log("✨ Foundational packages setup complete!");
console.log('πŸ’‘ Run "yarn start:dev" to start the development server.');
} catch (err) {
console.error(
"❌ Foundations setup failed.\n",
err?.stderr?.toString?.() || err?.message || err
);
process.exitCode = 1;
}
πŸ€– Prompt for AI Agents
In .scripts/setup-foundations.js around lines 10 to 17, the script currently
calls checkAndBuildFoundationalPackages() and always prints a success message
even if that call fails; wrap the invocation in a try/catch (await if the
function returns a Promise), move the success console.logs into the try block,
and in the catch block log the error with a clear message and set
process.exitCode = 1 (or call process.exit(1)) so the process fails fast on
errors.

48 changes: 48 additions & 0 deletions .yarn/versions/9e963b61.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
releases:
"@nimbus-ds/webpack": minor

declined:
- nimbus-design-system
- "@nimbus-ds/styles"
- "@nimbus-ds/typings"
- "@nimbus-ds/icons"
- "@nimbus-ds/components"
- "@nimbus-ds/badge"
- "@nimbus-ds/box"
- "@nimbus-ds/button"
- "@nimbus-ds/checkbox"
- "@nimbus-ds/chip"
- "@nimbus-ds/file-uploader"
- "@nimbus-ds/icon"
- "@nimbus-ds/icon-button"
- "@nimbus-ds/input"
- "@nimbus-ds/label"
- "@nimbus-ds/link"
- "@nimbus-ds/list"
- "@nimbus-ds/multi-select"
- "@nimbus-ds/popover"
- "@nimbus-ds/progress-bar"
- "@nimbus-ds/radio"
- "@nimbus-ds/select"
- "@nimbus-ds/skeleton"
- "@nimbus-ds/spinner"
- "@nimbus-ds/tag"
- "@nimbus-ds/text"
- "@nimbus-ds/textarea"
- "@nimbus-ds/thumbnail"
- "@nimbus-ds/title"
- "@nimbus-ds/toast"
- "@nimbus-ds/toggle"
- "@nimbus-ds/tooltip"
- "@nimbus-ds/accordion"
- "@nimbus-ds/alert"
- "@nimbus-ds/card"
- "@nimbus-ds/collapsible"
- "@nimbus-ds/modal"
- "@nimbus-ds/pagination"
- "@nimbus-ds/scroll-pane"
- "@nimbus-ds/segmented-control"
- "@nimbus-ds/sidebar"
- "@nimbus-ds/stepper"
- "@nimbus-ds/table"
- "@nimbus-ds/tabs"
64 changes: 64 additions & 0 deletions docs/DEVELOPMENT_SETUP.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# Development Setup Guide

This guide explains how to get the Nimbus Design System development environment running smoothly.

## Quick Start (New Contributors)

For new contributors or fresh clones, simply run:

```bash
yarn start:dev
```
Comment on lines +5 to +11
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick (assertive)

Call out required Node/Yarn versions upfront.

Helps avoid environment flakiness for new contributors.

Add right after β€œQuick Start”:

+> Prereqs
+> - Node 14.17–16.x (per package.json engines)
+> - Yarn 3.2+
πŸ“ Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
## Quick Start (New Contributors)
For new contributors or fresh clones, simply run:
```bash
yarn start:dev
```
## Quick Start (New Contributors)
> Prereqs
> - Node 14.17–16.x (per package.json engines)
> - Yarn 3.2+
For new contributors or fresh clones, simply run:
πŸ€– Prompt for AI Agents
In docs/DEVELOPMENT_SETUP.md around lines 5 to 11, add an explicit note
immediately after the "Quick Start" heading that states the required Node and
Yarn versions (e.g., "Requires Node >= X.Y.Z and Yarn >= A.B.C") and any
recommended NVM or installation guidance; ensure the versions are accurate for
the project, format it as a short single-line callout or bullet directly under
the header, and keep it concise so new contributors see version requirements
before running yarn start:dev.


**That's it!** The development setup is now intelligent and will:

1. πŸ” **Auto-detect** if foundational packages need building
2. πŸ”¨ **Auto-build** missing packages (`@nimbus-ds/tokens`, `@nimbus-ds/icons`)
3. πŸš€ **Start** the Storybook development server on `http://localhost:6006`

## Available Scripts

### `yarn start:dev`

**Recommended for development** - Intelligent setup that builds dependencies as needed and starts Storybook.

### `yarn setup:foundations`

**Build foundational packages only** - Useful for CI/CD or when you just want to ensure dependencies are built without starting the dev server.

### `yarn storybook`

**Direct Storybook start** - Only use this if you're sure all foundational packages are already built.
Comment on lines +21 to +31
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick (assertive)

Mention the single canonical dev command; de-emphasize direct Storybook.

Keeps folks on the supported path and avoids missing prebuilds.

Apply this tweak:

-### `yarn storybook`
-
-**Direct Storybook start** - Only use this if you're sure all foundational packages are already built.
+### `yarn storybook` (optional)
+
+Only if foundations are built (prefer `yarn start:dev`).
πŸ“ Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
### `yarn start:dev`
**Recommended for development** - Intelligent setup that builds dependencies as needed and starts Storybook.
### `yarn setup:foundations`
**Build foundational packages only** - Useful for CI/CD or when you just want to ensure dependencies are built without starting the dev server.
### `yarn storybook`
**Direct Storybook start** - Only use this if you're sure all foundational packages are already built.
### `yarn start:dev`
**Recommended for development** - Intelligent setup that builds dependencies as needed and starts Storybook.
### `yarn setup:foundations`
**Build foundational packages only** - Useful for CI/CD or when you just want to ensure dependencies are built without starting the dev server.
### `yarn storybook` (optional)
Only if foundations are built (prefer `yarn start:dev`).
πŸ€– Prompt for AI Agents
In docs/DEVELOPMENT_SETUP.md around lines 21 to 31, update the text to present a
single canonical development command (yarn start:dev) as the recommended
default, reword the yarn setup:foundations description to note it is for
CI/explicit prebuilds, and de-emphasize yarn storybook by adding a clear caution
that it should only be used when foundational packages are already built (or
after running setup:foundations or start:dev) so contributors follow the
supported path and avoid missing prebuilds.


## Foundational Packages

The following packages must be built before development can begin:

- **`@nimbus-ds/tokens`** - Design tokens (colors, spacing, typography, etc.)
- **`@nimbus-ds/icons`** - Icon components and SVG assets

These are now handled automatically by the development setup scripts.

## Troubleshooting

### "Module not found" errors for `@nimbus-ds/tokens` or `@nimbus-ds/icons`

This typically means foundational packages haven't been built. Solutions:

1. **Automatic**: Run `yarn start:dev` (will detect and build missing packages)
2. **Manual**: Run `yarn setup:foundations` then `yarn storybook`
3. **Full rebuild**: Run `yarn build:all` for a complete build

### Fresh clone setup

After cloning the repository:

```bash
# Install dependencies
yarn install

# Start development (auto-builds what's needed)
yarn start:dev
```
Comment on lines +56 to +62
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick (assertive)

Use yarn install --immutable with Yarn 3.

Guarantees lockfile fidelity in fresh clones.

Apply this tweak:

-# Install dependencies
-yarn install
+# Install dependencies (lockfile enforced)
+yarn install --immutable
πŸ“ Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
```bash
# Install dependencies
yarn install
# Start development (auto-builds what's needed)
yarn start:dev
```
πŸ€– Prompt for AI Agents
In docs/DEVELOPMENT_SETUP.md around lines 56 to 62, replace the plain "yarn
install" step with "yarn install --immutable" to enforce lockfile fidelity on
fresh clones; update the example command only (no other text changes) so
contributors run yarn install --immutable when following the setup instructions.


The smart setup will handle the rest!
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,10 @@
"publish:npm:stable": "yarn workspaces foreach -pv -pt --exclude nimbus-design-system --exclude nimbus-helper npm publish --tolerate-republish --access public",
"publish:rc": "babel-node -x .ts ./.scripts/publish-rc",
"reset": "yarn clean && rm -rf node_modules .yarn/cache .turbo && git clean -fdX",
"setup:foundations": "node .scripts/setup-foundations.js",
"setup:dev": "node .scripts/dev-setup.js",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick (assertive)

Avoid duplicate dev entry points (β€œsetup:dev” vs β€œstart:dev”).

Two nearly identical commands will drift and confuse contributors. Prefer a single canonical entry (start:dev) and drop the alias.

Apply this diff:

-    "setup:dev": "node .scripts/dev-setup.js",
πŸ“ Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"setup:dev": "node .scripts/dev-setup.js",
πŸ€– Prompt for AI Agents
In package.json around line 40, remove the duplicate "setup:dev" script and keep
the canonical "start:dev" entry; update any internal references (README,
CI/workflow files, other scripts) that call "setup:dev" to use "start:dev"
instead so there is a single development entry point and no drifting aliases.

"storybook": "storybook dev -p 6006",
"start:dev": "yarn storybook",
"start:dev": "node .scripts/dev-setup.js",
"test": "jest --passWithNoTests --no-cache --runInBand --watchAll=false",
"test:ci": "yarn types:check && jest --ci --coverage",
"test:coverage": "yarn test --coverage",
Expand Down
3 changes: 3 additions & 0 deletions packages/core/webpack/src/config/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ const webpack = ({
resolve: {
alias: aliasItems,
extensions: [".tsx", ".ts", ".js"],
// Improve resolution performance
symlinks: false,
cacheWithContext: false,
},
/**
* External dependencies configuration.
Expand Down
49 changes: 46 additions & 3 deletions packages/core/webpack/src/config/development.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,56 @@
* Created by: JΓΊnior Conquista (junior.conquista@nuvemshop.com.br)
*/
import { Configuration } from "webpack";
import { terserJSPlugin } from "../plugins";

const webpack: Configuration = {
devtool: "source-map",
output: {
// Disable path info
pathinfo: false,
// Improve output performance
clean: {
keep: /.*/,
},
Comment on lines +13 to +14
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick (assertive)

Clean configuration with keep-all pattern may cause stale file issues

The clean.keep: /.*/ pattern prevents any file cleanup, which could lead to stale or conflicting files accumulating in the output directory over time.

Consider keeping only essential files while allowing cleanup of truly stale content:

     clean: {
-      keep: /.*/,
+      keep: /\.(map|d\.ts)$/,  // Keep source maps and type definitions
     },
πŸ“ Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
keep: /.*/,
},
clean: {
keep: /\.(map|d\.ts)$/, // Keep source maps and type definitions
},
πŸ€– Prompt for AI Agents
In packages/core/webpack/src/config/development.ts around lines 13-14, the
clean.keep: /.*/ pattern disables cleanup and can leave stale build artifacts;
change it so only truly essential files are preserved (either remove the keep
property entirely to allow normal cleanup or replace /.*/ with an explicit array
of filenames/globs to retain, e.g. ['.gitkeep','important-manifest.json']), or
alternatively use cleanOnceBeforeBuildPatterns to whitelist necessary patterns
while allowing other files to be removed.

// Use faster hashing algorithm
hashFunction: "xxhash64",
},
optimization: {
minimize: true,
minimizer: [terserJSPlugin],
// Only optimize what's safe in a monorepo context
minimize: false,
// Keep these disabled to avoid issues with workspace dependencies
removeAvailableModules: false,
removeEmptyChunks: false,
splitChunks: false,
// Disable in development for faster builds
providedExports: false,
usedExports: false,
sideEffects: false,
},
// Enable build cache for faster subsequent builds
cache: {
type: "filesystem",
buildDependencies: {
config: [__filename],
},
cacheDirectory: ".cache/webpack",
name: `webpack-cache-${process.env.NODE_ENV || "development"}`,
// Improve cache performance
compression: "gzip",
maxAge: 604800000, // 7 days
store: "pack",
},
experiments: {
// Faster rebuilds
cacheUnaffected: true,
},
// Enable parallel processing
parallelism: 100,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick (assertive)

Parallelism value of 100 may be excessive

Setting parallelism: 100 could overwhelm systems with limited resources. The default (100) is already quite high, but explicitly setting it removes the ability for webpack to auto-adjust based on system capabilities.

Consider using a CPU-aware calculation similar to the dtsBundleGeneratorPlugin:

-  parallelism: 100,
+  parallelism: Math.min(100, Math.max(10, require("os").cpus().length * 4)),
πŸ“ Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
parallelism: 100,
parallelism: Math.min(100, Math.max(10, require("os").cpus().length * 4)),
πŸ€– Prompt for AI Agents
In packages/core/webpack/src/config/development.ts around line 48, the hardcoded
parallelism: 100 is too aggressive and prevents webpack from adapting to the
host machine; replace the literal with a CPU-aware value (e.g., derive from
os.cpus().length, capping to a reasonable max and enforcing a minimum of 1) or
remove the explicit setting so webpack auto-adjusts; implement the calculation
inline or reuse the same helper used by dtsBundleGeneratorPlugin, and ensure the
resulting value is an integer and constrained by a sensible upper bound.

// Reduce stat output in development
stats: "minimal",
// Improve module resolution performance
snapshot: {
// Disables default behavior. Changes in linked deps should not be ignored in builds/watch.
managedPaths: [],
},
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,14 +63,16 @@ export class MoveFilesIntoDistFolderPlugin {
];

console.log(`Moving ${filesToMove.join(" & ")} to ${outputPath}`);
await Promise.all(
await Promise.allSettled(
filesToMove.map(async (fileName) => {
const sourcePath = path.resolve(compiler.context, fileName);
const destFilePath = path.join(outputPath, fileName);
try {
await fs.copyFile(sourcePath, destFilePath);
} catch (err: any) {
if (err.code !== "ENOENT") throw err; // Ignore missing files
if (err.code !== "ENOENT") {
console.warn(`Failed to copy ${fileName}:`, err.message);
}
}
})
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
*/

import WebpackShellPluginNextPlugin from "webpack-shell-plugin-next";
import os from "os";
import { rootDir } from "../utils";

const entry = [
Expand All @@ -17,6 +18,13 @@ export const dtsBundleGeneratorPlugin = (
scripts: [...configuration.entries],
blocking: false,
parallel: true,
// Optimize memory usage and performance for parallel execution
parallelOptions: {
maxConcurrentProcesses: Math.min(
8,
Math.max(2, Math.ceil(os.cpus().length * 0.75))
),
},
},
};

Expand Down
12 changes: 12 additions & 0 deletions packages/core/webpack/src/rules/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,16 @@ export const typescriptRule = {
test: /\.tsx?$/,
loader: "ts-loader",
exclude: /node_modules/,
options: {
// Enable type checking in a separate process
transpileOnly: true,
compilerOptions: {
// Skip type checking
isolatedModules: true,
Comment on lines +16 to +17
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Comment contradicts the configuration

The comment states "Skip type checking" but isolatedModules: true doesn't skip type checking - it ensures each file can be transpiled independently. This is a requirement for transpileOnly mode, not a performance optimization.

Update the comment to accurately describe the setting:

-      // Skip type checking
+      // Ensure each file can be transpiled independently (required for transpileOnly)
πŸ“ Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// Skip type checking
isolatedModules: true,
// Ensure each file can be transpiled independently (required for transpileOnly)
isolatedModules: true,
πŸ€– Prompt for AI Agents
In packages/core/webpack/src/rules/common.ts around lines 16-17, the existing
comment "Skip type checking" is incorrect for the setting isolatedModules: true;
update the comment to accurately describe that isolatedModules ensures each file
can be transpiled independently (a requirement for transpileOnly mode) and does
not itself skip type checking or act as a performance optimization.

// Improve module resolution speed
moduleResolution: "node",
// Use incremental compilation
incremental: true,
},
},
Comment on lines +12 to +23
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

πŸ’‘ Verification agent

🧩 Analysis chain

transpileOnly disables all type checking - ensure alternative validation exists

Setting transpileOnly: true completely bypasses TypeScript type checking during builds, which could allow type errors to slip into production. While this significantly speeds up development builds, ensure that:

  1. Type checking runs in CI/CD pipelines
  2. Pre-commit hooks validate types
  3. IDE/editor integration provides real-time type feedback

🏁 Script executed:

#!/bin/bash
# Check if type checking is configured elsewhere
echo "Checking for TypeScript type checking in package.json scripts..."
fd -e json -x grep -l "tsc" {} \; | head -10

echo -e "\nChecking for type checking in CI workflows..."
fd -e yml -e yaml -p ".github" -x grep -l "tsc\|typecheck\|type-check" {} \; 2>/dev/null

echo -e "\nChecking for pre-commit hooks..."
if [ -f ".husky/pre-commit" ]; then
  cat .husky/pre-commit
fi

echo -e "\nChecking turbo.json for typecheck targets..."
if [ -f "turbo.json" ]; then
  cat turbo.json | jq '.pipeline | keys[] | select(contains("type") or contains("check"))'
fi

Length of output: 668


🏁 Script executed:

#!/bin/bash
set -e

echo "=== Listing CI configuration directories ==="
fd .github/workflows -t f || echo "No .github/workflows directory"
fd .circleci -t f || echo "No .circleci directory"

echo -e "\n=== Root YAML files ==="
ls *.yml *.yaml 2>/dev/null || echo "No root-level YAML files"

echo -e "\n=== Root package.json scripts ==="
jq '.scripts' package.json

echo -e "\n=== Root package.json lint-staged config ==="
jq '.["lint-staged"]' package.json || echo "No lint-staged config in package.json"

echo -e "\n=== Husky pre-commit hook ==="
if [ -f ".husky/pre-commit" ]; then
  cat .husky/pre-commit
else
  echo "No .husky/pre-commit file"
fi

echo -e "\n=== turbo.json pipeline keys and commands ==="
jq '.pipeline' turbo.json

echo -e "\n=== Looking for types:check script in package.json ==="
jq '.scripts["types:check"]' package.json || echo "No types:check script found"

Length of output: 4071


Enforce Type Checking Outside Webpack
Transpiling with transpileOnly: true skips all TS checksβ€”although you have a types:check script, there’s no automation invoking it:

  • CI: no .github/workflows or other CI config runs yarn types:check
  • Pre-push: no .husky/pre-push hook (only a pre-commit calling lint-staged)
  • lint-staged: no config found, so pre-commit won’t catch type errors

Add or confirm automated yarn types:check runs in your CI/CD pipeline, a Husky pre-push hook, and/or lint-staged tasks to prevent slipped type errors.

πŸ€– Prompt for AI Agents
packages/core/webpack/src/rules/common.ts lines 12-23: currently ts-loader is
configured with transpileOnly: true which skips TypeScript type checks; ensure
type checking is enforced outside Webpack by adding automated runs of your type
check script (yarn types:check) β€” add a CI job in your GitHub Actions (or other
CI) workflow to run yarn types:check, add a Husky pre-push hook that runs yarn
types:check (or run it via lint-staged for changed files), and/or update
lint-staged to include a type-check task so type errors cannot be slipped
through commits or CI.

};
4 changes: 2 additions & 2 deletions packages/core/webpack/src/utils/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export const getComponentsPackageExports = (

const allComponents = getDirectories(baseDir, folders);

// Process each component folder
// Process each component folder in parallel for better performance
allComponents.forEach((componentPath) => {
Comment on lines +42 to 43
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Comment misleads: forEach is sequential, not parallel

The comment states "Process each component folder in parallel for better performance", but the implementation uses forEach which executes synchronously. This creates a false expectation about the code's behavior.

Either update the comment to reflect the sequential nature:

-  // Process each component folder in parallel for better performance
+  // Process each component folder

Or implement actual parallel processing if performance is a concern:

-  // Process each component folder in parallel for better performance
-  allComponents.forEach((componentPath) => {
+  // Process each component folder in parallel for better performance
+  await Promise.all(allComponents.map(async (componentPath) => {
πŸ“ Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// Process each component folder in parallel for better performance
allComponents.forEach((componentPath) => {
// Process each component folder
allComponents.forEach((componentPath) => {
πŸ€– Prompt for AI Agents
In packages/core/webpack/src/utils/helpers.ts around lines 42 to 43, the inline
comment claims "Process each component folder in parallel for better
performance" but the code uses allComponents.forEach which runs synchronously;
either update the comment to accurately state it's sequential, or change the
implementation to true parallel processing by mapping allComponents to an array
of promises (e.g., allComponents.map(componentPath =>
processComponent(componentPath))) and awaiting them with Promise.all, and ensure
proper error handling/propagation for the Promise.all result.

const componentName = path.basename(componentPath);
const componentDir = path.join(baseDir, componentPath);
Expand Down Expand Up @@ -72,7 +72,7 @@ export const getComponentsPackageExports = (
webpackEntries[componentName] = entryFile;

// 4. Prepare the DTS bundle generator command for this component, removing the temp file after running it for cleanup
const dtsCommand = `node ${rootDir}/node_modules/.bin/dts-bundle-generator -o ./dist/${componentName}/index.d.ts ${entryFile} ${extraCommands.join(
const dtsCommand = `node --max-old-space-size=1024 ${rootDir}/node_modules/.bin/dts-bundle-generator -o ./dist/${componentName}/index.d.ts ${entryFile} ${extraCommands.join(
""
)}`;
Comment on lines +75 to 77
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick (assertive)

Node memory flag may be insufficient for large component libraries

The 1024MB heap size limit might be too restrictive for projects with many components or complex type definitions. Consider making this configurable or using a higher default.

Consider parameterizing the memory allocation:

-    const dtsCommand = `node --max-old-space-size=1024 ${rootDir}/node_modules/.bin/dts-bundle-generator -o ./dist/${componentName}/index.d.ts ${entryFile} ${extraCommands.join(
+    const memorySize = process.env.DTS_MEMORY_SIZE || '2048';
+    const dtsCommand = `node --max-old-space-size=${memorySize} ${rootDir}/node_modules/.bin/dts-bundle-generator -o ./dist/${componentName}/index.d.ts ${entryFile} ${extraCommands.join(
πŸ“ Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const dtsCommand = `node --max-old-space-size=1024 ${rootDir}/node_modules/.bin/dts-bundle-generator -o ./dist/${componentName}/index.d.ts ${entryFile} ${extraCommands.join(
""
)}`;
// Parameterize Node heap size for dts-bundle-generator
const memorySize = process.env.DTS_MEMORY_SIZE || '2048';
const dtsCommand = `node --max-old-space-size=${memorySize} ${rootDir}/node_modules/.bin/dts-bundle-generator -o ./dist/${componentName}/index.d.ts ${entryFile} ${extraCommands.join(
""
)}`;
πŸ€– Prompt for AI Agents
In packages/core/webpack/src/utils/helpers.ts around lines 75 to 77, the
hardcoded Node heap flag (--max-old-space-size=1024) is too small for large
component libraries; make the memory allocation configurable by introducing a
parameter (or environment variable) for maxOldSpaceSize with a sensible larger
default (e.g., 4096), update the function signature to accept this option (or
read process.env.DTS_MEMORY_MB), validate/coerce to a number, and use that
variable in the dtsCommand string instead of the hardcoded 1024 so callers or CI
can tune memory without changing code.

dtsCommands.push(dtsCommand);
Expand Down
Loading