Skip to content

feat: add excludeNames option #13

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

Merged
merged 4 commits into from
Nov 18, 2024
Merged

feat: add excludeNames option #13

merged 4 commits into from
Nov 18, 2024

Conversation

FliPPeDround
Copy link
Member

@FliPPeDround FliPPeDround commented Nov 11, 2024

Description 描述

  1. 移植unplugin-vue-components feat: add excludeNames option unplugin/unplugin-vue-components#788 excludeNames选项
  2. 添加UniUIResolver exclude 选项
    解决导入非uni-ui组件库组件错误 feat: add uni-ku-root plugin create-uni#72
  3. 修改test测试文件文件目录位置,使其能正常工作

Summary by CodeRabbit

Release Notes

  • New Features

    • Introduced the ability to exclude specific component names and directories from imports using the new excludeNames option.
    • Added new components <Book /> and <uni-test> to the index page.
  • Bug Fixes

    • Improved filtering logic to ensure excluded components are not processed, enhancing overall component resolution.
  • Tests

    • Expanded test coverage for exclusion functionality in component resolution.
    • Established a comprehensive suite of unit tests for transformation functionality related to Vue components.
  • Chores

    • Updated configuration for the Vite build tool to support new exclusion options.
    • Modified test files to align with the latest testing framework conventions.

Copy link

coderabbitai bot commented Nov 11, 2024

Walkthrough

The changes in this pull request introduce a new interface, UniUIResolverOptions, allowing for the specification of component names to exclude from imports. The UniUIResolver function is updated to accept these options, enhancing component resolution logic. Additionally, a new utility function isExclude is added to filter out excluded component names, and related updates are made across several files to support this functionality. Tests are also added to cover the new exclusion features, while some existing tests are updated for consistency.

Changes

File Change Summary
packages/core/src/_resolvers/uni-ui.ts Added UniUIResolverOptions interface and modified UniUIResolver function to accept options.
packages/core/src/context.ts Introduced isExclude utility function and updated updateComponentNameMap method to filter excluded names.
packages/core/src/options.ts Changed defaultOptions to use excludeNames instead of exclude.
packages/core/src/types.ts Added excludeNames property to Options interface and deprecated certain properties in ImportInfoLegacy.
packages/core/src/utils.ts Added isExclude function to check for name exclusions based on a filter pattern.
packages/core/test/dts.test.ts Updated import statements to use node: prefix and changed test function calls from test to it.
packages/core/test/search.test.ts Added tests for exclusion functionality in the Context class.
packages/core/test/transform.test.ts Introduced new tests for Vue component transformation logic.
packages/core/test/utils.test.ts Updated test function calls from test to it.
playground/src/pages/index/index.vue Added new components <Book /> and <uni-test> to the template section.
playground/vite.config.ts Updated UniUIResolver plugin configuration to include excludes and added excludeNames in the Components plugin.
test/transform.test.ts Deleted file containing tests for Vue 3 transformation functionality.

Possibly related PRs

  • feat: support uv-ui resolver #12: The changes in this PR introduce a new resolver for the uv-ui component library, which is relevant to the main PR's updates to the UniUIResolver function and its handling of component resolution options, including exclusions.

Suggested labels

size/M

Poem

🐰 In the code where rabbits play,
Exclusions help us find our way.
With UniUI now refined,
Components filtered, well-defined.
Hopping through the lines we cheer,
For clearer paths, we hold so dear! 🌟


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 61b1ef5 and c08253d.

📒 Files selected for processing (2)
  • packages/core/src/_resolvers/uni-ui.ts (1 hunks)
  • playground/vite.config.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • packages/core/src/_resolvers/uni-ui.ts
  • playground/vite.config.ts

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.

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: 5

🧹 Outside diff range and nitpick comments (14)
packages/core/test/utils.test.ts (1)

13-21: Consider adding test cases for excludeNames functionality.

While the BDD syntax updates look good, given that this PR introduces the excludeNames option, it would be beneficial to add test cases that verify the path resolution behavior when exclusion patterns are present.

Consider adding test cases like:

it('should handle excluded patterns', () => {
  const options: Partial<ResolvedOptions> = {
    ...baseOptions,
    excludeNames: ['a-*']  // exclude components starting with 'a-'
  }
  const inComponentFilePath = '/src/components/a/b.vue'
  expect(getNameFromFilePath(inComponentFilePath, options as ResolvedOptions)).toBeNull()
})
packages/core/src/_resolvers/uni-ui.ts (1)

5-10: Consider enhancing documentation and aligning property names.

The interface is well-designed, but two suggestions:

  1. The property name excludes differs from the PR objective's excludeNames. Consider aligning these for consistency.
  2. The documentation could be enhanced with examples of valid patterns.

Consider updating the documentation:

 /**
  * RegExp or string to match component names that will NOT be imported
+ * @example
+ * - string: 'UniTest'
+ * - RegExp: /^UniTest/
+ * - Array: ['UniTest', /^UniCustom/]
  */
playground/src/pages/index/index.vue (1)

Line range hint 13-52: Consider restructuring the playground implementation

The current implementation mixes demonstration and testing purposes, which could lead to maintenance issues. Consider the following improvements:

  1. Separate the playground into distinct sections:
    • Move test cases to dedicated test files
    • Keep the playground focused on demonstrating valid use cases
  2. Make section titles dynamic to avoid manual updates
  3. Consider adding comments to explain the purpose of each section

This would make the playground more maintainable and its purpose clearer.

packages/core/test/search.test.ts (3)

47-58: Enhance test assertion with more specific verification.

While the test correctly verifies that ComponentA is excluded, it could be more robust by also asserting that other expected components are still present. This ensures the exclusion doesn't accidentally remove too much.

Consider enhancing the test like this:

-    expect(cleanup(ctx.componentNameMap).map(i => i.as)).not.toEqual(expect.arrayContaining(['ComponentA']))
+    const componentNames = cleanup(ctx.componentNameMap).map(i => i.as)
+    expect(componentNames).not.toContain('ComponentA')
+    expect(componentNames).toEqual(
+      expect.arrayContaining(['ComponentB', 'ComponentC']) // add your expected components
+    )

60-71: Enhance directory exclusion test with more specific assertions.

Similar to the previous test, this could be more robust by verifying both the exclusion and inclusion of expected components.

Consider enhancing the test like this:

-    expect(cleanup(ctx.componentNameMap).map(i => i.as)).not.toEqual(expect.arrayContaining(['Book']))
+    const componentNames = cleanup(ctx.componentNameMap).map(i => i.as)
+    // Verify excluded components
+    expect(componentNames).not.toContain('Book')
+    // Verify components from other directories are still present
+    expect(componentNames).toEqual(
+      expect.arrayContaining(['ComponentA', 'ComponentB']) // add your expected components
+    )

46-82: Add test coverage for edge cases.

Consider adding the following test cases to improve coverage:

  1. Empty exclusion arrays
  2. Invalid exclusion patterns
  3. Wildcard patterns in excludeNames

Here's an example of additional test cases:

it('should handle empty excludeNames array', () => {
  const ctx = new Context({
    dirs: ['src/components'],
    excludeNames: [],
  })
  ctx.setRoot(root)
  ctx.searchGlob()
  
  // Verify no components are excluded
  const componentNames = cleanup(ctx.componentNameMap).map(i => i.as)
  expect(componentNames).toEqual(
    expect.arrayContaining(['Book', 'ComponentA', 'ComponentB'])
  )
})

it('should handle wildcard patterns in excludeNames', () => {
  const ctx = new Context({
    dirs: ['src/components'],
    excludeNames: ['Component*'], // exclude all components starting with "Component"
  })
  ctx.setRoot(root)
  ctx.searchGlob()
  
  const componentNames = cleanup(ctx.componentNameMap).map(i => i.as)
  expect(componentNames).not.toContain('ComponentA')
  expect(componentNames).not.toContain('ComponentB')
  expect(componentNames).toContain('Book') // should not be excluded
})
packages/core/src/options.ts (1)

Line range hint 23-58: Consider handling excludeNames in resolveOptions function.

The resolveOptions function processes and normalizes various options but doesn't handle the new excludeNames option. Consider adding normalization logic to ensure consistent handling of exclude patterns.

Here's a suggested implementation:

 export function resolveOptions(options: Options, root: string): ResolvedOptions {
   const resolved = Object.assign({}, defaultOptions, options) as ResolvedOptions
   resolved.resolvers = normalizeResolvers(resolved.resolvers)
   resolved.extensions = toArray(resolved.extensions)
+  
+  // Normalize excludeNames to array if provided
+  if (resolved.excludeNames)
+    resolved.excludeNames = toArray(resolved.excludeNames)

   if (resolved.globs) {
     resolved.globs = toArray(resolved.globs).map((glob: string) => slash(resolve(root, glob)))
packages/core/src/types.ts (1)

65-69: Enhance documentation with examples and clarification.

The addition of excludeNames is well-typed and consistent with existing filter properties. Consider enhancing the documentation with:

  1. An example pattern to demonstrate usage
  2. Clarification on how this differs from the exclude property which filters files
   /**
    * RegExp or string to match component names that will NOT be imported
+   * @example ['Button', /^Icon/] // excludes 'Button' and components starting with 'Icon'
+   * @remarks Different from `exclude` which filters files - this filters component names
    */
   excludeNames?: FilterPattern
packages/core/test/transform.test.ts (3)

73-73: Document the magic number in the code.

The comment 512 /* NEED_PATCH */ should include a more detailed explanation of what this patch flag represents and why it's needed.


40-40: Enhance test assertions beyond snapshots.

While snapshot testing is useful, consider adding specific assertions to verify:

  • The presence of imported components/directives
  • The correct transformation of component/directive names
  • The proper handling of transformation options

Also applies to: 62-62, 85-85


1-162: Consider restructuring tests to focus on new functionality.

While the test file provides good coverage for basic transformations, it should be reorganized to:

  1. Add a dedicated describe block for excludeNames functionality
  2. Include both positive and negative test cases for component exclusion
  3. Test edge cases and error conditions
  4. Add explicit assertions alongside snapshot testing

This would better align with the PR's main objective of adding the excludeNames option.

packages/core/test/dts.test.ts (1)

20-20: LGTM! Consider enhancing test descriptions.

The change from test to it improves readability and follows BDD-style conventions. While the change is good, consider making the test descriptions even more descriptive by following the "it should..." pattern. For example:

  • it('getDeclaration')it('should generate correct type declarations')
  • it('components only')it('should handle component-only declarations')

This would make the test intentions clearer and documentation more maintainable.

Also applies to: 34-34, 50-50, 86-86, 98-98, 111-111, 124-124, 145-145, 166-166

packages/core/src/utils.ts (1)

230-247: Consider performance and type safety improvements.

The implementation is functionally correct but could be enhanced:

  1. Use Array.some() for better performance as it will stop iterating once a match is found
  2. Add type narrowing for array items to ensure type safety

Here's a suggested improvement:

 export function isExclude(name: string, exclude?: FilterPattern): boolean {
   if (!exclude)
     return false

   if (typeof exclude === 'string')
     return name === exclude

   if (exclude instanceof RegExp)
     return !!name.match(exclude)

-  if (Array.isArray(exclude)) {
-    for (const item of exclude) {
-      if (name === item || name.match(item))
-        return true
-    }
-  }
-  return false
+  if (Array.isArray(exclude)) {
+    return exclude.some((item) => {
+      if (typeof item === 'string')
+        return name === item
+      if (item instanceof RegExp)
+        return !!name.match(item)
+      return false
+    })
+  }
+  return false
 }
packages/core/src/context.ts (1)

179-182: Consider enhancing error handling and debugging.

The exclusion logic is well-placed and follows good practices. Consider these improvements:

  1. Add more context to the debug message (e.g., reason for exclusion)
  2. Consider logging a warning when excluding components to help users troubleshoot configuration issues
 if (isExclude(name, this.options.excludeNames)) {
-  debug.components('exclude', name)
+  debug.components('exclude', `Component "${name}" matches exclusion pattern`)
+  if (this.options.debug) {
+    console.warn(`[vite-plugin-uni-components] Component "${name}" was excluded by pattern`)
+  }
   return
 }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 7d51689 and 61b1ef5.

⛔ Files ignored due to path filters (6)
  • packages/core/test/__snapshots__/dts.test.ts.snap is excluded by !**/*.snap
  • packages/core/test/__snapshots__/search.test.ts.snap is excluded by !**/*.snap
  • packages/core/test/__snapshots__/stringifyComponentImport.test.ts.snap is excluded by !**/*.snap
  • packages/core/test/__snapshots__/transform.test.ts.snap is excluded by !**/*.snap
  • test/__snapshots__/search.test.ts.snap is excluded by !**/*.snap
  • test/__snapshots__/transform.test.ts.snap is excluded by !**/*.snap
📒 Files selected for processing (12)
  • packages/core/src/_resolvers/uni-ui.ts (1 hunks)
  • packages/core/src/context.ts (2 hunks)
  • packages/core/src/options.ts (1 hunks)
  • packages/core/src/types.ts (1 hunks)
  • packages/core/src/utils.ts (2 hunks)
  • packages/core/test/dts.test.ts (10 hunks)
  • packages/core/test/search.test.ts (1 hunks)
  • packages/core/test/transform.test.ts (1 hunks)
  • packages/core/test/utils.test.ts (2 hunks)
  • playground/src/pages/index/index.vue (2 hunks)
  • playground/vite.config.ts (1 hunks)
  • test/transform.test.ts (0 hunks)
💤 Files with no reviewable changes (1)
  • test/transform.test.ts
🔇 Additional comments (13)
packages/core/test/utils.test.ts (2)

1-1: LGTM! Good move to BDD-style test syntax.

The change from test to it follows BDD conventions and improves test readability.


Line range hint 1-24: Verify test coverage for excludeNames functionality.

Let's check if the exclusion functionality is tested in other test files.

playground/vite.config.ts (2)

23-25: LGTM! UniUIResolver configuration looks correct.

The excludes option is properly configured to prevent importing the 'UniTest' component through the UniUIResolver, which helps avoid incorrect imports from non-uni-ui libraries.


29-29: Verify the impact of global component exclusion.

The excludeNames option is correctly configured to exclude the 'Book' component globally across all resolvers. However, let's verify that this component isn't required by other parts of the application.

✅ Verification successful

Let me check the actual Book component implementation and its dependencies to make a more informed decision.


Excluding the Book component is safe

The Book component is a simple demonstration component that only renders a heading. It's only used in one place (playground/src/pages/index/index.vue) and doesn't contain any critical functionality. The exclusion won't impact the application's functionality.

  • The component is minimally implemented in playground/src/components/book/index.vue
  • Single usage found in playground/src/pages/index/index.vue
  • No other dependencies or complex interactions detected
  • The exclusion is already being tested in the core package's test suite
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for any usage of the 'Book' component in the codebase
# to ensure excluding it won't break existing functionality

# Search for Book component usage in template files
echo "Checking for Book component usage in Vue templates..."
rg -g '*.vue' -i '<book'

# Search for Book component imports
echo "Checking for Book component imports..."
rg -g '*.{vue,js,ts}' -i 'import.*book'

Length of output: 420


Script:

#!/bin/bash
# Check the Book component implementation
echo "Checking Book component implementation..."
cat playground/src/components/book/index.vue

# Check if Book component is imported anywhere else
echo "Checking for additional Book component references..."
rg -g '*.{vue,js,ts}' -C 3 'Book'

Length of output: 3086

packages/core/src/_resolvers/uni-ui.ts (2)

1-1: LGTM! Appropriate imports for the new functionality.

The imports are well-organized and properly leverage existing tooling:

  • FilterPattern from @rollup/pluginutils is a standard type for exclusion patterns
  • isExclude utility is correctly imported from the utils module

Also applies to: 3-3


Line range hint 12-29: Implementation looks good! Verify impact on existing usages.

The resolver implementation is clean and maintains backward compatibility while adding the new exclusion feature. The order of checks is logical, and early returns improve readability.

Let's verify existing usages to ensure the changes don't break current implementations:

✅ Verification successful

Changes are safe and properly used in the codebase

The verification shows that:

  • The resolver is correctly used in the playground with the new options parameter, specifically excluding 'UniTest'
  • There is an actual usage of a uni-ui component (UniCalendar) demonstrating the resolver works
  • The implementation maintains backward compatibility as seen in the working playground setup

The changes are well-integrated and don't introduce any breaking changes to existing usages.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for existing resolver usages that might be affected
# by the new options parameter

# Search for UniUIResolver instantiations
echo "Checking UniUIResolver usages:"
rg "UniUIResolver\(" -A 2

# Search for potential uni-ui component imports that might be affected
echo -e "\nChecking uni-ui component imports:"
rg "from ['|\"]@dcloudio/uni-ui/lib/" -A 1

Length of output: 587


Script:

#!/bin/bash
# Let's verify the implementation more thoroughly

# Check if there are any test files for the resolver
echo "Checking for resolver tests:"
fd "uni-ui.test" --type f

# Check the content of the test file if found
echo -e "\nChecking test content:"
fd "uni-ui.test" --type f --exec cat {}

# Look for any usage patterns in the playground
echo -e "\nChecking playground usage patterns:"
fd "vite.config.ts" --type f --exec grep -A 5 "UniUIResolver" {}

# Check if there are any components using Uni prefix in playground
echo -e "\nChecking Uni components usage in playground:"
rg "Uni[A-Z]\w+" playground/

Length of output: 1215

packages/core/src/options.ts (1)

6-6: LGTM! Verify the implementation of excludeNames.

The type definition change correctly adds excludeNames to the omitted properties. This aligns with the PR objective of adding the excludeNames functionality.

Let's verify the implementation:

✅ Verification successful

Implementation of excludeNames is complete and properly tested

The verification shows that:

  • excludeNames is properly typed as FilterPattern in types.ts
  • The implementation is handled by isExclude function in utils.ts which supports both string and pattern matching
  • It's correctly used in context.ts for component filtering
  • Test coverage exists in search.test.ts verifying the exclusion behavior
  • No need for resolveOptions handling since excludeNames is used directly as a filter pattern
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the implementation of excludeNames option
# Expected: Find the type definition and usage of excludeNames

# Test 1: Find the type definition
echo "Searching for excludeNames type definition..."
rg -l "excludeNames.*:.*FilterPattern" 

# Test 2: Find the usage of excludeNames in the codebase
echo "Searching for excludeNames usage..."
rg "excludeNames" --type ts

Length of output: 801


Script:

#!/bin/bash
# Let's verify the implementation details

# Check the isExclude function implementation
echo "Checking isExclude implementation..."
rg -A 5 "function isExclude" --type ts

# Check the test implementation to understand the behavior
echo "Checking test implementation..."
rg -A 10 "should excludeNames" packages/core/test/search.test.ts

# Check if excludeNames is handled in resolveOptions
echo "Checking resolveOptions handling..."
ast-grep --pattern 'function resolveOptions($_) {
  $$$
}'

Length of output: 1030

packages/core/src/types.ts (1)

65-69: Verify implementation of excludeNames filtering.

Let's ensure the property is properly implemented in the resolver logic.

✅ Verification successful

Let me check the actual implementation details in those files to verify the proper usage of excludeNames.


Let me check one more thing to verify the isExclude function implementation since it's used for the actual filtering.


excludeNames property is properly implemented and tested

The verification shows that:

  • The excludeNames filtering is correctly implemented in context.ts using the isExclude utility
  • The isExclude function in utils.ts properly handles all cases (string, RegExp, and array patterns)
  • The functionality is covered by unit tests in search.test.ts
  • The property is properly typed in the options interface
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the implementation of excludeNames filtering

# Test 1: Check for the filtering implementation
echo "Checking for excludeNames filtering implementation..."
rg -l "excludeNames" --type ts

# Test 2: Look for resolver logic using the excludeNames
echo "Checking resolver implementation..."
ast-grep --pattern 'function $_($$_) {
  $$$
  excludeNames
  $$$
}'

Length of output: 444


Script:

#!/bin/bash
# Check the actual implementation and usage of excludeNames
echo "Checking core implementation files..."
rg "excludeNames" packages/core/src/context.ts -B 2 -A 2

echo "\nChecking options handling..."
rg "excludeNames" packages/core/src/options.ts -B 2 -A 2

echo "\nChecking test coverage..."
rg "excludeNames" packages/core/test/search.test.ts -B 2 -A 2

Length of output: 1086


Script:

#!/bin/bash
# Check the isExclude implementation
rg "function isExclude" -A 10

Length of output: 601

packages/core/test/dts.test.ts (1)

1-2: LGTM! Good practice using the node: prefix.

Using the node: prefix for built-in modules is a recommended practice as it:

  • Makes it explicit that these are Node.js built-in modules
  • Prevents potential conflicts with similarly named third-party modules
  • Improves module resolution performance
packages/core/src/utils.ts (2)

9-9: LGTM! Appropriate type import for exclusion patterns.

The FilterPattern type from '@rollup/pluginutils' is the standard choice for handling exclusion patterns in Vite/Rollup plugins.


230-247: Verify implementation against source project.

Since this feature is ported from unplugin-vue-components, let's verify the implementation matches the source.

packages/core/src/context.ts (2)

8-8: LGTM: Import statement updated correctly.

The addition of isExclude utility import aligns with the new exclusion functionality.


179-182: Verify integration with HMR and component resolution.

The exclusion logic needs to work correctly with Hot Module Replacement and component resolution features.

✅ Verification successful

Let me fix the regex patterns and gather more information about HMR and component resolution.


Based on the results, I can now generate a final response as we have sufficient information about the component resolution and HMR implementation.

The exclusion logic is safely integrated with component resolution and HMR

The code analysis shows that:

  • The exclusion logic is properly integrated within the component resolution flow through findComponent() method, which respects excluded paths
  • The HMR implementation through onUpdate() works at a higher level and is not directly impacted by component exclusions
  • The component name mapping (_componentNameMap) is properly maintained and cleared when needed
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the integration of exclusion logic with HMR and resolution features

# Test 1: Check if HMR code handles excluded components
echo "Checking HMR handling..."
rg -A 10 "onUpdate.*{" 

# Test 2: Check component resolution code
echo "Checking component resolution..."
rg -A 10 "findComponent.*{" 

# Test 3: Check for any direct references to componentNameMap that might need updating
echo "Checking componentNameMap usage..."
rg "_componentNameMap" 

Length of output: 1007


Script:

#!/bin/bash
# Description: Verify the integration of exclusion logic with HMR and resolution features

# Test 1: Check if HMR code handles excluded components
echo "Checking HMR handling..."
rg "onUpdate.*\{" -A 10

# Test 2: Check component resolution code
echo "Checking component resolution..."
rg "findComponent.*\{" -A 10

# Test 3: Let's also check for any HMR-related imports and usage
echo "Checking HMR imports and usage..."
rg "HMR|hot|reload" -A 3

# Test 4: Let's check the context file more thoroughly for component resolution
echo "Checking context.ts for component resolution..."
rg "resolve.*Component.*\{|get.*Component.*\{" packages/core/src/context.ts -A 10

Length of output: 9836

@@ -19,6 +19,7 @@ const tree = ref({
<ComponentD />
<h3>Recursive Components</h3>
<recursive :data="tree" />
<Book />
Copy link

Choose a reason for hiding this comment

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

💡 Codebase verification

⚠️ Potential issue

Remove or update Book component usage as it's excluded in configuration

The verification confirms that the Book component is explicitly excluded via excludeNames: ['Book'] in vite.config.ts. Using this component in the template will cause runtime errors since it won't be registered. Either:

  • Remove the <Book /> component from the template, or
  • Remove 'Book' from the excludeNames configuration if the component is needed
🔗 Analysis chain

Potential runtime error: Book component is excluded but used

According to the configuration mentioned in the AI summary, the Book component is excluded via excludeNames in vite.config.ts. Using an excluded component in the template could lead to runtime errors.

Additionally, the section title "Basic (4)" should be updated as it now contains 6 components.

Let's verify the component exclusion configuration:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the Book component exclusion configuration
# Expected: Find the excludeNames configuration in vite.config.ts

rg -l 'excludeNames.*Book' 

Length of output: 88


Script:

#!/bin/bash
# Let's check the actual configuration in vite.config.ts
rg -A 5 'excludeNames.*Book' playground/vite.config.ts

# Also check if Book component is actually defined and imported
rg -l 'import.*Book' playground/src/pages/index/

Length of output: 179

@@ -34,6 +35,7 @@ const tree = ref({
start-date="2019-3-2"
end-date="2019-5-20"
/>
<uni-test>test</uni-test>
Copy link

Choose a reason for hiding this comment

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

💡 Codebase verification

⚠️ Potential issue

Remove or reconfigure uni-test component usage

The verification confirms that UniTest component is explicitly excluded in the vite.config.ts configuration:

UniUIResolver({
  excludes: 'UniTest',
})

This will prevent the component from being auto-imported, leading to runtime errors. Either:

  • Remove the uni-test component usage from the template
  • Remove 'UniTest' from the excludes configuration if the component is needed
  • Import the component manually if it's required despite being excluded

Additionally, update the "Uni UI (2)" section title to reflect the actual number of components.

🔗 Analysis chain

Potential runtime error: uni-test component is excluded but used

According to the configuration mentioned in the AI summary, the uni-test component is excluded via the UniUIResolver's exclude option. Using an excluded component in the template could lead to runtime errors.

Additionally:

  1. The section title "Uni UI (2)" should be updated as it now contains 3 components
  2. If this is a test component, consider moving it to a dedicated test file instead of the main playground

Let's verify the component exclusion configuration:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the uni-test component exclusion configuration
# Expected: Find the exclude configuration in UniUIResolver

rg -l 'exclude.*UniTest'

Length of output: 52


Script:

#!/bin/bash
# Let's check the actual exclude configuration in vite.config.ts
cat playground/vite.config.ts

Length of output: 893

Comment on lines +73 to +82
it('should excludeNames', () => {
const ctx = new Context({
dirs: ['src/components'],
excludeNames: ['Book'],
})
ctx.setRoot(root)
ctx.searchGlob()

expect(cleanup(ctx.componentNameMap).map(i => i.as)).not.toEqual(expect.arrayContaining(['Book']))
})
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Enhance excludeNames test coverage.

The test could be more comprehensive by:

  1. Testing multiple excluded names
  2. Verifying case sensitivity behavior
  3. Adding more specific assertions

Consider enhancing the test like this:

-  it('should excludeNames', () => {
+  it('should handle excludeNames with multiple patterns and case sensitivity', () => {
     const ctx = new Context({
       dirs: ['src/components'],
-      excludeNames: ['Book'],
+      excludeNames: ['Book', 'ComponentA', 'component-b'],
     })
     ctx.setRoot(root)
     ctx.searchGlob()

-    expect(cleanup(ctx.componentNameMap).map(i => i.as)).not.toEqual(expect.arrayContaining(['Book']))
+    const componentNames = cleanup(ctx.componentNameMap).map(i => i.as)
+    
+    // Verify excluded components
+    expect(componentNames).not.toContain('Book')
+    expect(componentNames).not.toContain('ComponentA')
+    expect(componentNames).not.toContain('component-b')
+    
+    // Verify case sensitivity (assuming case-sensitive matching)
+    expect(componentNames).toContain('ComponentB')
+    
+    // Verify other components are still present
+    expect(componentNames).toEqual(
+      expect.arrayContaining(['ComponentC']) // add your expected components
+    )
   })

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

Comment on lines +5 to +14
const resolver: ComponentResolver[] = [
{
type: 'component',
resolve: name => ({ from: `test/component/${name}` }),
},
{
type: 'directive',
resolve: name => ({ from: `test/directive/${name}` }),
},
]
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add test cases for excludeNames functionality.

Given that this PR introduces the excludeNames option, the resolver configuration should include test cases that verify the exclusion functionality. Consider adding test cases that:

  1. Verify components are correctly excluded when matched by excludeNames
  2. Test edge cases like partial matches and case sensitivity

Comment on lines +143 to +150
const _component_el_infinite_scroll = _resolveComponent("el-infinite-scroll")
const _directive_el_infinite_scroll = _resolveDirective("el-infinite-scroll")

return _withDirectives(
(_openBlock(),
_createBlock(_component_test_comp, null, null, 512 /* NEED_PATCH */)),
[[_directive_loading, 123]]
)
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix inconsistent component names in Vue 3 test.

There's a mismatch between the resolved and used component/directive names:

  1. el-infinite-scroll is resolved but never used
  2. test-comp is used but never resolved
  3. loading directive is used but el-infinite-scroll was resolved

This affects the validity of the test case.

Apply this fix:

  const render = (_ctx, _cache) => {
    const _component_el_infinite_scroll = _resolveComponent("el-infinite-scroll")
    const _directive_el_infinite_scroll = _resolveDirective("el-infinite-scroll")

    return _withDirectives(
      (_openBlock(),
-     _createBlock(_component_test_comp, null, null, 512 /* NEED_PATCH */)),
-     [[_directive_loading, 123]]
+     _createBlock(_component_el_infinite_scroll, null, null, 512 /* NEED_PATCH */)),
+     [[_directive_el_infinite_scroll, 123]]
    )
  }
📝 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 _component_el_infinite_scroll = _resolveComponent("el-infinite-scroll")
const _directive_el_infinite_scroll = _resolveDirective("el-infinite-scroll")
return _withDirectives(
(_openBlock(),
_createBlock(_component_test_comp, null, null, 512 /* NEED_PATCH */)),
[[_directive_loading, 123]]
)
const _component_el_infinite_scroll = _resolveComponent("el-infinite-scroll")
const _directive_el_infinite_scroll = _resolveDirective("el-infinite-scroll")
return _withDirectives(
(_openBlock(),
_createBlock(_component_el_infinite_scroll, null, null, 512 /* NEED_PATCH */)),
[[_directive_el_infinite_scroll, 123]]
)

@ModyQyW
Copy link
Member

ModyQyW commented Nov 15, 2024

LGTM, @nei1ee @KeJunMao @skiyee cc?

如果没有进一步反馈,我可能会在两天内合并发布,谢谢🙏

@ModyQyW ModyQyW merged commit 235ae7c into uni-helper:main Nov 18, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants