Creación de una aplicación web estática con una API sin servidor

Obtenga información sobre cómo ejecutar localmente y, a continuación, implementar una aplicación web estática con una API sin servidor en Azure. En este tutorial se usa la versión preliminar del último modelo de programación node.js de Azure Functions. Dado que en este artículo se usa una versión preliminar de Azure Functions, se implementa como una aplicación independiente de la aplicación web estática.

Obtenga información sobre cómo:

  • Ejecución local de una aplicación web estática (SWA) con una aplicación de función de Azure
  • Solicitudes de front-end de proxy local a la API de back-end local mediante la CLI de SWA.
  • Implemente y ejecute el mismo código de forma remota.

El proxy entre el front-end y backend-endis proporcionado por la CLI de la aplicación web estática proporciona:

  • La dirección URL de React, /api/todo, no especifica el número de puerto o servidor para la API. Las solicitudes que usan esta dirección URL se procesan correctamente de forma local porque la CLI de SWA administra el proxy automáticamente.
  • Un emulador de autenticación local al acceder a /.auth/login/<provider>.
  • Administración y autorización de rutas.

Autenticación en este ejemplo

La autenticación de este ejemplo se proporciona para los usuarios front-end del servicio Azure Static Web Apps:

  • Inicio de sesión y cierre de sesión
  • Contenido público y privado

Código fuente de este ejemplo

El código fuente de este ejemplo está diseñado para aprender a compilar e implementar una aplicación web estática con una API sin servidor. El código no está pensado para producción.

Encontrará varios lugares en el código que no siguen los procedimientos de seguridad recomendados. Por ejemplo, el código usa console.log para escribir en la consola del explorador.

Al pasar a un entorno de producción, debe revisar y quitar cualquier código, lo que infringe los procedimientos recomendados de seguridad para su organización.

1. Preparación del entorno de desarrollo

Crea las cuentas siguientes:

Instale lo siguiente en el equipo de desarrollo local:

2. Bifurcar el repositorio de ejemplo en GitHub

Debe tener su propia bifurcación del repositorio de ejemplo para completar la implementación desde GitHub. Durante el proceso de bifurcación, solo tiene que copiar la main rama.

Bifurcar el repositorio de ejemplo: https://github.com/Azure-Samples/azure-typescript-e2e-apps.

3. Clonar el repositorio de ejemplo bifurcada

  1. En un terminal de Bash, clone el repositorio bifurcada en el equipo local. No clone el repositorio de ejemplo original. Una dirección URL de ejemplo es https://github.com/YOUR-ACCOUNT-NAME/azure-typescript-e2e-apps

    git clone YOUR-FORKED-REPO-URL
    
  2. Instale las dependencias de la aplicación front-end local:

    cd app-react-vite && npm install 
    
  3. Instale las dependencias de la aplicación back-end local:

    cd ../apiV4-inmemory && npm install && cd ..
    

4. Opcional, compilación y ejecución de la aplicación local

El repositorio de ejemplo tiene varias versiones de las aplicaciones front-end y back-end. En los pasos siguientes se usa la versión de React 18 (Vite) del front-end y azure Function v4 con la versión Node.js del back-end con las rutas de API /status y /todo .

  1. Desde la raíz de la aplicación de ejemplo, use la CLI de SWA con el ./swa-cli.config.json archivo para compilar las aplicaciones front-end y back-end:

    swa build
    

    Si se producen errores, que pueden producirse en función de la versión de distintos paquetes y de su entorno, corríjalos antes de continuar. Es importante saber que el proyecto se compila correctamente localmente antes de pasar a la implementación en Azure Static Web Apps.

  2. Desde la raíz de la aplicación de ejemplo, use la CLI de SWA para iniciar las aplicaciones con un proxy.

    swa start
    
  3. Cuando vea las siguientes líneas en el terminal de Bash, el proyecto se inició correctamente.

    [swa] Serving static content:
    [swa]   /workspaces/azure-typescript-e2e-apps/app-react-vite/dist
    [swa] 
    [swa] Serving API:
    [swa]   /workspaces/azure-typescript-e2e-apps/api-inmemory
    [swa] 
    [swa] Azure Static Web Apps emulator started at http://0.0.0.0:4280. Press CTRL+C to exit.
    
  4. Abra un explorador web en la dirección URL proxy, http://localhost:4280. Debería ver la página siguiente:

    Screenshot of local React app prior to authentication.

  5. Puede iniciar sesión con la autenticación proporcionada por la CLI de SWA. El proceso simula la autenticación en aplicaciones web estáticas de Azure basadas en la nube. El código de front-end usa el /.auth/me punto de conexión para obtener la identidad del usuario. Escriba cualquier nombre de usuario falso y no cambie el resto de los campos.

    Screenshot of local React app's mock authentication form.

  6. Una vez autenticado un usuario, el front-end muestra información privada , como las variables de entorno de la API.

    Screenshot of local React app with authentication complete.

    El código fuente de la aplicación Azure Function v4 para esta API es:

    import { app, HttpRequest, HttpResponseInit, InvocationContext } from "@azure/functions";
    
    import { name, version } from '../../package.json';
    function isObject(v) {
        return '[object Object]' === Object.prototype.toString.call(v);
    };
    function sortJson(o){
        if (Array.isArray(o)) {
            return o.sort().map(sortJson);
        } else if (isObject(o)) {
            return Object
                .keys(o)
            .sort()
                .reduce(function(a, k) {
                    a[k] = sortJson(o[k]);
    
                    return a;
                }, {});
        }
        return o;
    }
    
    export async function status(request: HttpRequest, context: InvocationContext): Promise<HttpResponseInit> {
        context.log(`Http function processed request for url "${request.url}"`);
    
        const sortedEnv = sortJson(process.env);
    
        return { jsonBody: {
            name,
            version,
            env: sortedEnv,
            requestHeaders: request.headers 
        }};
    };
    
    app.http('status', {
        route: "status",
        methods: ['GET'],
        authLevel: 'anonymous',
        handler: status
    });
    
  7. Expanda las secciones pública y privada para ver que se muestra el contenido de la API.

5. Creación de una nueva aplicación de Azure Functions

La sección anterior de ejecutar la aplicación web estática con la API era opcional. Las secciones restantes del artículo son necesarias para implementar la aplicación y la API en la nube de Azure.

Para usar la versión preliminar del entorno de ejecución de Azure Functions v4, debe crear una nueva aplicación de Azure Functions. La aplicación web estática también debe volver a compilarse e implementarse para usar el URI de la aplicación de Azure Functions en las solicitudes fetch a la API en lugar de usar una API proxy y administrada.

  1. En un explorador web, abra Azure Portal para crear una nueva aplicación de Azure Functions: Creación de una nueva aplicación

  2. Use la siguiente información para crear function App::

    Tab:Setting Value
    Conceptos básicos: Suscripción Seleccione la suscripción que quiere usar.
    Conceptos básicos: Grupo de recursos Cree un nuevo grupo de recursos, como first-static-web-app-with-api. El nombre no se usa en la dirección URL pública de la aplicación. Los grupos de recursos le ayudan a agrupar y administrar recursos de Azure relacionados.
    Aspectos básicos: Detalles de la instancia: Nombre de la aplicación de funciones Escriba un nombre único global, como swa-api con 3 caracteres aleatorios agregados al final, como swa-api-123.
    Conceptos básicos: Detalles de la instancia: Código o contenedor Seleccione Code.
    Conceptos básicos: Detalles de la instancia: Pila en tiempo de ejecución Seleccione Node.js.
    Conceptos básicos: Detalles de la instancia: Pila en tiempo de ejecución Seleccione 18LTS.
    Conceptos básicos: Sistema operativo Seleccione Linux.
    Aspectos básicos: Hospedaje Seleccione Consumption.
    Almacenamiento: cuenta de almacenamiento No cambie esto. Se crea una nueva cuenta de Azure Storage para ayudar con eventos de función.
    Redes No cambies nada.
    Supervisión: Application Ideas: Habilitar application Ideas Seleccione Yes. No cambie el nombre predeterminado proporcionado.
    Implementación: Acciones de GitHub Configuración: implementación continua Seleccione Enable.
    Implementación: cuenta de GitHub Seleccione la cuenta de GitHub.
    Implementación: Organización Seleccione la cuenta de GitHub que usó al bifurcar el repositorio de ejemplo.
    Implementación: repositorio Seleccione el nombre del repositorio bifurcada, azure-typescript-e2e-apps.
    Implementación: Rama Seleccione main.
    Etiquetas No cambies nada.
    Revisar y crear Seleccione Create.

    El paso agrega un archivo de flujo de trabajo yaml de GitHub al repositorio bifurcada.

  3. Cuando se cree el recurso, seleccione el Go to resource botón .

  4. Seleccione Configuración -> Configuración y agregue una configuración para el entorno de ejecución de Azure Function Node.js v4 con el nombre AzureWebJobsFeatureFlags y el valor EnableWorkerIndexing.

  5. Seleccione Guardar para guardar la configuración.

  6. En un terminal de Bash, use Git para extraer el nuevo archivo de flujo de trabajo yaml desde el repositorio bifurcada de GitHub al equipo local.

    git pull origin main
    
  7. En Visual Studio Code, abra el nuevo archivo de flujo de trabajo de yaml ubicado en ./.github/workflows/.

  8. El archivo de flujo de trabajo predeterminado proporcionado para usted asume que el código fuente de la función está en la raíz del repositorio y es la única aplicación del repositorio, pero eso no es el caso con este ejemplo. Para corregirlo, edite el archivo. Las líneas que se van a editar se resaltan en el siguiente bloque yaml y se explican a continuación:

    # Docs for the Azure Web Apps Deploy action: https://github.com/azure/functions-action
    # More GitHub Actions for Azure: https://github.com/Azure/actions
    
    # Deploy Azure Functions Node.js v4 runtime
    # with api-inmemory subdir
    
    name: Azure Function App - api-inmemory
    
    on:
      push:
        branches:
          - main
        paths:
          - 'api-inmemory/**'
      workflow_dispatch:
    
    env:
      AZURE_FUNCTIONAPP_PACKAGE_PATH: 'api-inmemory' # set this to the path to your web app project, defaults to the repository root
      NODE_VERSION: '18.x' # Azure Functions v4 runtime requires 18
      VERBOSE: true # For debugging
    
    jobs:
      build-and-deploy:
        runs-on: ubuntu-latest
        steps:
          - name: 'Checkout GitHub Action'
            uses: actions/checkout@v2
    
          - name: Setup Node ${{ env.NODE_VERSION }} Environment
            uses: actions/setup-node@v1
            with:
              node-version: ${{ env.NODE_VERSION }}
    
          - name: 'Resolve Project Dependencies Using Npm'
            shell: bash
            run: |
              pushd './${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }}'
              npm install
              npm run build --if-present
              npm run test --if-present
              popd
          - name: 'Upload artifact for deployment job' # For debugging
            uses: actions/upload-artifact@v3
            with:
              name: azure-function-v4-app
              path: |
                ${{env.AZURE_FUNCTIONAPP_PACKAGE_PATH}}
                !${{env.AZURE_FUNCTIONAPP_PACKAGE_PATH}}/node_modules
                !${{env.AZURE_FUNCTIONAPP_PACKAGE_PATH}}/dist          
          - name: 'Run Azure Functions Action'
            uses: Azure/functions-action@v1
            id: fa
            with:
              app-name: 'swa-api' # change this to your Azure Function app name
              slot-name: 'Production'
              package: ${{env.AZURE_FUNCTIONAPP_PACKAGE_PATH}}
              publish-profile: ${{ secrets.AZUREAPPSERVICE_PUBLISHPROFILE_123 }}
              scm-do-build-during-deployment: false
              enable-oryx-build: false
    
    Cambio de propiedad Propósito
    name Acorte el nombre para que pueda encontrarlo fácilmente en la lista de acciones de GitHub de la bifurcación.
    paths Agregue la sección rutas de acceso para limitar la implementación para que solo se ejecute cuando cambie el código de la API de Azure Functions. Al editar el archivo de flujo de trabajo, puede desencadenar la implementación manualmente.
    AZURE_FUNCTIONAPP_PACKAGE_PATH Cuando se usa una subdirectión para el código fuente, debe ser esa ruta de acceso y nombre del subdirectorio.
    VERBOSE Esta configuración es útil para depurar el proceso de compilación e implementación.
    paso denominado Upload artifact for deployment job Este paso crea un artefacto descargable. Esto resulta útil al depurar exactamente qué archivos se implementan en la función de Azure.

    Upload artifact for deployment job es opcional. Se usa para comprender y depurar qué archivos se implementan en Azure Functions o para usar esos archivos en un entorno independiente.

  9. Guarde el archivo y agregue, confirme y vuelva a insertarlo en GitHub con Git:

    git add .
    git commit -m "fix the workflow for a subdir"
    git push origin main
    
  10. Desde un explorador, vuelva a ejecutar el flujo de trabajo en GitHub en el área de acciones de la bifurcación.

    Screenshot of GitHub forked repository, showing how to rerun a GitHub action.

  11. Espere a que la acción se complete correctamente antes de continuar.

  12. En un explorador web, use el punto de conexión de API externo de la aplicación de funciones para comprobar que la aplicación se implementó correctamente.

    https://YOUR-FUNCTION-APP-NAME.azurewebsites.net/api/todo
    

    El resultado JSON devuelto para los datos en memoria es:

    {
        "1": "Say hello"
    }
    
  13. Anote la dirección URL de la función. Lo necesita en la sección siguiente.

  14. Sabe que la aplicación de funciones de Azure funciona en la nube. Ahora debe crear la aplicación web estática en la nube para usar la API.

6. Creación de una nueva aplicación web estática de Azure

Este proceso de creación implementa el mismo repositorio de ejemplo de GitHub bifurcada en Azure. Configure la implementación para que use solo la aplicación front-end.

  1. Abra Azure Portal e inicie sesión con su cuenta de Azure: Azure Portal.

  2. Use la siguiente información para completar los pasos de creación:

    Aviso Configuración
    Suscripción Seleccione la suscripción que quiere usar.
    Grupo de recursos Seleccione Create new y escriba un nuevo para el grupo de recursos, como first-static-web-app. El nombre no se usa en la dirección URL pública de la aplicación. Los grupos de recursos le ayudan a agrupar los recursos usados para un solo proyecto.
    Tipo de plan de hospedaje Seleccione Free
    Detalles de almacenamiento provisional y Azure Functions No cambie el valor predeterminado. No va a implementar function API dentro de la aplicación web estática.
    Detalles de implementación: origen Seleccione GitHub
    Detalles de implementación: GitHub Inicie sesión en GitHub si es necesario.
    Detalles de implementación: organización Seleccione la cuenta de GitHub.
    Detalles de implementación: repositorio Seleccione el repositorio bifurcada denominado azure-typescript-e2e-apps.
    Detalles de implementación: rama Seleccione la main rama.
    Detalles de compilación: presenta la compilación Seleccione Custom.
    Detalles de compilación: ubicación de la aplicación Escriba /app-react-vite.
    Detalles de compilación: ubicación de api Dejar en blanco
    Detalles de compilación: ubicación de salida Escriba la ubicación del directorio de salida del front-end, dist.
  3. Seleccione Revisar y crear y, luego, Crear.

  4. Cuando se cree el recurso, seleccione el Go to resource botón .

  5. En la página Información general , anote la dirección URL de la aplicación web estática. Necesita eso en la sección siguiente al establecer la configuración de CORS de la función de Azure.

  6. El proceso de creación crea un archivo de flujo de trabajo yaml de GitHub en el repositorio de GitHub bifurcada. Extraiga ese cambio con el siguiente comando:

    git pull origin main
    
  7. La acción de GitHub que se encuentra en ./.github/workflows/azure-static-web-apps-*.yml es responsable de compilar e implementar la aplicación front-end. Edite el archivo para agregar una variable de entorno para la dirección URL de la API de back-end basada en la nube. Las líneas que se van a editar se resaltan en el siguiente bloque yaml y se explican debajo del bloque yaml.

    name: Azure Static Web Apps CI/CD
    
    on:
      push:
        branches:
          - main
        paths:
          - 'app-react-vite/**'
      pull_request:
        types: [opened, synchronize, reopened, closed]
        branches:
          - main
        paths:
          - 'app-react-vite/**'      
      workflow_dispatch:
    
    jobs:
      build_and_deploy_job:
        if: github.event_name == 'push' || github.event_name == 'workflow_dispatch' || (github.event_name == 'pull_request' && github.event.action != 'closed')
        runs-on: ubuntu-latest
        name: Build and Deploy Job
        steps:
          - uses: actions/checkout@v2
            with:
              submodules: true
          - name: Build And Deploy
            id: builddeploy
            uses: Azure/static-web-apps-deploy@v1
            with:
              azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_ORANGE_DUNE_123 }}
              repo_token: ${{ secrets.GITHUB_TOKEN }} # Used for Github integrations (i.e. PR comments)
              action: "upload"
              ###### Repository/Build Configurations - These values can be configured to match your app requirements. ######
              # For more information regarding Static Web App workflow configurations, please visit: https://aka.ms/swaworkflowconfig
              app_location: "/app-react-vite" # App source code path
              api_location: "" # Api source code path - optional
              output_location: "dist" # Built app content directory - optional
              ###### End of Repository/Build Configurations ######
            env: 
              VITE_BACKEND_URI: https://swa-api-123.azurewebsites.net
              VITE_CLOUD_ENV: production
    
      close_pull_request_job:
        if: github.event_name == 'pull_request' && github.event.action == 'closed'
        runs-on: ubuntu-latest
        name: Close Pull Request Job
        steps:
          - name: Close Pull Request
            id: closepullrequest
            uses: Azure/static-web-apps-deploy@v1
            with:
              azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_ORANGE_DUNE_123 }}
              action: "close"
    
    Cambio de propiedad Propósito
    paths Agregue la sección rutas de acceso para limitar la implementación para que solo se ejecute cuando cambie el código de la API de Azure Functions. Al editar el archivo de flujo de trabajo, puede desencadenar la implementación manualmente.
    workflow_dispatch Agregue workflow_dispatchsolo al aprender el proceso de implementación y depurar los problemas de la compilación de Vite. Quite esta línea cuando continúe con este código fuente más allá de este artículo.
    if ... || github.event_name == 'workflow_dispatch' Incluya el workflow_dispatch evento como permitido para generar una compilación solo mientras aprende el proceso de implementación y depura cualquier problema en la compilación de Vite.
    env Agregue las variables de entorno necesarias para incluir la dirección URL de Azure Function API en la compilación estática con Vite. VITE_BACKEND_URL es la dirección URL de la aplicación de funciones de Azure. VITE_CLOUD_ENV es un parámetro para indicar cuándo usar la dirección URL de VITE_BACKEND_URL. No use NODE_ENV para este ejemplo, ya que tiene efectos secundarios no deseados.
  8. Guarde el archivo y agregue, confirme y vuelva a insertarlo en GitHub con Git:

    git add .
    git commit -m "fix the workflow for a subdir"
    git push origin main
    
  9. Desde un explorador, vuelva a ejecutar el flujo de trabajo en GitHub en el área de acciones de la bifurcación para la aplicación web estática.

  10. La aplicación front-end se implementa en Azure. Ahora debe configurar la aplicación de funciones de Azure para permitir solicitudes CORS desde la aplicación web estática.

7. Configuración de CORS para la aplicación de funciones de Azure

Al usar una aplicación de funciones de Azure independiente, en lugar de una aplicación de funciones administradas, debe configurar CORS para permitir solicitudes de la aplicación web estática.

  1. En Azure Portal, abra la aplicación de funciones de Azure.
  2. En la sección API -> CORS , agregue la dirección URL de la aplicación web estática a la lista de orígenes permitidos.

8. Prueba de la aplicación web estática

  1. En un explorador, abra la aplicación web estática.
  2. Interactúe con la aplicación para iniciar sesión, ver información pública y privada y cerrarla de nuevo.

9. Limpieza de todos los recursos usados en esta serie de artículos

Limpie todos los recursos creados en esta serie de artículos.

  1. En Azure Portal, elimine el grupo de recursos, que elimina la aplicación web estática y la aplicación de funciones.
  2. En el portal de GitHub, elimine el repositorio bifurcada.

Solucionar problemas

Este ejemplo mantiene una lista de problemas conocidos y soluciones. Si el problema no aparece en la lista, abra un problema.

Direcciones URL públicas de aplicación web estática y aplicación de funciones

Siempre puede encontrar la dirección URL de la aplicación web estática y la dirección URL de la aplicación de funciones en Azure Portal, en la página Información general de cada recurso. Estas direcciones URL son públicas de forma predeterminada.

Pasos siguientes