OfficeDev/teams-toolkit

TTK VSC template "React with Fluent UI" bundling error results in runtime error when using Adaptive Card Templating

Closed this issue · 4 comments

Describe the bug
When using Adaptive Card templating, either using the @microsoft/adaptivecards-tools or adaptivecards-templating package, the generated bundle contains a runtime error blocking loading. If you remove the templating references, the bundling works. The same code that worked a few months ago is no longer working.

The exact same code that's used to implement the templating works server-side in a bot, thus I believe this is rooted in some bundling aspect in the project template that didn't exist before as I can't find any differences in the dependency package versions from the same project used a few months ago.

Error:

To Reproduce
Steps to reproduce the behavior:

  1. Create a new TTK VSC project using the Tab > React with Fluent UI template

  2. Build, deploy & test... observe the project works

  3. Use either of the @microsoft/adaptivecards-tools or adaptivecards-templating packages using the following code as an example. Uncomment the single line after EITHER OPTION 1 or OPTION 2 to see the error:

    Sample code demonstrating the error
    import PICKABLE_VIDEOS from "./MOCK_VIDEOS";
    
    import { AdaptiveCards } from "@microsoft/adaptivecards-tools";
    import * as AdaptiveCardsTemplating from "adaptivecards-templating";
    import rawSelectorCardTemplate from "./selectorCard.json";
    
    export default function Player() {
    
      /* omitted for brevity */
    
      const onChangeVideoAdaptiveCardClick = (event: React.MouseEvent<HTMLButtonElement>): void => {
        let cardJson = {};
    
        /*
           Both of the following code options SHOULD work, and has in the past, but something related
            to Adaptive Card templating is causing runtime errors.
        */
    
        /* NOT WORKING - OPTION 1 - using @microsoft/adaptivecards-tools */
        // cardJson = AdaptiveCards.declare(rawSelectorCardTemplate).render({ videoOptions: PICKABLE_VIDEOS });
    
        /* NOT WORKING - OPTION 2 - using adaptivecards-templating (preferred as of August 2024 > https://vtns.io/Xtbrvu) */
        // cardJson = new AdaptiveCardsTemplating.Template(rawSelectorCardTemplate).expand({ $root: { videoOptions: PICKABLE_VIDEOS } });
    
        /*
          WORKAROUND - Adaptive Card templating for a collection is not working...
                        The following code is a workaround to manually add the video choice
                        options to the AC instead of using AC templating.
        */
        // rawSelectorCardTemplate.body.forEach(acContainer => {
        //   acContainer.items.forEach((acItem: any) => {
        //     if (acItem.type === 'Input.ChoiceSet') {
        //       acItem.choices = PICKABLE_VIDEOS.map(video => {
        //         return {
        //           title: video.title,
        //           value: video.id
        //         };
        //       });
        //     }
        //   });
        // });
        // cardJson = rawSelectorCardTemplate;
    
        const dialogInfo: AdaptiveCardDialogInfo = {
          title: 'YouTube Video Selector',
          size: { width: DialogDimension.Large, height: DialogDimension.Large },
          card: JSON.stringify(cardJson)
        };
    
        const submitHandler: microsoftTeams.dialog.DialogSubmitHandler = (dialogResult: any) => {
          if (dialogResult?.result) {
            const result = JSON.parse(dialogResult.result);
            if (result.choiceVideoId) {
              setVideoId(result.choiceVideoId);
            } else if (result.textVideoId) {
              setVideoId(result.textVideoId);
            }
          }
        };
    
        microsoftTeams.dialog.adaptiveCard.open(dialogInfo, submitHandler);
      };
    
      return (
        <Button onClick={onChangeVideoAdaptiveCardClick}>Change selected video</Button>
      );
    }
    Sample Adaptive Card
    {
      "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
      "type": "AdaptiveCard",
      "version": "1.5",
      "body": [
        {
          "type": "Container",
          "items": [
            {
              "type": "TextBlock",
              "text": "YouTube Video Selector",
              "weight": "Bolder",
              "size": "ExtraLarge"
            }
          ]
        },
        {
          "type": "Container",
          "items": [
            {
              "type": "TextBlock",
              "text": "Enter the ID of a YouTube video to show in the task module player, or select from a list of videos:",
              "wrap": true
            },
            {
              "type": "Input.Text",
              "id": "textVideoId",
              "value": "",
              "placeholder": "enter video ID",
              "label": "Enter a YouTube video ID:"
            },
            {
              "type": "Input.ChoiceSet",
              "id": "choiceVideoId",
              "placeholder": "select video",
              "label": "Select an existing YouTube video:",
              "choices": [
                {
                  "$data": "${videoOptions}",
                  "title": "${title}",
                  "value": "${id}"
                }
              ]
            }
          ]
        }
      ],
      "actions": [
        {
          "type": "Action.Submit",
          "title": "Update selected video"
        }
      ]
    }
  4. Build, deploy & test... observe the error in tab UX

    $ is not a function
    TypeError: $ is not a function
        at 668.../internals/export (https://localhost:53000/static/js/bundle.js:125701:7)
        at o (https://localhost:53000/static/js/bundle.js:38523:19)
        at https://localhost:53000/static/js/bundle.js:38525:20
        at 781.../modules/es.global-this (https://localhost:53000/static/js/bundle.js:130395:7)
        at o (https://localhost:53000/static/js/bundle.js:38523:19)
        at https://localhost:53000/static/js/bundle.js:38525:20
        at Object.<anonymous> (https://localhost:53000/static/js/bundle.js:120773:11)
        at Object.<anonymous> (https://localhost:53000/static/js/bundle.js:120789:12)
        at 522.@babel/runtime/helpers/interopRequireDefault (https://localhost:53000/static/js/bundle.js:120790:10)
        at o (https://localhost:53000/static/js/bundle.js:38523:19)
    
  5. Comment either of the breaking OPTION 1 or OPTION 2 codes & uncomment the block after the WORKAROUND that manually edits the Adaptive Card's JSON

  6. Observe it works.

Expected behavior
No error... templating should work

Screenshots
n/a

VS Code Extension Information (please complete the following information):

  • OS: MacOS v14 & v15
  • Version: v5.8.2

CLI Information (please complete the following information):

  • OS: MacOS v14 & v15
  • Version: v3.0.2

Additional context
The same packages, code, and Adaptive Card used in a bot works as expected:

export class TeamsBot extends TeamsActivityHandler {
  // ... omitted for brevity
  protected async handleTeamsTaskModuleFetch(context: TurnContext, request: TaskModuleRequest): Promise<TaskModuleResponse> {
    if (request.data?.videoId) {
      // ... omitted for brevity
    } else {
      let cardJson = {};

      /* OPTION 1 - using @microsoft/adaptivecards-tools */
      // cardJson = AdaptiveCards.declare(rawSelectorCardTemplate).render( { videoOptions: PICKABLE_VIDEOS } );

      /* OPTION 2 - using adaptivecards-templating (preferred as of August 2024 > https://vtns.io/Xtbrvu) */
      cardJson = new AdaptiveCardsTemplating.Template(rawSelectorCardTemplate).expand( { $root: { videoOptions: PICKABLE_VIDEOS } } );

      const response: TaskModuleResponse = {
        task: {
          type: 'continue',
          value: {
            title: 'YouTube Player',
            card: CardFactory.adaptiveCard(cardJson)
          }
        }
      }
      return Promise.resolve(response);
  }
}

I reproduced the issue and tried removing all teams related dependencies and code but the still meet the error.
I think this should be an upstream issue as there is a similar issue:
microsoft/AdaptiveCards#9035

@hund030 Interesting... I think it might be related to bundling the adaptive cards package rather than a Teams-specific thing.

I noticed in one of those comments in the issue you referenced, that another person was also using the Create React App utility.

So I had the same issue recently as I described here microsoft/AdaptiveCards#9035 (comment) and the workaround seems to be to downgrade the adaptive-expressions to version 4.22.3.

It seemingly broke support with adaptivecard-templating 5 months ago.

@eriolchan Why was this closed as completed? Was this fixed?