TigerZF
🌐Español

29.5. Soporte de capas de compilación (build layer) de Zend_Dojo

29.5.1. Introducción

Las capas de compilación (build layers) de Dojo proporcionan un camino limpio desde el desarrollo hasta la producción cuando se utiliza Dojo para la capa de interfaz de usuario. En desarrollo, puede tener carga bajo demanda, prototipado rápido de aplicaciones; una capa de compilación toma todas las dependencias de Dojo y las compila en un único archivo, opcionalmente eliminando espacios en blanco y comentarios, y realizando heurísticas de código para permitir una mayor minificación de los nombres de variables. Además, puede realizar minificación de CSS.

Para crear una capa de compilación, tradicionalmente crearía un archivo JavaScript que tuviera sentencias dojo.require para cada dependencia, y opcionalmente algo de código adicional que podría ejecutarse cuando se carga el script. Como ejemplo:

dojo.provide("custom.main");

dojo.require("dijit.layout.TabContainer");
dojo.require("dijit.layout.ContentPane");
dojo.require("dijit.form.Form");
dojo.require("dijit.form.Button");
dojo.require("dijit.form.TextBox");

Este script generalmente se conoce como un script de "capa" (layer).

Después, en el layout de su aplicación, indicaría a Dojo que cargue este módulo:

<html>
<head>
    <script type="text/javascript" src="/js/dojo/dojo.js"></script>
    <script type="text/javascript">
        dojo.registerModulePath("custom", "../custom/");
        dojo.require("custom.main");
    </script>

Si utiliza Zend_Dojo para hacer esto, haría lo siguiente:

$view->dojo()->registerModulePath('custom', '../custom/')
             ->requireModule('custom.main');

Pero dado que Zend_Dojo agrega sus diversas sentencias dojo.require, ¿cómo crea su script de capa? Podría abrir cada página y ver las sentencias dojo.require generadas, y cortarlas y pegarlas manualmente en un archivo de script de capa.

Sin embargo, existe una solución mejor: dado que Zend_Dojo ya agrega esta información, puede simplemente extraer esa información y construir su archivo de capa. Este es el propósito de Zend_Dojo_BuildLayer.

29.5.2. Generación de capas de módulos personalizadas con Zend_Dojo_BuildLayer

En su forma más simple, simplemente instancia Zend_Dojo_BuildLayer, le pasa el objeto de vista y el nombre de su capa de módulo personalizada, y le hace generar el contenido del archivo de capa; luego depende de usted escribirlo en disco.

Como ejemplo, supongamos que desea crear la capa de módulo "custom.main". Suponiendo que sigue la estructura de directorios de proyecto recomendada, y que está almacenando sus archivos JavaScript bajo public/js/, podría hacer lo siguiente:

$build = new Zend_Dojo_BuildLayer(array(
    'view'      => $view,
    'layerName' => 'custom.main',
));

$layerContents = $build->generateLayerScript();
$filename      = APPLICATION_PATH . '/../public/js/custom/main.js';
if (!file_exists(dirname($filename))) {
    mkdir(dirname($filename));
}
file_put_contents($filename, $layerContents);

¿Cuándo debería hacer lo anterior? Para que funcione correctamente, necesita hacerlo después de que se hayan renderizado todos los scripts de vista y el layout, para asegurar que el ayudante dojo() esté completamente poblado. Una forma sencilla de hacerlo es utilizando un plugin del controlador frontal, con un gancho dispatchLoopShutdown():

class App_Plugin_DojoLayer extends Zend_Controller_Plugin_Abstract
{
    public $layerScript = APPLICATION_PATH . '/../public/js/custom/main.js';
    protected $_build;

    public function dispatchLoopShutdown()
    {
        if (!file_exists($this->layerScript)) {
            $this->generateDojoLayer();
        }
    }

    public function getBuild()
    {
        $viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper(
            'ViewRenderer'
        );
        $viewRenderer->initView();
        if (null === $this->_build) {
            $this->_build = new Zend_Dojo_BuildLayer(array(
                'view'      => $viewRenderer->view,
                'layerName' => 'custom.main',
            ));
        }
        return $this->_build;
    }

    public function generateDojoLayer()
    {
        $build = $this->getBuild();
        $layerContents = $build->generateLayerScript();
        if (!file_exists(dirname($this->layerScript))) {
            mkdir(dirname($this->layerScript));
        }
        file_put_contents($this->layerScript, $layerContents);
    }
}
[Note] No genere la capa en cada página

Es tentador generar el script de capa en cada página. Sin embargo, esto consume muchos recursos, ya que debe escribir en el disco en cada página. Además, dado que el mtime del archivo seguirá cambiando, no obtendrá ningún beneficio del caché del lado del cliente. Escriba el archivo una sola vez.

29.5.2.1. Opciones de BuildLayer

La funcionalidad anterior será suficiente para la mayoría de las situaciones. Para aquellos que necesiten más personalización, se puede invocar una variedad de opciones.

29.5.2.1.1. Establecer el objeto de vista

Aunque el objeto de vista puede pasarse durante la instanciación, también puede pasarlo a una instancia a través del método setView():

$build->setView($view);
29.5.2.1.2. Establecer el nombre de la capa

Aunque el nombre de la capa puede pasarse durante la instanciación, también puede pasarlo a una instancia a través del método setLayerName():

$build->setLayerName("custom.main");
29.5.2.1.3. Incluir eventos onLoad en la capa generada

dojo.addOnLoad es una utilidad útil para especificar acciones que deben dispararse cuando el DOM ha terminado de cargarse. El ayudante de vista dojo() puede crear estas sentencias a través de sus métodos addOnLoad() y onLoadCapture(). En algunos casos, tiene sentido incluirlos en su archivo de capa en lugar de renderizarlos a través de sus scripts de vista.

Por defecto, estos no se renderizan; para habilitarlos, pase la clave de configuración consumeOnLoad durante la instanciación:

$build = new Zend_Dojo_BuildLayer(array(
    'view'          => $view,
    'layerName'     => 'custom.main',
    'consumeOnLoad' => true,
));

Alternativamente, puede usar el método setConsumeOnLoad() después de la instanciación:

$build->setConsumeOnLoad(true);
29.5.2.1.4. Incluir JavaScript capturado en la capa generada

El ayudante de vista dojo() incluye métodos para capturar JavaScript arbitrario para incluir en la etiqueta <script> que contiene las diversas sentencias dojo.require y dojo.addOnLoad. Esto puede resultar útil al crear almacenes de datos predeterminados u objetos con ámbito global utilizados en toda su aplicación.

Por defecto, estos no se renderizan; para habilitarlos, pase la clave de configuración consumeJavascript durante la instanciación:

$build = new Zend_Dojo_BuildLayer(array(
    'view'              => $view,
    'layerName'         => 'custom.main',
    'consumeJavascript' => true,
));

Alternativamente, puede usar el método setConsumeJavascript() después de la instanciación:

$build->setConsumeJavascript(true);

29.5.3. Generación de perfiles de compilación con Zend_Dojo_BuildLayer

Uno de los principales beneficios de una capa de módulo de Dojo es que facilita la creación de una compilación personalizada. Zend_Dojo_BuildLayer tiene funcionalidad para generar perfiles de compilación.

El caso de uso más simple es utilizar el método generateBuildProfile() y enviar la salida a un archivo:

$build = new Zend_Dojo_BuildLayer(array(
    'view'      => $view,
    'layerName' => 'custom.main',
));

$profile   = $build->generateBuildProfile();
$filename  = APPLICATION_PATH . '/../misc/scripts/custom.profile.js';
file_put_contents($filename, $profile);

Al igual que la generación de capas, puede que desee automatizar esto mediante un gancho de plugin dispatchLoopShutdown(); incluso podría simplemente modificar el mostrado para la generación de capas para que quede así:

class App_Plugin_DojoLayer extends Zend_Controller_Plugin_Abstract
{
    public $layerScript  = APPLICATION_PATH
                         . '/../public/js/custom/main.js';
    public $buildProfile = APPLICATION_PATH
                         . '/../misc/scripts/custom.profile.js';
    protected $_build;

    public function dispatchLoopShutdown()
    {
        if (!file_exists($this->layerScript)) {
            $this->generateDojoLayer();
        }
        if (!file_exists($this->buildProfile)) {
            $this->generateBuildProfile();
        }
    }

    public function generateDojoLayer() { /* ... */ }

    public function generateBuildProfile()
    {
        $profile = $this->getBuild()->generateBuildProfile();
        file_put_contents($this->buildProfile, $profile);
    }

}

Como se ha señalado, con las capas de módulo, solo debe crear el archivo una vez.

29.5.3.1. Opciones del perfil de compilación

La funcionalidad anterior será suficiente para la mayoría de las situaciones. La única manera de personalizar la generación del perfil de compilación es proporcionar opciones adicionales de perfil de compilación a utilizar.

Como ejemplo, puede que desee especificar qué tipo de optimizaciones deben realizarse, si se deben optimizar o no los archivos CSS en la capa, si se deben copiar o no las pruebas en la compilación, etc. Para obtener una lista de las opciones disponibles, debería leer la documentación de compilación de Dojo y la documentación que la acompaña.

Establecer estas opciones es trivial: utilice los métodos addProfileOption(), addProfileOptions(), o setProfileOptions(). El primer método añade un único par de clave y valor de opción, el segundo añadirá varios, y el tercero sobrescribirá cualquier opción con la lista de pares de clave y valor proporcionados.

Por defecto, se establecen las siguientes opciones:

{
    action:        "release",
    optimize:      "shrinksafe",
    layerOptimize: "shrinksafe",
    copyTests:     false,
    loader:        "default",
    cssOptimize:   "comments"
}

Puede pasar los pares de clave y valor que desee; el script de compilación de Dojo ignorará aquellos que no comprenda.

Como ejemplo de establecimiento de opciones:

// A single option:
$build->addProfileOption('version', 'zend-1.3.1');

// Several options:
$build->addProfileOptions(array(
    'loader'   => 'xdomain',
    'optimize' => 'packer',
));

// Or overwrite options:
$build->setProfileOptions(array(
    'version'  => 'custom-1.3.1',
    'loader'   => 'shrinksafe',
    'optimize' => 'shrinksafe',
));