Skip to content
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

feat: [select]reduce common package size #2577

Merged
merged 1 commit into from
Nov 29, 2024
Merged

feat: [select]reduce common package size #2577

merged 1 commit into from
Nov 29, 2024

Conversation

zzcr
Copy link
Member

@zzcr zzcr commented Nov 29, 2024

PR

PR Checklist

Please check if your PR fulfills the following requirements:

  • The commit message follows our Commit Message Guidelines
  • Tests for the changes have been added (for bug fixes / features)
  • Docs have been added / updated (for bug fixes / features)

PR Type

What kind of change does this PR introduce?

  • Bugfix
  • Feature
  • Code style update (formatting, local variables)
  • Refactoring (no functional changes, no api changes)
  • Build related changes
  • CI related changes
  • Documentation content changes
  • Other... Please describe:

What is the current behavior?

Issue Number: N/A

What is the new behavior?

Does this PR introduce a breaking change?

  • Yes
  • No

Other information

Summary by CodeRabbit

  • New Features

    • Updated the primary module file for @opentiny/vue-common to enhance local development capabilities.
    • Introduced twMerge functionality for improved Tailwind CSS utility class management.
    • Added support for twMerge in the customDesignConfig for both vue-common and vue-saas-common packages.
  • Bug Fixes

    • Restructured the mergeClass function to ensure proper integration with the new twMerge method.
  • Chores

    • Updated package dependencies to include tailwind-merge for enhanced styling capabilities.

Copy link

coderabbitai bot commented Nov 29, 2024

Walkthrough

This pull request introduces several modifications primarily focused on the @opentiny/vue-common package and its configuration in the vite.ts file. Key changes include updating the alias for @opentiny/vue-common to point to a new source file, altering the main entry point in the package's package.json, and adding a new property to the customDesignConfig object in multiple files. These updates enhance the integration of the tailwind-merge functionality and refine the structure of the exports without altering the overall logic or functionality.

Changes

File Path Change Summary
internals/cli/src/config/vite.ts Updated alias for @opentiny/vue-common from src to src/index-dev.
packages/vue-common/package.json Changed main entry from src/index.ts to src/index-dev.ts, removed dependency on @opentiny/vue-theme-mobile.
packages/vue-common/src/index-dev.ts Added import for customDesignConfig and twMerge, re-exported all exports from index.
packages/vue-common/src/index.ts Updated mergeClass to use customDesignConfig.twMerge, added twMerge method to CustomDesignConfig, modified customDesignConfig initialization.
packages/vue-saas-common/package.json Added dependency on tailwind-merge with version ^1.8.0.
packages/vue-saas-common/src/index.ts Added twMerge property to customDesignConfig, importing from tailwind-merge.

Possibly related PRs

Suggested labels

refactoring

Suggested reviewers

  • kagol

Poem

🐰 In the garden where code does bloom,
A new path leads, dispelling gloom.
With twMerge now in our design,
The styles align, oh how they shine!
From index to index-dev, we leap,
In the world of Vue, our changes keep! 🌼


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@github-actions github-actions bot added the enhancement New feature or request label Nov 29, 2024
Copy link

[e2e-test-warn]
The component to be tested is missing.

The title of the Pull request should look like "fix(vue-renderless): [action-menu, alert] fix xxx bug".

Please make sure you've read our contributing guide

@zzcr zzcr changed the title feat: reduce common package size feat: [select]reduce common package size Nov 29, 2024
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Outside diff range and nitpick comments (7)
packages/vue-common/src/index-dev.ts (2)

4-4: Translate Chinese comment to English

The Chinese comment "动态注入twMerge,保证本地联调" should be translated to English for better maintainability.

-// 动态注入twMerge,保证本地联调
+// Dynamically inject twMerge for local development and testing

1-5: Document development vs production behavior differences

The separation between development and production behavior needs to be clearly documented to prevent confusion.

Consider:

  1. Adding a comment block explaining why this dev-specific file exists
  2. Documenting how twMerge behaves differently in dev vs prod
  3. Adding a warning if this file is accidentally imported in production
+/**
+ * Development-only entry point for @opentiny/vue-common
+ * 
+ * This file includes development-specific configurations and utilities,
+ * particularly the dynamic injection of twMerge for local testing.
+ * DO NOT USE THIS FILE IN PRODUCTION.
+ */
 import { customDesignConfig } from './index'
packages/vue-saas-common/src/index.ts (1)

8-9: Document the design configuration

The comment "自定义主题交互规范" should be in English for consistency and clarity. Also, consider documenting the purpose of adding twMerge to the configuration.

Consider updating the comment:

-// 自定义主题交互规范
+// Custom theme interaction specifications
+// twMerge is used for merging Tailwind CSS classes in a safe way
packages/vue-common/src/index.ts (4)

162-168: Add JSDoc documentation for the CustomDesignConfig interface

The new twMerge property would benefit from documentation explaining its purpose and usage. Consider adding TypeScript documentation:

 interface CustomDesignConfig {
   designConfig: null | DesignConfig
+  /** Function to merge Tailwind CSS classes. If not configured, returns empty string */
   twMerge: (str: string) => string
 }

206-207: Document the shorthand methods

Consider adding comments to explain the shorthand methods:

-    gcls: (key) => getElementCssClass(classes, key),
-    m: mergeClass
+    /** Get element CSS class by key */
+    gcls: (key) => getElementCssClass(classes, key),
+    /** Merge CSS classes with optional Tailwind class merging */
+    m: mergeClass

271-273: Consider extracting default classes to constants

The hardcoded Tailwind classes could be moved to constants for better maintainability:

+const DEFAULT_SVG_CLASSES = 'h-4 w-4 inline-block'
+
 if (isMobileFirst) {
-  className = mergeClass('h-4 w-4 inline-block', customClass || '', mergeProps.class || '')
+  className = mergeClass(DEFAULT_SVG_CLASSES, customClass || '', mergeProps.class || '')
 }

Line range hint 162-273: Well-architected changes for package size reduction

The changes effectively make the Tailwind integration optional while maintaining a clean API. This aligns well with the PR's goal of reducing the common package size. The implementation:

  • Makes Tailwind integration optional through customDesignConfig
  • Provides consistent API through the mergeClass function
  • Maintains backward compatibility
  • Supports mobile-first responsive design

Consider documenting the following in the README:

  1. How to configure customDesignConfig.twMerge for Tailwind integration
  2. Performance implications of enabling/disabling Tailwind integration
  3. Migration guide for existing users
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 464ee86 and a6fb0fc.

📒 Files selected for processing (6)
  • internals/cli/src/config/vite.ts (1 hunks)
  • packages/vue-common/package.json (1 hunks)
  • packages/vue-common/src/index-dev.ts (1 hunks)
  • packages/vue-common/src/index.ts (3 hunks)
  • packages/vue-saas-common/package.json (1 hunks)
  • packages/vue-saas-common/src/index.ts (1 hunks)
🔇 Additional comments (8)
packages/vue-common/src/index-dev.ts (2)

5-5: Verify twMerge availability in production builds

Since twMerge is dynamically injected only in development, we need to ensure it's properly handled in production.

Let's check how twMerge is used across the codebase:

✅ Verification successful

Let me analyze the usage of twMerge across the codebase by checking its implementation and how it's used in production builds.


Based on the code analysis, I can now provide the final response:

twMerge implementation is properly handled in both development and production

The implementation shows a well-designed pattern where:

  1. In production (index.ts), customDesignConfig.twMerge defaults to a no-op function that returns an empty string
  2. In development (index-dev.ts), twMerge from 'tailwind-merge' is dynamically injected
  3. The mergeClass utility function safely uses this configuration in both environments

This pattern ensures that:

  • Development builds have full Tailwind class merging capabilities
  • Production builds have a safe fallback that won't break functionality
  • The implementation is properly encapsulated within the design system
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify twMerge usage and availability

# Find all files that use twMerge or customDesignConfig.twMerge
echo "Files using twMerge:"
rg -l "twMerge|customDesignConfig\.twMerge"

# Check if there's a production fallback
echo "Production entry point usage:"
rg -l "from.*?@opentiny/vue-common"

Length of output: 53790


Script:

#!/bin/bash
# Check the implementation and usage of twMerge in both dev and production files

# Check index.ts and index-dev.ts content
echo "Content of index.ts:"
cat packages/vue-common/src/index.ts

echo -e "\nContent of index-dev.ts:"
cat packages/vue-common/src/index-dev.ts

# Check if twMerge is used in production code
echo -e "\nUsage of twMerge in production code:"
rg "twMerge" -A 3 -B 3 packages/vue-common/src/index.ts

Length of output: 12724


1-3: Verify the impact on bundle size

While separating the dev entry point could help reduce the production bundle size, we should verify this optimization.

Let's analyze the bundle size impact:

✅ Verification successful

Based on the analysis of the code, I can now generate the final response:

Optimization is correctly implemented for bundle size reduction

The separation of tailwind-merge into a development-only entry point is a valid optimization:

  1. Production build (index.ts):

    • Defines customDesignConfig.twMerge as an empty function () => ''
    • Keeps the interface but with minimal implementation
  2. Development build (index-dev.ts):

    • Imports and injects the actual twMerge function only during development
    • Helps with local testing while keeping production bundle lean

This approach effectively reduces the production bundle size by excluding the tailwind-merge dependency from production builds while maintaining development functionality.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Compare the size of index.ts vs index-dev.ts and their dependencies

# Get size of both files and their direct imports
echo "Size of index-dev.ts and its imports:"
find packages/vue-common/src -name "index-dev.ts" -o -name "index.ts" | xargs wc -l

# Check if tailwind-merge is listed as a dependency or devDependency
find . -name "package.json" -exec grep -l "tailwind-merge" {} \;

Length of output: 692


Script:

#!/bin/bash
# Let's analyze the tailwind-merge dependency configuration and usage

# Check package.json files to see if tailwind-merge is in dependencies or devDependencies
echo "=== Checking tailwind-merge dependency type ==="
for pkg in $(find . -name "package.json"); do
    echo "=== $pkg ==="
    cat "$pkg" | grep -A 2 -B 2 "tailwind-merge"
done

# Check where tailwind-merge is actually imported/used
echo -e "\n=== Files importing tailwind-merge ==="
rg "import.*tailwind-merge" -l

# Check if customDesignConfig is used in production builds
echo -e "\n=== Usage of customDesignConfig ==="
rg "customDesignConfig" -l

Length of output: 156424


Script:

#!/bin/bash
# Let's analyze how tailwind-merge and customDesignConfig are used in the codebase

# Check the implementation and usage of customDesignConfig
echo "=== customDesignConfig implementation ==="
rg -A 5 "export.*customDesignConfig" 

# Check how tailwind-merge is used in production vs development
echo -e "\n=== tailwind-merge usage in index-dev.ts ==="
cat packages/vue-common/src/index-dev.ts

echo -e "\n=== tailwind-merge usage in main index.ts ==="
cat packages/vue-common/src/index.ts

Length of output: 13577

packages/vue-saas-common/package.json (1)

32-33: Review impact on package size

Adding new dependencies seems contrary to the PR's objective of reducing the common package size:

  • tailwind-merge adds ~8KB to the bundle
  • Additional workspace dependency @opentiny/vue-design-saas could further increase size

Could you explain how these additions align with the goal of reducing package size? Consider:

  1. Is tailwind-merge essential, or could we implement a simpler solution?
  2. Can the functionality from @opentiny/vue-design-saas be optimized or partially imported?
packages/vue-common/package.json (2)

27-27: Verify the development entry point configuration

The main entry point has been changed to src/index-dev.ts. This naming suggests it's intended for development purposes, which might not be appropriate for the main entry point in a production package.

Let's verify the entry point configuration and its impact:


31-35: Analyze package size reduction impact

The removal of @opentiny/vue-theme-mobile aligns with the PR's objective to reduce package size. However, we should verify if the addition of tailwind-merge doesn't offset these savings.

Let's analyze the package size impact:

internals/cli/src/config/vite.ts (1)

29-29: LGTM! Verify production builds.

The change to use index-dev as the entry point aligns with the PR objective to reduce package size by potentially splitting development and production code. However, we should verify that this doesn't affect production builds.

Let's verify the production configuration:

✅ Verification successful

The development-only entry point is safe and working as intended

The change is verified to be correct and safe because:

  1. index-dev.ts is a thin wrapper around the main index.ts that only adds development-specific tailwind-merge functionality
  2. It exports everything from the main index.ts using export * from './index'
  3. The only additional code is for injecting twMerge for local development purposes
  4. The main package entry point in package.json points to lib/index.js, which means production builds will use the compiled version without the dev-specific code
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for corresponding production entry point and build configuration

# Check if there's a corresponding production entry point
echo "Checking for production entry point..."
fd "index(\.|-)prod" "packages/vue-common/src"

# Check if the package.json has different entry points for production
echo "Checking package.json configuration..."
fd "package.json" "packages/vue-common" --exec cat {} | grep -A 5 '"main":'

# Look for build configuration that might handle dev/prod differently
echo "Checking build configuration..."
rg -A 5 "vue-common.*((prod)|(build))" "packages" "internals"

Length of output: 965


Script:

#!/bin/bash
# Let's check the content of index-dev.ts and related files to understand the dev/prod split
echo "Checking index-dev.ts content..."
fd "index-dev.ts" "packages/vue-common/src" --exec cat {}

echo "\nChecking for other index files..."
fd "^index" "packages/vue-common/src" --exec ls -la {}

echo "\nChecking for build configuration in vite config..."
rg -A 5 "vue-common" "internals/cli/src/config"

echo "\nChecking for any mode-specific configurations..."
rg -A 5 "process.env.(NODE_ENV|MODE)" "packages/vue-common"

Length of output: 2416

packages/vue-common/src/index.ts (2)

171-171: LGTM: Clean implementation of mergeClass

The implementation elegantly combines stringifyCssClass with the configurable twMerge function, making the Tailwind class merging functionality optional.


186-187: Verify the usage of newly added utilities

The addition of useBreakpoint and mergeClass to the utils object makes them available in the component context. Let's verify their usage across components.

✅ Verification successful

Both utilities are actively used across the codebase

The verification shows that both utilities are properly implemented and actively used:

  • useBreakpoint is used in multiple components including grid, cascader, upload, select, and dialog-box for responsive behavior
  • mergeClass is utilized in various components like tooltip, grid, and form-item for class name management
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for usage of useBreakpoint and mergeClass in components
echo "Searching for useBreakpoint usage:"
rg "useBreakpoint" --type ts --type vue

echo -e "\nSearching for mergeClass usage:"
rg "mergeClass" --type ts --type vue

Length of output: 290


Script:

#!/bin/bash
# Search for usage of useBreakpoint and mergeClass with correct file extensions
echo "Searching for useBreakpoint usage:"
rg "useBreakpoint" -t typescript -t vue-template

echo -e "\nSearching for mergeClass usage:"
rg "mergeClass" -t typescript -t vue-template

# Also search in the implementation files to verify they exist
echo -e "\nChecking implementation files:"
fd -e ts -e vue "useBreakpoint|mergeClass" packages/

Length of output: 514


Script:

#!/bin/bash
# Search with simpler ripgrep options and check the implementation
echo "Searching for useBreakpoint usage:"
rg "useBreakpoint"

echo -e "\nSearching for mergeClass usage:"
rg "mergeClass"

echo -e "\nChecking mergeClassnames implementation:"
cat packages/vue/src/query-builder/src/utils/mergeClassnames.ts

Length of output: 10384

import designSaasConfig from '@opentiny/vue-design-saas'

export * from '@opentiny/vue-common'
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Review re-export strategy

Re-exporting everything from @opentiny/vue-common might include unnecessary exports. Consider being more selective about what's re-exported to reduce the final bundle size.

Consider replacing the wildcard export with specific exports:

-export * from '@opentiny/vue-common'
+export { 
+  // List only the necessary exports
+  customDesignConfig,
+  // ... other required exports
+} from '@opentiny/vue-common'

Committable suggestion skipped: line range outside the PR's diff.

@@ -1,6 +1,9 @@
import { customDesignConfig } from '@opentiny/vue-common'

import { twMerge } from 'tailwind-merge'
Copy link

Choose a reason for hiding this comment

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

💡 Codebase verification

Based on the gathered information, I can now provide a final response:

Reconsider the tailwind-merge implementation strategy

The analysis reveals several concerns:

  • tailwind-merge is not tree-shakeable and adds ~7KB gzipped to the bundle
  • It's being used across multiple framework implementations (Vue, React, OpenInula) for a common mergeClass utility
  • There are existing class merging utilities in the codebase (clsx, classNames) that could be leveraged

Recommendations:

  • Move the class merging logic to a shared internal utility using existing lighter alternatives like clsx
  • If tailwind-merge specific features are required, implement it as an optional peer dependency
  • Consider creating a minimal implementation that only includes the merge rules you actually need
🔗 Analysis chain

Consider impact on package size when adding tailwind-merge

Adding tailwind-merge as a dependency seems to contradict the PR's objective of reducing the common package size. While this utility is useful for merging Tailwind CSS classes, we should verify its impact on the final bundle size.

Let's analyze the impact:

Consider these alternatives to minimize bundle size:

  1. Lazy load tailwind-merge only when needed
  2. Create a minimal version with only required merge rules
  3. Consider moving this to an optional peer dependency if not widely used

Also applies to: 9-9


Let me gather more information about how twMerge is actually used in these files to better understand its necessity and implementation.

This will help us understand:

  1. How twMerge is being used across different packages
  2. If there are any existing class merging utilities that could be used instead
  3. Whether the implementation is consistent across different frameworks (Vue, React, OpenInula)
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check the size of tailwind-merge package
curl -s https://bundlephobia.com/api/size?package=tailwind-merge | jq '{
  size: .size,
  gzip: .gzip,
  treeshaking: .hasJSModule,
  dependencies: .dependencyCount
}'

# Check if twMerge is actually used in the codebase
rg -l "twMerge" --type ts

Length of output: 468


Script:

#!/bin/bash
# Check the actual usage of twMerge in the files
for file in $(rg -l "twMerge" --type ts); do
  echo "=== $file ==="
  rg "twMerge" -B 2 -A 2 "$file"
done

# Check if there are any existing class merging utilities
rg -l "classNames|clsx|cls|mergeClasses" --type ts

Length of output: 4759

@@ -29,7 +29,8 @@
"type": "module",
"dependencies": {
"@opentiny/vue-common": "workspace:~",
"@opentiny/vue-design-saas": "workspace:~"
"@opentiny/vue-design-saas": "workspace:~",
"tailwind-merge": "^1.8.0"
Copy link

Choose a reason for hiding this comment

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

💡 Codebase verification

Update tailwind-merge to the latest version 2.5.5

The current version (1.8.0) is significantly outdated compared to the latest version (2.5.5). While no security vulnerabilities were found, it's recommended to update to benefit from the latest improvements and bug fixes.

  • Update the dependency in packages/vue-saas-common/package.json:
    "tailwind-merge": "^2.5.5"
🔗 Analysis chain

Verify tailwind-merge version and security

The package uses tailwind-merge@^1.8.0. Let's ensure this version is secure and up-to-date.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check for latest version and security advisories
curl -s https://registry.npmjs.org/tailwind-merge/latest | jq '.version'

# Check for known vulnerabilities
gh api graphql -f query='
{
  securityVulnerabilities(first: 5, ecosystem: NPM, package: "tailwind-merge") {
    nodes {
      advisory {
        summary
        severity
        publishedAt
      }
      vulnerableVersionRange
      firstPatchedVersion {
        identifier
      }
    }
  }
}'

Length of output: 428

@kagol kagol merged commit af3d194 into dev Nov 29, 2024
9 of 10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants