[UI-Filecoin] Enable JIT compilation for filecoin-site#2143
[UI-Filecoin] Enable JIT compilation for filecoin-site#2143CharlyMartin wants to merge 3 commits intomainfrom
Conversation
- Add transpilePackages support to ui-filecoin for JIT compilation - Configure Next.js to transpile ui-filecoin from source - Add tsup build tool for dual ESM/CJS npm publishing - Update package exports to point to source files - Add .npmignore to include dist/ in npm package - Changes to ui-filecoin now appear instantly in dev without rebuild
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
Pull request overview
This PR enables Just-In-Time (JIT) compilation for the ui-filecoin package to provide instant hot-reload in the filecoin-site app during development. The implementation adds tsup as a build tool, configures Next.js transpilePackages support, and updates package exports to point directly to TypeScript source files.
Changes:
- Added tsup build configuration with dual ESM/CJS output and sourcemaps
- Restructured package exports to point to source .tsx files instead of compiled .js files
- Configured filecoin-site to transpile ui-filecoin via Next.js transpilePackages option
Reviewed changes
Copilot reviewed 5 out of 6 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/ui-filecoin/tsup.config.ts | New build configuration using tsup for dual ESM/CJS compilation with external dependencies |
| packages/ui-filecoin/package.json | Updated exports to source files, modified build scripts to use tsup, added tsup as dev dependency |
| packages/ui-filecoin/.npmignore | Added file to exclude development files while including both src/ and dist/ for npm publishing |
| packages/next-config/src/createNextConfig.js | Added optional transpilePackages parameter to support JIT compilation |
| package-lock.json | Added tsup and its dependencies, version bump for ui-filecoin dependency |
| apps/filecoin-site/next.config.ts | Enabled transpilePackages for ui-filecoin to support JIT compilation |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| }, | ||
| "scripts": { | ||
| "build": "tsc && mkdir -p dist/styles && cp src/styles/*.css dist/styles/", | ||
| "build": "tsup && cp -r src/styles dist/", |
There was a problem hiding this comment.
The build script uses 'cp -r src/styles dist/' which works on Unix-based systems but will fail on Windows. Consider using a cross-platform solution like the 'cpy-cli' package or 'cpx' to ensure the build works on all platforms, or document that Windows users need WSL or Git Bash.
| "exports": { | ||
| "./Alert": { | ||
| "types": "./dist/components/Alert.d.ts", | ||
| "default": "./dist/components/Alert.js" | ||
| }, | ||
| "./Announcement": { | ||
| "types": "./dist/components/Announcement.d.ts", | ||
| "default": "./dist/components/Announcement.js" | ||
| }, | ||
| "./Badge": { | ||
| "types": "./dist/components/Badge.d.ts", | ||
| "default": "./dist/components/Badge.js" | ||
| }, | ||
| "./BaseLink": { | ||
| "types": "./dist/components/BaseLink.d.ts", | ||
| "default": "./dist/components/BaseLink.js" | ||
| }, | ||
| "./BreakpointDebugger": { | ||
| "types": "./dist/components/BreakpointDebugger.d.ts", | ||
| "default": "./dist/components/BreakpointDebugger.js" | ||
| }, | ||
| "./Button": { | ||
| "types": "./dist/components/Button.d.ts", | ||
| "default": "./dist/components/Button.js" | ||
| }, | ||
| "./ButtonRow": { | ||
| "types": "./dist/components/ButtonRow.d.ts", | ||
| "default": "./dist/components/ButtonRow.js" | ||
| }, | ||
| "./Card": { | ||
| "types": "./dist/components/Card/Card.d.ts", | ||
| "default": "./dist/components/Card/Card.js" | ||
| }, | ||
| "./Card/CardImage": { | ||
| "types": "./dist/components/Card/CardImage.d.ts", | ||
| "default": "./dist/components/Card/CardImage.js" | ||
| }, | ||
| "./CardGrid": { | ||
| "types": "./dist/components/CardGrid.d.ts", | ||
| "default": "./dist/components/CardGrid.js" | ||
| }, | ||
| "./BreakoutContainer": { | ||
| "types": "./dist/components/BreakoutContainer.d.ts", | ||
| "default": "./dist/components/BreakoutContainer.js" | ||
| }, | ||
| "./Container": { | ||
| "types": "./dist/components/Container.d.ts", | ||
| "default": "./dist/components/Container.js" | ||
| }, | ||
| "./CTALink": { | ||
| "types": "./dist/components/CTALink.d.ts", | ||
| "default": "./dist/components/CTALink.js" | ||
| }, | ||
| "./Checkbox": { | ||
| "types": "./dist/components/Checkbox.d.ts", | ||
| "default": "./dist/components/Checkbox.js" | ||
| }, | ||
| "./EmptyStateCard": { | ||
| "types": "./dist/components/EmptyStateCard.d.ts", | ||
| "default": "./dist/components/EmptyStateCard.js" | ||
| }, | ||
| "./ErrorStateCard": { | ||
| "types": "./dist/components/ErrorStateCard.d.ts", | ||
| "default": "./dist/components/ErrorStateCard.js" | ||
| }, | ||
| "./Footer/LegalSection": { | ||
| "types": "./dist/components/Footer/LegalSection.d.ts", | ||
| "default": "./dist/components/Footer/LegalSection.js" | ||
| }, | ||
| "./FilterButton": { | ||
| "types": "./dist/components/FilterButton.d.ts", | ||
| "default": "./dist/components/FilterButton.js" | ||
| }, | ||
| "./Heading": { | ||
| "types": "./dist/components/Heading.d.ts", | ||
| "default": "./dist/components/Heading.js" | ||
| }, | ||
| "./HomeLogoLink": { | ||
| "types": "./dist/components/HomeLogoLink.d.ts", | ||
| "default": "./dist/components/HomeLogoLink.js" | ||
| }, | ||
| "./Icon": { | ||
| "types": "./dist/components/Icon.d.ts", | ||
| "default": "./dist/components/Icon.js" | ||
| }, | ||
| "./IconBadge": { | ||
| "types": "./dist/components/IconBadge.d.ts", | ||
| "default": "./dist/components/IconBadge.js" | ||
| }, | ||
| "./IconButton": { | ||
| "types": "./dist/components/IconButton.d.ts", | ||
| "default": "./dist/components/IconButton.js" | ||
| }, | ||
| "./InfoCard": { | ||
| "types": "./dist/components/InfoCard.d.ts", | ||
| "default": "./dist/components/InfoCard.js" | ||
| }, | ||
| "./Input": { | ||
| "types": "./dist/components/Input.d.ts", | ||
| "default": "./dist/components/Input.js" | ||
| }, | ||
| "./LinkCard": { | ||
| "types": "./dist/components/LinkCard.d.ts", | ||
| "default": "./dist/components/LinkCard.js" | ||
| }, | ||
| "./LoadingStateCard": { | ||
| "types": "./dist/components/LoadingStateCard.d.ts", | ||
| "default": "./dist/components/LoadingStateCard.js" | ||
| }, | ||
| "./Table": { | ||
| "types": "./dist/components/Table.d.ts", | ||
| "default": "./dist/components/Table.js" | ||
| }, | ||
| "./Table/CompactAddress": { | ||
| "types": "./dist/components/Table/CompactAddress.d.ts", | ||
| "default": "./dist/components/Table/CompactAddress.js" | ||
| }, | ||
| "./Table/ID": { | ||
| "types": "./dist/components/Table/ID.d.ts", | ||
| "default": "./dist/components/Table/ID.js" | ||
| }, | ||
| "./Table/PeerID": { | ||
| "types": "./dist/components/Table/PeerID.d.ts", | ||
| "default": "./dist/components/Table/PeerID.js" | ||
| }, | ||
| "./Table/SoftwareVersion": { | ||
| "types": "./dist/components/Table/SoftwareVersion.d.ts", | ||
| "default": "./dist/components/Table/SoftwareVersion.js" | ||
| }, | ||
| "./Table/ActiveStatus": { | ||
| "types": "./dist/components/Table/ActiveStatus.d.ts", | ||
| "default": "./dist/components/Table/ActiveStatus.js" | ||
| }, | ||
| "./Table/YesNoStatus": { | ||
| "types": "./dist/components/Table/YesNoStatus.d.ts", | ||
| "default": "./dist/components/Table/YesNoStatus.js" | ||
| }, | ||
| "./Table/TanstackTable": { | ||
| "types": "./dist/components/Table/TanstackTable.d.ts", | ||
| "default": "./dist/components/Table/TanstackTable.js" | ||
| }, | ||
| "./Listbox": { | ||
| "types": "./dist/components/Listbox.d.ts", | ||
| "default": "./dist/components/Listbox.js" | ||
| }, | ||
| "./LogoSection/LogoSection": { | ||
| "types": "./dist/components/LogoSection/LogoSection.d.ts", | ||
| "default": "./dist/components/LogoSection/LogoSection.js" | ||
| }, | ||
| "./LogoSection/LogoItem": { | ||
| "types": "./dist/components/LogoSection/LogoItem.d.ts", | ||
| "default": "./dist/components/LogoSection/LogoItem.js" | ||
| }, | ||
| "./Markdown/MarkdownContent": { | ||
| "types": "./dist/components/Markdown/MarkdownContent.d.ts", | ||
| "default": "./dist/components/Markdown/MarkdownContent.js" | ||
| }, | ||
| "./Markdown/MarkdownLink": { | ||
| "types": "./dist/components/Markdown/MarkdownLink.d.ts", | ||
| "default": "./dist/components/Markdown/MarkdownLink.js" | ||
| }, | ||
| "./Markdown/MarkdownPage": { | ||
| "types": "./dist/components/Markdown/MarkdownPage.d.ts", | ||
| "default": "./dist/components/Markdown/MarkdownPage.js" | ||
| }, | ||
| "./Navigation/MobileNavigation": { | ||
| "types": "./dist/components/Navigation/MobileNavigation.d.ts", | ||
| "default": "./dist/components/Navigation/MobileNavigation.js" | ||
| }, | ||
| "./Navigation/NavigationMainLink": { | ||
| "types": "./dist/components/Navigation/NavigationMainLink.d.ts", | ||
| "default": "./dist/components/Navigation/NavigationMainLink.js" | ||
| }, | ||
| "./Navigation/NavigationMenu": { | ||
| "types": "./dist/components/Navigation/NavigationMenu.d.ts", | ||
| "default": "./dist/components/Navigation/NavigationMenu.js" | ||
| }, | ||
| "./Navigation/NavigationMenuLink": { | ||
| "types": "./dist/components/Navigation/NavigationMenuLink.d.ts", | ||
| "default": "./dist/components/Navigation/NavigationMenuLink.js" | ||
| }, | ||
| "./Navigation/NavigationMenuPanel": { | ||
| "types": "./dist/components/Navigation/NavigationMenuPanel.d.ts", | ||
| "default": "./dist/components/Navigation/NavigationMenuPanel.js" | ||
| }, | ||
| "./Navigation/constants": { | ||
| "types": "./dist/components/Navigation/constants/index.d.ts", | ||
| "default": "./dist/components/Navigation/constants/index.js" | ||
| }, | ||
| "./Navigation/types": { | ||
| "types": "./dist/components/Navigation/types/index.d.ts", | ||
| "default": "./dist/components/Navigation/types/index.js" | ||
| }, | ||
| "./Navigation/hooks/*": { | ||
| "types": "./dist/components/Navigation/hooks/*.d.ts", | ||
| "default": "./dist/components/Navigation/hooks/*.js" | ||
| }, | ||
| "./PageHeader": { | ||
| "types": "./dist/components/PageHeader.d.ts", | ||
| "default": "./dist/components/PageHeader.js" | ||
| }, | ||
| "./PageSection": { | ||
| "types": "./dist/components/PageSection.d.ts", | ||
| "default": "./dist/components/PageSection.js" | ||
| }, | ||
| "./RefreshButton": { | ||
| "types": "./dist/components/RefreshButton.d.ts", | ||
| "default": "./dist/components/RefreshButton.js" | ||
| }, | ||
| "./RefreshOverlay": { | ||
| "types": "./dist/components/RefreshOverlay.d.ts", | ||
| "default": "./dist/components/RefreshOverlay.js" | ||
| }, | ||
| "./Network/useNetwork": { | ||
| "types": "./dist/components/Network/useNetwork.d.ts", | ||
| "default": "./dist/components/Network/useNetwork.js" | ||
| }, | ||
| "./Network/NetworkSelector": { | ||
| "types": "./dist/components/Network/NetworkSelector.d.ts", | ||
| "default": "./dist/components/Network/NetworkSelector.js" | ||
| }, | ||
| "./Network/config": { | ||
| "types": "./dist/components/Network/config/index.d.ts", | ||
| "default": "./dist/components/Network/config/index.js" | ||
| }, | ||
| "./Network/types": { | ||
| "types": "./dist/components/Network/types/index.d.ts", | ||
| "default": "./dist/components/Network/types/index.js" | ||
| }, | ||
| "./Section/Section": { | ||
| "types": "./dist/components/Section/Section.d.ts", | ||
| "default": "./dist/components/Section/Section.js" | ||
| }, | ||
| "./SectionContent": { | ||
| "types": "./dist/components/SectionContent.d.ts", | ||
| "default": "./dist/components/SectionContent.js" | ||
| }, | ||
| "./Search": { | ||
| "types": "./dist/components/Search/index.d.ts", | ||
| "default": "./dist/components/Search/index.js" | ||
| }, | ||
| "./SimpleCard": { | ||
| "types": "./dist/components/SimpleCard.d.ts", | ||
| "default": "./dist/components/SimpleCard.js" | ||
| }, | ||
| "./SlideOver": { | ||
| "types": "./dist/components/SlideOver.d.ts", | ||
| "default": "./dist/components/SlideOver.js" | ||
| }, | ||
| "./Spinner": { | ||
| "types": "./dist/components/Spinner.d.ts", | ||
| "default": "./dist/components/Spinner.js" | ||
| }, | ||
| "./StateCard": { | ||
| "types": "./dist/components/StateCard.d.ts", | ||
| "default": "./dist/components/StateCard.js" | ||
| }, | ||
| "./SearchInput": { | ||
| "types": "./dist/components/SearchInput.d.ts", | ||
| "default": "./dist/components/SearchInput.js" | ||
| }, | ||
| "./TextLink/ExternalTextLink": { | ||
| "types": "./dist/components/TextLink/ExternalTextLink.d.ts", | ||
| "default": "./dist/components/TextLink/ExternalTextLink.js" | ||
| }, | ||
| "./TextLink/InternalTextLink": { | ||
| "types": "./dist/components/TextLink/InternalTextLink.d.ts", | ||
| "default": "./dist/components/TextLink/InternalTextLink.js" | ||
| }, | ||
| "./TextLink/SmartTextLink": { | ||
| "types": "./dist/components/TextLink/SmartTextLink.d.ts", | ||
| "default": "./dist/components/TextLink/SmartTextLink.js" | ||
| }, | ||
| "./constants/tailwindConstants": { | ||
| "types": "./dist/constants/tailwindConstants.d.ts", | ||
| "default": "./dist/constants/tailwindConstants.js" | ||
| }, | ||
| "./styles": "./dist/styles/globals.css", | ||
| "./types/imageType": { | ||
| "types": "./dist/types/imageType.d.ts", | ||
| "default": "./dist/types/imageType.js" | ||
| }, | ||
| "./types/tailwindTypes": { | ||
| "types": "./dist/types/tailwindTypes.d.ts", | ||
| "default": "./dist/types/tailwindTypes.js" | ||
| }, | ||
| "./types/touchTarget": { | ||
| "types": "./dist/types/touchTarget.d.ts", | ||
| "default": "./dist/types/touchTarget.js" | ||
| }, | ||
| "./utils": { | ||
| "types": "./dist/utils/index.d.ts", | ||
| "default": "./dist/utils/index.js" | ||
| }, | ||
| "./config/ui-config": { | ||
| "types": "./dist/config/ui-config.d.ts", | ||
| "default": "./dist/config/ui-config.js" | ||
| } | ||
| "./Alert": "./src/components/Alert.tsx", | ||
| "./Announcement": "./src/components/Announcement.tsx", | ||
| "./Badge": "./src/components/Badge.tsx", | ||
| "./BaseLink": "./src/components/BaseLink.tsx", | ||
| "./BreakpointDebugger": "./src/components/BreakpointDebugger.tsx", | ||
| "./Button": "./src/components/Button.tsx", | ||
| "./ButtonRow": "./src/components/ButtonRow.tsx", | ||
| "./Card": "./src/components/Card/Card.tsx", | ||
| "./Card/CardImage": "./src/components/Card/CardImage.tsx", | ||
| "./CardGrid": "./src/components/CardGrid.tsx", | ||
| "./BreakoutContainer": "./src/components/BreakoutContainer.tsx", | ||
| "./Container": "./src/components/Container.tsx", | ||
| "./CTALink": "./src/components/CTALink.tsx", | ||
| "./Checkbox": "./src/components/Checkbox.tsx", | ||
| "./EmptyStateCard": "./src/components/EmptyStateCard.tsx", | ||
| "./ErrorStateCard": "./src/components/ErrorStateCard.tsx", | ||
| "./Footer/LegalSection": "./src/components/Footer/LegalSection.tsx", | ||
| "./FilterButton": "./src/components/FilterButton.tsx", | ||
| "./Heading": "./src/components/Heading.tsx", | ||
| "./HomeLogoLink": "./src/components/HomeLogoLink.tsx", | ||
| "./Icon": "./src/components/Icon.tsx", | ||
| "./IconBadge": "./src/components/IconBadge.tsx", | ||
| "./IconButton": "./src/components/IconButton.tsx", | ||
| "./InfoCard": "./src/components/InfoCard.tsx", | ||
| "./Input": "./src/components/Input.tsx", | ||
| "./LinkCard": "./src/components/LinkCard.tsx", | ||
| "./LoadingStateCard": "./src/components/LoadingStateCard.tsx", | ||
| "./Table": "./src/components/Table.tsx", | ||
| "./Table/CompactAddress": "./src/components/Table/CompactAddress.tsx", | ||
| "./Table/ID": "./src/components/Table/ID.tsx", | ||
| "./Table/PeerID": "./src/components/Table/PeerID.tsx", | ||
| "./Table/SoftwareVersion": "./src/components/Table/SoftwareVersion.tsx", | ||
| "./Table/ActiveStatus": "./src/components/Table/ActiveStatus.tsx", | ||
| "./Table/YesNoStatus": "./src/components/Table/YesNoStatus.tsx", | ||
| "./Table/TanstackTable": "./src/components/Table/TanstackTable.tsx", | ||
| "./Listbox": "./src/components/Listbox.tsx", | ||
| "./LogoSection/LogoSection": "./src/components/LogoSection/LogoSection.tsx", | ||
| "./LogoSection/LogoItem": "./src/components/LogoSection/LogoItem.tsx", | ||
| "./Markdown/MarkdownContent": "./src/components/Markdown/MarkdownContent.tsx", | ||
| "./Markdown/MarkdownLink": "./src/components/Markdown/MarkdownLink.tsx", | ||
| "./Markdown/MarkdownPage": "./src/components/Markdown/MarkdownPage.tsx", | ||
| "./Navigation/MobileNavigation": "./src/components/Navigation/MobileNavigation.tsx", | ||
| "./Navigation/NavigationMainLink": "./src/components/Navigation/NavigationMainLink.tsx", | ||
| "./Navigation/NavigationMenu": "./src/components/Navigation/NavigationMenu.tsx", | ||
| "./Navigation/NavigationMenuLink": "./src/components/Navigation/NavigationMenuLink.tsx", | ||
| "./Navigation/NavigationMenuPanel": "./src/components/Navigation/NavigationMenuPanel.tsx", | ||
| "./Navigation/constants": "./src/components/Navigation/constants/index.ts", | ||
| "./Navigation/types": "./src/components/Navigation/types/index.ts", | ||
| "./Navigation/hooks/*": "./src/components/Navigation/hooks/*.ts", | ||
| "./PageHeader": "./src/components/PageHeader.tsx", | ||
| "./PageSection": "./src/components/PageSection.tsx", | ||
| "./RefreshButton": "./src/components/RefreshButton.tsx", | ||
| "./RefreshOverlay": "./src/components/RefreshOverlay.tsx", | ||
| "./Network/useNetwork": "./src/components/Network/useNetwork.tsx", | ||
| "./Network/NetworkSelector": "./src/components/Network/NetworkSelector.tsx", | ||
| "./Network/config": "./src/components/Network/config/index.ts", | ||
| "./Network/types": "./src/components/Network/types/index.ts", | ||
| "./Section/Section": "./src/components/Section/Section.tsx", | ||
| "./SectionContent": "./src/components/SectionContent.tsx", | ||
| "./Search": "./src/components/Search/index.ts", | ||
| "./SimpleCard": "./src/components/SimpleCard.tsx", | ||
| "./SlideOver": "./src/components/SlideOver.tsx", | ||
| "./Spinner": "./src/components/Spinner.tsx", | ||
| "./StateCard": "./src/components/StateCard.tsx", | ||
| "./SearchInput": "./src/components/SearchInput.tsx", | ||
| "./TextLink/ExternalTextLink": "./src/components/TextLink/ExternalTextLink.tsx", | ||
| "./TextLink/InternalTextLink": "./src/components/TextLink/InternalTextLink.tsx", | ||
| "./TextLink/SmartTextLink": "./src/components/TextLink/SmartTextLink.tsx", | ||
| "./constants/tailwindConstants": "./src/constants/tailwindConstants.ts", | ||
| "./styles": "./src/styles/globals.css", | ||
| "./types/imageType": "./src/types/imageType.ts", | ||
| "./types/tailwindTypes": "./src/types/tailwindTypes.ts", | ||
| "./types/touchTarget": "./src/types/touchTarget.ts", | ||
| "./utils": "./src/utils/index.ts", | ||
| "./config/ui-config": "./src/config/ui-config.ts" |
There was a problem hiding this comment.
This PR fundamentally changes how the package is consumed, but the implementation creates a breaking change for external npm users. The package exports now point exclusively to source .tsx/.ts files instead of compiled .js files. This approach works for the monorepo with transpilePackages, but breaks for external npm consumers who:
- Won't have the src/ directory files needed for the exports
- Can't process .tsx files without specific TypeScript/Next.js configuration
- Won't get pre-compiled .d.ts type definitions (since dts: false in tsup.config.ts)
The PR description claims "npm Compatible: Package still publishes pre-built files for external consumers," but the exports field doesn't reference these pre-built files at all. Consider implementing one of these solutions:
Option A - Conditional Exports (Recommended):
Use Node.js conditional exports to serve source files for local development and dist files for npm consumers.
Option B - Workspace Protocol:
If this package is only meant for use within the monorepo, mark it as "private": true and use workspace: protocol in consuming apps.
Option C - Dual Exports:
Provide separate entry points (e.g., "@filecoin-foundation/ui-filecoin/src/Button" vs "@filecoin-foundation/ui-filecoin/Button") for source vs compiled imports.
|
Parked for now, will revisit later. |
Summary
Enable Just-In-Time (JIT) compilation for
ui-filecoinin the filecoin-site app while maintaining npm publishing compatibility.Changes
transpilePackagessupport toui-filecoinfor JIT compilationui-filecoinfrom source filestsupbuild tool for dual ESM/CJS npm publishing.tsxfiles.npmignoreto include bothsrc/anddist/in npm packagetranspilePackagesconfigurable via parameter increateNextConfigBenefits
ui-filecoincomponents appear instantly in filecoin-site without rebuildTesting
Package Structure
Each component now includes:
src/components/*.tsx(for types & JIT)dist/components/*.js+ sourcemapdist/components/*.cjs+ sourcemap🤖 Generated with Claude Code