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: enable live code inclusion for consuming applications #2642

Merged
merged 19 commits into from
Oct 24, 2023

Conversation

gavinbarron
Copy link
Member

@gavinbarron gavinbarron commented Jul 28, 2023

Closes #1457
Closes #2656

PR Type

  • Feature

Design considerations

Currently bundlers like rollup, webpack, and parcel are unable to analyze the mgt packages and determine which parts of the these dependencies are live code to be included. This is often called "Tree Shaking", dead code removal. To enable this behavior our libraries must be side effect free, or refactor the side effects in such a way that they can be avoided by developers.

The current implementation of our @microsoft/mgt-components relies on the side effects of using the @customElement decorator to register the custom elements with the browser as part of the import of any dependency from the library at the top level, i.e. import { xyz } from '@microsoft/mgt-components';. This results in all of the custom elements being registered as soon as one top level import exists. Completely removing this side effect would be a breaking change and one that we want to avoid until we're ready for a v4 release.
Given these constraints it is necessary to:

  • Eliminate the usage of a decorator to provide custom element registraton
    • Open question, should we create a custom eslint rule to scan for usages of the @customElement decorator and report these as errors?
  • Provide a function for registering a given custom element which calls the registration functions for each of the custom elements that the component directly relies upon. Using a registration function is consistent with the way in which @fluentui/web-component approaches component registration.
  • Ensure that importing from the top level of the @microsoft/mgt-components library still has a side effect of registering all custom elements.
  • Provide a simple second level import point that is free of side effects for @microsoft/mgt-components, e.g. import { MgtPersonCard } from '@microsoft/mgt-components/exports;
  • Refactor the code generation of the @microsoft/mgt-react library such that it avoids the top level side effect in @microsoft/mgt-components and allows correct tree shaking by bundlers.
  • Ensure that any use of the disambiguation tooling still results in registration of correctly disambiguated tags with the browser

Description of the changes

Marks most libraries as being side effect free in package.json to allow bundlers to determine which code should be included.
Marks the root index file in mgt-components as having side effects.
Removes the use of the @customElement decorator as this is a side effect generating pattern that adds code which executes at import time to register the custom elements.
Creates a new register{{ComponentClass}}Component() function per component to provide an imperative function based component mechanism for registering a custom element, including any nested custom element usages. Having a registration function that uses a naming convention is essential to allow the React shims to be generated based on metadata generated via custom-elements-mainifest/analyzer.
Refactors React shim generation to be file per shim component and a barrel file, this ensures that bunders can include dependencies via React usage on a per-file basis and eliminates ambiguity as to which dependencies are required for a given React component.
Refactors a number of functions/classes/interfaces into separate files to reduce the number of circular dependencies down to two chains (mgt-person => mgt-person-card => mgt-person & mgt-person => mgt-person-card => mgt-organization => mgt-person)
Adds a plugin for custom-elements-mainifest/analyzer to correctly determine out custom element definitions at build time for use in generation of the react package and metadata used in storybook for docs pages, this is necessary as our components now use a custom function to perform the registration of the custom element which the custom-elements-mainifest/analyzer is unable to detect and understand natively.
Refactored the import of MgtPersonCard in MgtPerson to become a dynamic import.

PR checklist

  • Project builds (yarn build) and changes have been tested in at least two supported browsers (Edge + non-Chromium based browser)
  • All public APIs (classes, methods, etc) have been documented following the jsdoc syntax
  • Stories have been added and existing stories have been tested
  • Added appropriate documentation. Docs PR:
  • License header has been added to all new source files (yarn setLicense)
  • Contains NO breaking changes

Other information

Still to do, try to sort out dynamic imports in mgt-person so that we only pull in the mgt-person-card when needed.

BEGIN_COMMIT_OVERRIDE
feat!: enable live code inclusion for consuming applications (#2642)

Packages are marked as side effect free or have the files that include side effects listed in package.json. This allows bundlers to discard code not in the direct dependency tree of an import.
Adds functions for registering components
Moved to generating a single file per react wrpper component and a barrel file
Update tests to use registerComponent calls
fixing render problem when given and surname are null on personType objects
move mgt-components to module type es2020 for dynamic imports
refactored to only lazy load the person-card code when opening the flyout
update list of components registered by registerMgtComponents
move sample app to use lazy + Suspense to chunk up component usage
adding documentation for tree shaking support

BREAKING CHANGE: applications importing @microsoft/mgt-react but not using the wrapper components will not have components automatically registered in the browser. This leads to a breaking change when these applications emit raw web component markup rather than using the wrapper components.
END_COMMIT_OVERRIDE

@gavinbarron gavinbarron requested a review from a team as a code owner July 28, 2023 23:15
@gavinbarron gavinbarron marked this pull request as draft July 28, 2023 23:15
@microsoft-github-policy-service
Copy link
Contributor

Thank you for creating a Pull Request @gavinbarron.

This is a checklist for the PR reviewer(s) to complete before approving and merging this PR:

  • I have verified a documentation PR has been linked and is approved (or not applicable)
  • I have ran this PR locally and have tested the fix/feature
  • I have verified that stories have been added to storybook (or not applicable)
  • I have tested existing stories in storybook to verify no regression has occured
  • I have tested the solution in at least two browsers (Edge + 1 non-Chromium based browser)

@github-actions
Copy link

The updated storybook is available here

package.json Show resolved Hide resolved
@gavinbarron gavinbarron marked this pull request as ready for review August 25, 2023 18:43
@github-actions
Copy link

github-actions bot commented Oct 5, 2023

📖 The updated storybook is available here

@github-actions
Copy link

github-actions bot commented Oct 5, 2023

📖 The updated storybook is available here

@github-actions
Copy link

github-actions bot commented Oct 5, 2023

📖 The updated storybook is available here

@github-actions
Copy link

github-actions bot commented Oct 5, 2023

🚀 New react-contoso sample application deployed here

@github-actions
Copy link

github-actions bot commented Oct 5, 2023

📖 The updated storybook is available here

@github-actions
Copy link

github-actions bot commented Oct 9, 2023

🚀 New react-contoso sample application deployed here

@github-actions
Copy link

github-actions bot commented Oct 9, 2023

📖 The updated storybook is available here

@github-actions
Copy link

🚀 New react-contoso sample application deployed here

@github-actions
Copy link

📖 The updated storybook is available here

@github-actions
Copy link

🚀 New react-contoso sample application deployed here

@github-actions
Copy link

📖 The updated storybook is available here

musale
musale previously approved these changes Oct 12, 2023
Copy link
Contributor

@musale musale left a comment

Choose a reason for hiding this comment

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

This looks good to me too. For the docs, we can add them on the READMEs and portal on a separate work item.

@gavinbarron gavinbarron dismissed stale reviews from musale and sebastienlevert via d405e0b October 23, 2023 14:19
@github-actions
Copy link

🚀 New react-contoso sample application deployed here

@github-actions
Copy link

📖 The updated storybook is available here

musale
musale previously approved these changes Oct 23, 2023
…unction and setting up a side effect free path for importing the provider class
@github-actions
Copy link

🚀 New react-contoso sample application deployed here

@github-actions
Copy link

📖 The updated storybook is available here

@github-actions
Copy link

Code Coverage

Package Line Rate Branch Rate Complexity Health
mgt-components.src.components 26% 0% 0
mgt-components.src.components.mgt-contact 37% 9% 0
mgt-components.src.components.mgt-file 15% 0% 0
mgt-components.src.components.mgt-file-list 15% 0% 0
mgt-components.src.components.mgt-file-list.mgt-file-upload 6% 0% 0
mgt-components.src.components.mgt-messages 30% 0% 0
mgt-components.src.components.mgt-organization 17% 0% 0
mgt-components.src.components.mgt-person 61% 55% 0
mgt-components.src.components.mgt-person-card 43% 26% 0
mgt-components.src.components.mgt-profile 7% 0% 0
mgt-components.src.components.mgt-theme-toggle 100% 100% 0
mgt-components.src.components.sub-components.mgt-flyout 29% 11% 0
mgt-components.src.components.sub-components.mgt-spinner 100% 100% 0
mgt-components.src.graph 19% 7% 0
mgt-components.src.styles 82% 37% 0
mgt-components.src.utils 45% 13% 0
mgt-element.src 39% 0% 0
mgt-element.src.components 30% 0% 0
mgt-element.src.mock 51% 42% 0
mgt-element.src.providers 39% 19% 0
mgt-element.src.utils 43% 26% 0
Summary 31% (1236 / 4035) 16% (375 / 2389) 0

@gavinbarron gavinbarron enabled auto-merge (squash) October 23, 2023 21:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Archived in project
3 participants