Compartir a través de


Tutorial: Uso de bibliotecas dependientes en un componente

[Este tema es documentación preliminar y está sujeto a modificaciones.]

En este tutorial se muestra cómo crear un componente de código para aplicaciones basadas en modelos que depende de las bibliotecas contenidas en otro componente. Más información sobre la vista previa de bibliotecas dependientes

Goal

Siga los pasos de este tutorial para crear un control de biblioteca y un control que dependa de él. Este tutorial contiene los pasos siguientes:

  1. Crear el componente de biblioteca: cree un componente que solo contenga la biblioteca reutilizable. Para simplificar, este control solo contiene la biblioteca reutilizable. No hay ninguna razón por la que no pueda proporcionar también funcionalidad.
  2. Cree el control dependiente: cree un componente que use la biblioteca definida en el control de biblioteca y agréguelo a un formulario de aplicación basada en modelo para comprobar que funciona.
  3. Cargar biblioteca dependiente a petición: amplíe el ejemplo para que el componente dependiente cargue el recurso de biblioteca a petición en lugar de que el marco cargue la biblioteca cuando se cargue el control.

Requisitos previos

Ya deberías saber cómo:

1. Crear el componente de biblioteca

Este componente no proporciona ninguna capacidad por sí mismo. Es simplemente un contenedor para la biblioteca.

El primer paso es crear un nuevo componente usando el comando pac pcf init:

pac pcf init -n StubLibrary -ns SampleNamespace -t field -npm

Definir la biblioteca

  1. Necesita un nuevo archivo de declaración (d.ts) para describir los objetos y funciones contenidos en su biblioteca. Cree un nuevo archivo llamado myLib.d.ts en la carpeta raíz de su proyecto:

    declare module 'myLib' {
      export function sayHello(): string;
    }
    
  2. Vamos a exponer nuestra biblioteca como un módulo UMD, y necesitamos poner la variable en el ámbito global. Para ello necesitamos un nuevo fichero de declaración (d.ts). Cree un nuevo archivo llamado global.d.ts en la carpeta raíz de su proyecto:

    /* eslint-disable no-var */
    declare global {
      var myLib: typeof import('myLib');
    }
    
    export { };
    
  3. Actualice tsconfig.json para permitir módulos UMD y código javascript de la siguiente manera:

    {
        "extends": "./node_modules/pcf-scripts/tsconfig_base.json",
        "compilerOptions": {
            "typeRoots": ["node_modules/@types"]
        }
    }
    

Agregar la biblioteca

En la nueva carpeta de control, agregue una nueva carpeta que contenga las bibliotecas libs para este ejemplo, cree un nuevo archivo JavaScript. En este ejemplo se usa una biblioteca llamada myLib-v_0_0_1.js que tiene una sola función sayHello.

// UMD module pattern
var myLib = (function (exports) {
"use strict";

function sayHello() {
   return "Hello from myLib";
}

exports.sayHello = sayHello;

return exports;
})(/** @type {import('myLib')}  */ ({}));

Agregar datos de configuración

  1. Agregue un archivo llamado featureconfig.json en la carpeta raíz del proyecto.

  2. Agregue el siguiente texto al archivo featureconfig.json:

    {
      "pcfAllowCustomWebpack": "on",
      "pcfAllowLibraryResources": "on"
    }
    

    Puede obtener más información sobre el archivo featureconfig.json

  3. Agregue un archivo nuevo webpack.config.js en la carpeta raíz de su proyecto. Estos datos de configuración garantizan que las bibliotecas no se incluyan con la salida del control. La inclusión no es necesaria porque ya se empaquetan por separado al compilar el proyecto.

    /* eslint-disable */
    "use strict";
    
    module.exports = {
      externals: {
        "myLib": "myLib"
      },
    }
    

    Puede obtener más información sobre el archivo webpack.config.json

  4. Agregue una referencia a la biblioteca bajo resources en el manifiesto de control

<resources> 
  <code path="index.ts" order="1"/> 
</resources> 

Agregue la biblioteca a la ventana

El último paso es editar el index.ts del control para enlazar la biblioteca a la ventana.

import { IInputs, IOutputs } from "./generated/ManifestTypes";

export class StubLibrary
implements ComponentFramework.StandardControl<IInputs, IOutputs>
{
 constructor() {
   // Empty
 }

 public init(
    context: ComponentFramework.Context<IInputs>,
    notifyOutputChanged: () => void,
    state: ComponentFramework.Dictionary,
    container: HTMLDivElement
 ): void {
   // Add control initialization code
 }

 public updateView(context: ComponentFramework.Context<IInputs>): void {
   // Add code to update control view
 }

 public getOutputs(): IOutputs {
    return {};
 }

  public destroy(): void {
    // Add code to cleanup control if necessary
  }
}

El proyecto de biblioteca deberá tener un aspecto similar al siguiente:

Vista de la carpeta del proyecto

Compilar y empaquetar el componente de biblioteca

Para finalizar el componente de biblioteca, complete los siguientes pasos como de costumbre:

  1. Crear y generar el componente de código
  2. Empaquete el componente de código
  3. Implementar el componente de código

2. Compilar el control dependiente

Ahora que tiene un control de biblioteca, necesita un control que dependa de él.

  1. Crea un nuevo componente usando este comando:

    pac pcf init -n DependencyControl -ns SampleNamespace -t field -fw react -npm
    
  2. Agregue un nuevo archivo de control característica en la carpeta raíz de su proyecto llamado featureconfig.json que contiene el siguiente texto:

    {
      "pcfResourceDependency": "on"
    } 
    
  3. Agregue el recurso dependiente en el manifiesto de control.

    Utilice el schemaName del control dependiente [solution prefix]_[namespace].[control name] que puede encontrar en el archivo solution.xml del componente dependiente. El XML del archivo solution.xml podría tener este aspecto:

    <RootComponents>
      <RootComponent
       type="66"
       schemaName="samples_SampleNamespace.StubLibrary"
       behavior="0"
      />
    </RootComponents>
    
<resources>
      <code path="index.ts"
         order="1" />
      <platform-library name="React"
         version="16.14.0" />
      <platform-library name="Fluent"
         version="9.46.2" />
</resources> 

Añada Global.d.ts

Dado que StubLibrary se expone como un módulo UMD, debemos colocar la variable en el ámbito global. Para ello necesitamos un nuevo fichero de declaración (d.ts). Cree un nuevo archivo llamado global.d.ts en la carpeta raíz de su proyecto:

/* eslint-disable no-var */

interface MyLib {
      sayHello(): string;
}

declare global {
      var myLib: MyLib;
}

export { };

Usar la función de biblioteca

Actualice el archivo de componente HelloWorld.tsx para que utilice una función de la biblioteca dependiente. La biblioteca se carga en el objeto Window en tiempo de ejecución.

import * as React from 'react';
import { Label } from '@fluentui/react-components';

export interface IHelloWorldProps {
  name?: string;
}

export class HelloWorld extends React.Component<IHelloWorldProps> {
  public render(): React.ReactNode {
    return (
      <Label>
        {this.props.name}
      </Label>
    )
  }
}

Compilar y empaquetar el componente dependiente

Para finalizar el componente dependiente, complete los siguientes pasos como de costumbre:

  1. Crear y generar el componente de código
  2. Empaquete el componente de código
  3. Implementar el componente de código

Agregue el componente al formulario

  1. Agregue el componente a su aplicación basada en formulario.

  2. Navegue hasta el formulario y debería ver que el componente muestra el texto Hello from myLib from Dependency.

    Imagen del componente que se ejecuta en un entorno

3. Cargue la biblioteca dependiente bajo demanda

Puede expandir el ejemplo cambiando el componente dependiente para que cargue el recurso de biblioteca a petición en lugar de que el marco cargue la biblioteca cuando se cargue el componente. El comportamiento de carga a petición es útil si las bibliotecas que utiliza el control son grandes y aumentarían el tiempo de carga del formulario.

Especificar el comportamiento de la carga a petición

Para especificar el comportamiento de carga a petición, modifique el manifiesto de control del componente creado en 2. Construya el control dependiente.

<resources>
    <dependency type="control"
        name="samples_SampleNamespace.StubLibrary"
        order="1" />
    <code path="index.ts"
        order="2" />
    <platform-library name="React" version="16.14.0" />
    <platform-library name="Fluent" version="9.46.2" />
</resources>

Modificar el componente dependiente para cargar la biblioteca bajo demanda

Modifique HelloWorld.tsx para agregar un estado y métodos para actualizarlo una vez que se cargue la dependencia.

import * as React from 'react';
import { Label } from '@fluentui/react-components';

export interface IHelloWorldProps {
  name?: string;
}

export class HelloWorld extends React.Component<IHelloWorldProps> {
  public render(): React.ReactNode {
    return (
      <Label>
        { window.myLib.sayHello() + " from Dependency" || "Hello World"}
      </Label>
    )
  }
}

Actualizar index.ts

Cuando el script se carga bajo demanda, debe realizar ligeros ajustes en la forma en que se crea e inicializa el componente. Por ejemplo, nuevas variables para las referencias al contexto y al contenedor para actualizar el estado.

Lo más importante es agregar un método getActions para reaccionar a la carga y solicitar que se cargue el control dependiente.

import { IInputs, IOutputs } from "./generated/ManifestTypes";
import { HelloWorld, IHelloWorldProps } from "./HelloWorld";
import * as React from "react";

export class DependencyControl implements ComponentFramework.ReactControl<IInputs, IOutputs> {
    private notifyOutputChanged: () => void;

    constructor() {
        // Empty
    }

    public init(
        context: ComponentFramework.Context<IInputs>,
        notifyOutputChanged: () => void,
        state: ComponentFramework.Dictionary
    ): void {
        this.notifyOutputChanged = notifyOutputChanged;
    }

    public updateView(context: ComponentFramework.Context<IInputs>): React.ReactElement {
        const props: IHelloWorldProps = { name: 'Power Apps' };
        return React.createElement(
            HelloWorld, props
        );
    }

    public getOutputs(): IOutputs {
        return { };
    }

    public destroy(): void {
        // Add code to cleanup control if necessary
    }
}

Pasos finales

  1. Actualice el número de versión del control en el ControlManifest.Input.xml y la versión en el Solution.xml
  2. Recompile, empaquete, implemente y publique la solución con el control actualizado.

Compruebe los resultados

Ahora, cuando se cargue la página, verá la carga de control Loading... mostrada.

Imagen del componente mientras se carga el formulario

Una vez que se carga la página, el control se actualiza para mostrar Hello from myLib Dependency On Demand Load.

Imagen del componente una vez cargado el formulario

Bibliotecas dependientes (versión preliminar)