-
Notifications
You must be signed in to change notification settings - Fork 646
feat(styled-react): Add an automatic generation of a components.json file to be used in the primer-react/use-styled-react-import eslint plugin
#6848
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
🦋 Changeset detectedLatest commit: 2a84655 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR adds automatic generation of a components.json file for the @primer/styled-react package, providing consumers with a machine-readable list of all exported components, utilities, and types. The feature extracts exports from the main index file during build time and categorizes them into components, utilities, and types with package metadata.
Key changes:
- Added build-time script to parse exports and generate structured JSON
- Integrated JSON generation into the build process
- Added export path configuration for the components.json file
Reviewed Changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 5 comments.
| File | Description |
|---|---|
| packages/styled-react/script/generate-components-json | New Node.js script that parses the main index.tsx file and categorizes exports into components, utilities, and types |
| packages/styled-react/script/build | Updated build script to include components.json generation step after rollup compilation |
| packages/styled-react/package.json | Added export path for "./components.json" to make the generated file importable by consumers |
| packages/styled-react/README.md | Added documentation section explaining the components.json feature with usage examples |
| const types = [...typeExports] // All type exports go into types | ||
|
|
||
| // Known utility patterns | ||
| const utilityPatterns = ['merge', 'sx', 'theme', 'themeGet', 'useColorSchemeVar', 'useTheme'] |
Copilot
AI
Sep 12, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The utility patterns are hardcoded in the script. Consider moving this list to a configuration file or making it discoverable through naming conventions to reduce maintenance overhead when utilities are added or removed.
| const typeExports = [] | ||
|
|
||
| // Extract regular exports (handle multi-line exports) | ||
| const exportRegex = /export\s*\{\s*([\s\S]*?)\s*\}/g |
Copilot
AI
Sep 12, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The regex patterns for parsing exports may not handle all edge cases of TypeScript/JavaScript syntax. Consider using a proper AST parser like @babel/parser or typescript compiler API for more robust parsing.
| } | ||
|
|
||
| // Extract type exports (handle multi-line exports) | ||
| const typeExportRegex = /export\s+type\s*\{\s*([\s\S]*?)\s*\}/g |
Copilot
AI
Sep 12, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The regex patterns for parsing exports may not handle all edge cases of TypeScript/JavaScript syntax. Consider using a proper AST parser like @babel/parser or typescript compiler API for more robust parsing.
| } | ||
|
|
||
| // Extract direct exports | ||
| const directExportRegex = /export\s+(?:const|let|var|function|class)\s+(\w+)/g |
Copilot
AI
Sep 12, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The regex patterns for parsing exports may not handle all edge cases of TypeScript/JavaScript syntax. Consider using a proper AST parser like @babel/parser or typescript compiler API for more robust parsing.
|
|
||
| async function generateComponentsJson() { | ||
| try { | ||
| const srcPath = path.join(__dirname, '..', 'src', 'index.tsx') |
Copilot
AI
Sep 12, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The source file path is hardcoded. Consider making this configurable or deriving it from package.json to improve flexibility if the entry point changes.
| const srcPath = path.join(__dirname, '..', 'src', 'index.tsx') | |
| // Read package.json to get the entry point | |
| const pkgJsonPath = path.join(__dirname, '..', 'package.json') | |
| const pkgJsonContent = await fs.readFile(pkgJsonPath, 'utf-8') | |
| const pkgJson = JSON.parse(pkgJsonContent) | |
| // Use 'main' field, fallback to 'src/index.tsx' if not present | |
| const entryRelative = pkgJson.main || 'src/index.tsx' | |
| const srcPath = path.join(__dirname, '..', entryRelative) |
size-limit report 📦
|
| metadata: { | ||
| package: '@primer/styled-react', | ||
| description: 'Exported components and utilities from the Primer styled-react package', | ||
| totalComponents: categorized.components.length, | ||
| totalUtilities: categorized.utilities.length, | ||
| totalTypes: categorized.types.length, | ||
| generatedAt: new Date().toISOString().split('T')[0], | ||
| }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need any of this for the rule? Wasn't sure if we needed this kind of metadata or not
| } | ||
|
|
||
| // Extract type exports (handle multi-line exports) | ||
| const typeExportRegex = /export\s+type\s*\{\s*([\s\S]*?)\s*\}/g |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it be possible to match what the copilot comment left and use AST for parsing instead of regex? Would help make things more reliable, I think, if we want to depend on this file
Co-authored-by: Josh Black <joshblack@users.noreply.github.com>
This PR adds automatic generation of a
components.jsonfile during the build process for the@primer/styled-reactpackage. This provides consumers with a machine-readable list of all exported components, utilities, and types.Problem
Previously, there was no programmatic way for consumers to discover what components and utilities are available in the
@primer/styled-reactpackage without manually inspecting the source code or documentation.Solution
Added a build-time script that automatically parses the main
index.tsxfile and generates a structured JSON file containing:Usage
Changelog
New
script/generate-components-jsonbuild script to automatically extract and categorize exportscomponents.jsonexport path to package.json exports map/dist/components.jsonduring build processChanged
script/buildto include components.json generation stepRemoved
Rollout strategy
Rationale: This is a new feature that adds functionality without breaking existing APIs. The components.json file is additive and provides new capabilities for package consumers.
Testing & Reviewing
To test this PR:
npm run buildinpackages/styled-react/dist/components.jsonis created with correct structure@primer/styled-react/components.jsonKey files to review:
packages/styled-react/script/generate-components-json- The extraction and generation logicpackages/styled-react/script/build- Integration into build processpackages/styled-react/package.json- Export path configurationpackages/styled-react/README.md- Updated documentationExample generated structure:
{ "components": ["ActionList", "Avatar", "Box", ...], "utilities": ["merge", "sx", "theme", ...], "types": ["BetterSystemStyleObject", "BoxProps", "SxProp"], }Merge checklist