Extender Webpack en la cadena de herramientas de SharePoint Framework

Webpack es un módulo que instala varios programas de JavaScript que toma los archivos de JavaScript y sus dependencias y genera uno o varios archivos JavaScript para que pueda cargar distintos fragmentos de código para distintos escenarios.

La cadena de herramientas de Framework usa CommonJS como unión. Esto le permite definir los módulos y el lugar en el que quiere usarlos. La cadena de herramientas también usa SystemJS, un cargador de módulos universal, para cargar los módulos. Esto le ayuda a definir el ámbito de los elementos web asegurándose de que cada uno se ejecuta en su propio espacio de nombres.

Una tarea común que puede agregar a la cadena de herramientas de SharePoint Framework es ampliar la configuración de Webpack con complementos y cargadores personalizados.

Usar cargadores de Webpack

Hay muchos casos en los que se quiere importar y usar un recurso que no sea JavaScript durante el desarrollo, lo que suele realizarse con imágenes o plantillas. Un cargador de Webpack convierte el recurso en algo que la aplicación JavaScript puede utilizar u ofrece una referencia simple que la aplicación JavaScript puede entender.

Por ejemplo, una plantilla de Markdown se puede compilar y convertir en una cadena de texto, mientras que un recurso de imagen puede convertirse en una imagen Base64 insertada o hacerse referencia a él como dirección URL y copiarse en el directorio de implementación dist.

Existen varios cargadores útiles, algunos ya se usan en la configuración estándar de Webpack de SharePoint Framework, como:

  • html-loader
  • json-loader
  • loader-load-themed-styles

La ampliación de la configuración de Webpack de Framework con cargadores personalizados es un proceso sencillo que se recoge en la documentación sobre cargadores de Webpack.

Ejemplo: Usar el paquete markdown-loader

A modo de ejemplo, se usará el paquete markdown-loader. Se trata de un cargador que le permite hacer referencia a un archivo .md y obtener una cadena HTML como resultado.

Puede descargar el ejemplo completo en samples/js-extend-webpack.

Paso 1: Instalar el paquete

Haga referencia a markdown-loader en el proyecto:

npm i --save markdown-loader

Paso 2: Configurar Webpack

Ahora que se ha instalado el paquete, se define la configuración de Webpack de SharePoint Framework para que incluya markdown-loader.

En la documentación de markdown-loader, se muestra cómo extender la configuración de Webpack para incluir el cargador:

{
  module: {
    rules: [
      {
        test: /\.md$/,
        use: [
          {
            loader: 'html-loader'
          },
          {
            loader: 'markdown-loader',
            options: {
              /* options for markdown-loader here */
            }
          }
        ]
      }
    ]
  }
}

Echemos un vistazo a lo que hace esta configuración:

  • La matriz rules de la configuración de Webpack define un conjunto de pruebas de ruta de acceso de archivo y los cargadores que deben utilizarse cuando se encuentra un recurso que coincide con la prueba. En este caso, la propiedad test busca rutas de acceso de archivo que terminen en .md.
  • La matriz use describe una lista de cargadores que se aplican secuencialmente al recurso. Se aplican del último al primero. En este caso, el primer cargador que se aplica es markdown-loader y el último cargador que se aplica es html-loader.
  • Cuando se especifican varios cargadores, el resultado de cada cargador se canaliza al siguiente.

Se usará esta información para configurarlo en el proyecto.

Para agregar este cargador personalizado a la configuración de Webpack de SharePoint Framework, hay que indicar a la tarea de compilación que configure Webpack. Las tareas de compilación se definen en el archivo gulpfile.js que se encuentra en la raíz del proyecto.

Edite el archivo gulpfile.js y agregue el siguiente código justo antes de build.initialize(gulp);:

build.configureWebpack.mergeConfig({
  additionalConfiguration: (generatedConfiguration) => {
    generatedConfiguration.module.rules.push(
      {
        test: /\.md$/,
        use: [
          {
            loader: 'html-loader'
          },
          {
            loader: 'markdown-loader'
          }
        ]
      }
    );

    return generatedConfiguration;
  }
});

Veamos lo que hace este fragmento de código:

  • La ConfigureWebpackTask (que crea una instancia de build.configureWebpack) configura el webpack automáticamente. Se produce mucha configuración especial para generar proyectos de SPFx, por lo que hay alguna lógica no trivial en esta tarea.
  • ConfigureWebpackTask adopta una propiedad opcional additionalConfiguration. Se quiere establecer esta propiedad en una función que toma la configuración generada, le realiza las modificaciones y luego devuelve la configuración actualizada. Esta función debe devolver una configuración de Webpack a la cadena de herramientas, de lo contrario Webpack no se configurará correctamente.
  • En el cuerpo de la función que se establece como additionalConfiguration, basta con insertar una nueva regla en el conjunto de reglas existente en la configuración. Observe que esta nueva regla es similar al ejemplo del fragmento de código de configuración que aparece al principio del paso 2.

Nota:

Aunque puede reemplazar por completo la configuración predeterminada de Webpack de la cadena de herramientas con este enfoque, para sacar el máximo partido del rendimiento y la optimización, no se recomienda hacerlo a no ser que se indique lo contrario en la documentación.

Paso 3: Actualizar el código

Ahora que se ha configurado el cargador, vamos a actualizar el código y a agregar algunos archivos para probar el escenario.

  1. Cree un archivo ./src/my-markdown.md que incluya texto Markdown.

    #Hello Markdown
    
    *Markdown* is a simple markup format to write content.
    
    You can also format text as **bold** or *italics* or ***bold italics***
    

Al compilar el proyecto, el markdown-loader de Webpack convertirá este texto Markdown en una cadena HTML.

  1. Para usar esta cadena HTML en cualquiera de sus archivos .ts de origen, agregue la siguiente línea require() en la parte superior del archivo después de las importaciones, por ejemplo:

    const markdownString: string = require<string>('./../../../../src/my-markdown.md');
    

    De manera predeterminada, Webpack busca el archivo en la carpeta lib, pero los archivos .md no se copian de manera predeterminada en la carpeta lib, por lo que hay que crear una ruta de acceso relativa bastante más larga. Se puede controlar esta opción definiendo un archivo de configuración que indique a la cadena de herramientas que copie los archivos md en la carpeta lib.

  2. Cree un archivo ./config/copy-static-assets.json para indicar al sistema de compilación que copie algunos archivos adicionales de src a lib. Esta tarea de compilación copia archivos con extensiones que la configuración predeterminada de Webpack de la cadena de herramientas entiende (como png y json), por lo que solo hay que indicarle que también copie archivos md.

    {
      "includeExtensions": [
        "md"
      ]
    }
    
  3. Ahora, en lugar de usar la ruta de acceso relativa, puede usar la ruta del archivo en su instrucción require, por ejemplo:

    const markdownString: string = require<string>('./../../readme.md');
    
  4. Después, puede hacer referencia a esta cadena en su código, por ejemplo:

    public render(): void {
      this.domElement.innerHTML = markdownString;
    }
    

Paso 4: Compilar y probar el código

Para compilar y probar el código, ejecute el siguiente comando en una consola en la raíz del directorio del proyecto:

gulp serve

Ver también