Amazon AlexaAPLask-sdk

Create APL template using ask-sdk-jsx-for-apl with TypeScript

Since AlexaLive 2020, we can create APL tempalte by using JSX. Let’s try it. Install We need to install […]

広告ここから
広告ここまで

Since AlexaLive 2020, we can create APL tempalte by using JSX.

Let’s try it.

Install

We need to install these require packages.

$ npm install -S ask-sdk-jsx-for-apl react react-dom

And install TypeScript helpers.

$ npm install -D @types/react @types/react-dom

Check and update tsconfig.json

We need to set these parameters into your tsconfig.json

  • compilerOptions.jsx = 'react'
  • compilerOptions.esModuleInterop = true

Here is a example of tsconfig.json

{
    "compilerOptions": {
      "module": "commonjs",
      "target": "es6",
      "noImplicitAny": true,
      "noImplicitReturns": true,
      "noFallthroughCasesInSwitch": true,
      "outDir": "./dist",
      "esModuleInterop": true,
      "jsx": "react",
      "allowJs": false
    },
    "include": [
        "./src/**/*"
    ]
  }

Create APL by React

Then, we can create APL template by using React JSX with TypeScript.

import React from 'react';
import { APL, MainTemplate, Container, Text } from 'ask-sdk-jsx-for-apl';

/**
 * Class component
 */
export class LaunchAplDocument extends React.Component {
    private readonly launchMessage = 'Welcome to my first JSX for APL skill!';
    render() {
        return (
            <APL theme="dark">
                <MainTemplate>
                    <Container
                        alignItems="center"
                        justifyContent="spaceAround">
                        <Text
                            text={this.launchMessage}
                            fontSize="50px"
                            color="rgb(251,184,41)" />
                    </Container>
                </MainTemplate>
            </APL>
        );
    }
}

/**
 * Functional Component
 */
export const LaunchAplDocumentFC: React.FC = () => {
    const launchMessage = 'Welcome to my first JSX for APL skill!';
    return (
        <APL theme="dark">
            <MainTemplate>
                <Container
                    alignItems="center"
                    justifyContent="spaceAround">
                    <Text
                        text={launchMessage}
                        fontSize="50px"
                        color="rgb(251,184,41)" />
                </Container>
            </MainTemplate>
        </APL>
    );
}

And use these component can be added by AplDocument class in your RequestHandler like the example.

import React from 'react'
import { RequestHandler } from 'ask-sdk-core';
import { AplDocument } from 'ask-sdk-jsx-for-apl';
import { LaunchAplDocument } from './LaunchRequest.apl';

export const LaunchRequestHandler:  RequestHandler = {
    async canHandle(handlerInput) {
        return handlerInput.requestEnvelope.request.type === "LaunchRequest"
    },
    async handle(handlerInput) {
        return handlerInput.responseBuilder
            .speak("Hello! It's a nice development. How are you?")
            .reprompt("How are you?")
            .addDirective(
                new AplDocument(
                    <LaunchAplDocument />
                ).getDirective()
            )
            .getResponse()        
    }
}

export default LaunchRequestHandler

Trouble shooting

Error: TS2352: Conversion of type ‘RegExp’ to type ‘LaunchAplDocument’ may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to ‘unknown’ first.

If you don’t using .tsx suffix, you may get the error.

We have to replace your file from .ts to .tsx

Left: LaunchRequest.ts (get Error)
Right: LaunchRequest.tsx (No Error)

Error: TS2686: ‘React’ refers to a UMD global, but the current file is a module. Consider adding an import instead.

If we want to use JSX component, we must import React in the file.

Left: import React (No Error)
Right:nothing (Get Error)

Test your APL Component by Jest

We can test your APL component by using jest.

import React from 'react';
import {
    APL,
    MainTemplate,
    Container,
    Text,
    AplDocument
} from 'ask-sdk-jsx-for-apl'

const LaunchAplDocumentFC: React.FC = () => {
    const launchMessage = 'Welcome to my first JSX for APL skill!';
    return (
        <APL theme="dark">
            <MainTemplate>
                <Container
                    alignItems="center"
                    justifyContent="spaceAround">
                    <Text
                        text={launchMessage}
                        fontSize="50px"
                        color="rgb(251,184,41)" />
                </Container>
            </MainTemplate>
        </APL>
    );
}

describe('AplDocument', () => {
    const directive = new AplDocument(<LaunchAplDocumentFC />).getDirective()
    it('should get RenderDocument Directive', () => {
        expect(directive).toEqual({
            "document": {
              "import": [],
              "mainTemplate": {
                "items": [
                  {
                    "alignItems": "center",
                    "items": [
                      {
                        "color": "rgb(251,184,41)",
                        "fontSize": "50px",
                        "items": [],
                        "text": "Welcome to my first JSX for APL skill!",
                        "type": "Text"
                      }
                    ],
                    "justifyContent": "spaceAround",
                    "type": "Container"
                  }
                ],
                "parameters": []
              },
              "theme": "dark",
              "type": "APL",
              "version": "1.3"
            },
            "type": "Alexa.Presentation.APL.RenderDocument"
          })
    })
})

Use snapshot testing to check the component update

Jest provides a snapshot testing. We can detect the return value changes by the test.

We have to execute the test before update the component.

import React from 'react';
import {
    APL,
    MainTemplate,
    Container,
    Text,
    AplDocument
} from 'ask-sdk-jsx-for-apl'

const LaunchAplDocumentFC: React.FC = () => {
    const launchMessage = 'Welcome to my first JSX for APL skill!';
    return (
        <APL theme="dark">
            <MainTemplate>
                <Container
                    alignItems="center"
                    justifyContent="spaceAround">
                    <Text
                        text={launchMessage}
                        fontSize="50px"
                        color="rgb(251,184,41)" />
                </Container>
            </MainTemplate>
        </APL>
    );
}

describe('AplDocument', () => {
    const directive = new AplDocument(<LaunchAplDocumentFC />).getDirective()
    it('should match snapshot', () => {
        expect(directive).toMatchSnapshot()
    })
})

Then, if you update the Text color from rgb(251,184,41) to rgb(255,184,41), jest will detect the change.


    Snapshot name: `AplDocument should match snapshot 1`

    - Snapshot  - 1
    + Received  + 1

    @@ -14,11 +14,11 @@
            "items": Array [
              Object {
                "alignItems": "center",
                "items": Array [
                  Object {
    -               "color": "rgb(251,184,41)",
    +               "color": "rgb(255,184,41)",
                    "fontSize": "50px",
                    "items": Array [],
                    "text": "Welcome to my first JSX for APL skill!",
                    "type": "Text",
                  },

      29 |     const directive = new AplDocument(<LaunchAplDocumentFC />).getDirective()
      30 |     it('should match snapshot', () => {
    > 31 |         expect(directive).toMatchSnapshot()
         |                           ^
      32 |     })
      33 |     it('should get RenderDocument Directive', () => {

If the change is expected, we can update the snapshot by using -u option to execute the jest test. If not, we need to fix it.

ブックマークや限定記事(予定)など

WP Kyotoサポーター募集中

WordPressやフロントエンドアプリのホスティング、Algolia・AWSなどのサービス利用料を支援する「WP Kyotoサポーター」を募集しています。
月額または年額の有料プランを契約すると、ブックマーク機能などのサポーター限定機能がご利用いただけます。

14日間のトライアルも用意しておりますので、「このサイトよく見るな」という方はぜひご検討ください。

広告ここから
広告ここまで

Related Category posts