8000 Various improvements for writing ESM components by philippjfr · Pull Request #7462 · holoviz/panel · GitHub
[go: up one dir, main page]

Skip to content

Conversation

@philippjfr
Copy link
Member

This PR provides a number of fixes and improvements for ESM components that I encountered as I was building a library with many components. This includes:

  • Ensure bundle path is correctly resolved on superclasses: This allows compiling a single bundle for an entire package of different ESM components
  • Refactor ESM child resolution: Makes it easier to modify the creation of child models (e.g. to allow lazily creating the models)
  • Allow defining constants on ESM model: Allows providing a _constants dict on a component to modify the behavior of a component without having to define (public) parameters
  • Allow providing URL to _stylesheets: Useful for loading external CSS resources
  • Load @emotion/styled for Material UI components: Required for rendering certain Material UI components
  • Allow initializing NamedListPanel title dict as parameter: Required for implementing ESM components implementing the NamedListPanel interfaces.

@codecov
Copy link
codecov bot commented Nov 5, 2024

Codecov Report

Attention: Patch coverage is 71.92982% with 32 lines in your changes missing coverage. Please review.

Project coverage is 82.36%. Comparing base (c06f779) to head (3a9fc8b).
Report is 5 commits behind head on main.

Files with missing lines Patch % Lines
panel/command/compile.py 7.14% 13 Missing ⚠️
panel/io/compile.py 66.66% 12 Missing ⚠️
panel/custom.py 84.09% 7 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #7462      +/-   ##
==========================================
+ Coverage   82.30%   82.36%   +0.06%     
==========================================
  Files         338      338              
  Lines       50819    50893      +74     
==========================================
+ Hits        41825    41918      +93     
+ Misses       8994     8975      -19     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@griffinmilsap
Copy link

@philippjfr

ESM Components are AWESOME! I've been thrilled for this capability for a while now!!

While you're in here making ESM improvements, I noticed a few panel compile issues that we could address in this PR too:

  1. panel compile appears to not be actually compatible with "dotted module names" as indicated in the documentation. I believe the issue comes down to this line in compile.py where dotted modules are treated as file extensions by os.path.splitext. I don't really know a good way to separate filenames from dotted module names as the last submodule looks like an extension to os.path.splitext. It may be that another flag is necessary to explicitly inform the command that we're compiling a dotted module name. Easiest thing to do for now would be to adjust docs to inform users that panel compile only takes filenames for now.

  2. Copying dependencies into the temporary build directory can result in files that have a <file>..js filename instead of <file>.js which breaks the build. I believe the issue is in these lines of panel/io/compile.py

Comments added pointing out issues

    for component in components:
        name = component.__name__
        esm_path = component._esm_path(compiled=False)
        if esm_path:
            ext = esm_path.suffix # ISSUE: this returns `.js` for a standard esm js file
        else:
            ext = 'jsx' if issubclass(component, ReactComponent) else 'js' # ISSUE: this seems to assume ext won't have a dot in the suffix
        code, component_deps = extract_dependencies(component)
        # Detect default export in component code and handle import accordingly
        if _EXPORT_DEFAULT_RE.search(code):
            index += f'import {name} from "./{name}"\n'
        else:
            index += f'import * as {name} from "./{name}"\n'

        with open(path / f'{name}.{ext}', 'w') as component_file: # ISSUE: when ext is '.js', the output file is `<name>..js` which breaks build
            component_file.write(code)

I think the fix is just to adjust as such:

    for component in components:
        name = component.__name__
        esm_path = component._esm_path(compiled=False)
        if esm_path:
            ext = esm_path.suffix
        else:
            ext = '.jsx' if issubclass(component, ReactComponent) else '.js'
        code, component_deps = extract_dependencies(component)
        # Detect default export in component code and handle import accordingly
        if _EXPORT_DEFAULT_RE.search(code):
            index += f'import {name} from "./{name}"\n'
        else:
            index += f'import * as {name} from "./{name}"\n'

        with open(path / f'{name}{ext}', 'w') as component_file:
            component_file.write(code)

@philippjfr
Copy link
Member Author

Thanks, @griffinmilsap. I believe 2. was already fixed in #7446 and I'm about to push up fixes for 1.

@philippjfr philippjfr added this to the v1.5.4 milestone Nov 6, 2024
@philippjfr philippjfr enabled auto-merge (squash) November 6, 2024 16:41
@philippjfr philippjfr disabled auto-merge November 8, 2024 11:17
@philippjfr philippjfr merged commit 773936d into main Nov 8, 2024
17 of 18 checks passed
@philippjfr philippjfr deleted the esm_improvements branch November 8, 2024 11:18
@github-actions
Copy link
github-actions bot commented Sep 9, 2025

This pull request has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Sep 9, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

0