Please note, this is a STATIC archive of website developer.mozilla.org from 03 Nov 2016, cach3.com does not collect or store any user information, there is no "phishing" involved.

Usando módulos de código JavaScript

Imagen:traduccion-pendiente.png Esta página está traduciéndose a partir del artículo Using JavaScript code modules, razón por la cual puede haber algunos errores sintácticos o partes sin traducir. Puedes colaborar continuando con la traducción

Los módulos de código JavaScript son un concepto introducido en Firefox 3 (Gecko 1.9) y pueden ser usados para compartir código entre alcances (scopes) con diferentes privilegios. Los módulos pueden también ser usados para crear singletons globales de JavaScript que previamente requerian usar objetos XPCOM de JavaScript. Un módulo de código JavaScript es simplemente una porción de código JavaScript ubicado en una ubiación registrada. El módulo es cargado dentro de un alcance (scope) de JavaScript específico, tal como un script de XUL o un script XPCOM de JavaScript, usando Components.utils.import.

Creación de módulos JavaScript

Los módulos JavaScript tienen dos secciones: 1. un array EXPORTED_SYMBOLS en el que se declaran como "símbolos" los objetos, propiedades y métodos que serán empleados por los scripts que los importen. Y, 2. El código, que trata las propiedades y métodos de los "símbolos" exportados. Un muy sencillo módulo de JavaScript luce como esto:

var EXPORTED_SYMBOLS = ["foo", "bar"]

function foo() {
  return "foo";
}

var bar = {
  name : "bar",
  size : "3"
};

var dummy = "dummy";

Nótese que el módulo usa JavaScript normal para crear funciones, objetos, constantes y cualquier otro tipo JavaScript. Sólo los elementos declarados en el Array especial EXPORTED_SYMBOLS serán accesibles desde el exterior del módulo; los demás quedan encapsulados y no son accesibles fuera del mismo. Cualquier elemento de JavaScript nombrado en EXPORTED_SYMBOLS será exportado desde el módulo e insertado dentro del alcance (scope) importador. Por ejemplo:

Components.utils.import("resource://app/modules/my_module.jsm");

alert(foo());         // muestra "foo"
alert(bar.size + 3);  // muestra "6"
alert(dummy);         // muestra "dummy is not defined" porque 'dummy' no fue exportado desde el módulo.

La URL de un módulo JavaScript

Como se puede apreciar en el ejemplo, arriba, hace falta un llamado empleando una dirección URL para poder importar los módulos JavaScript. Éstos, normalmente, se crean como archivos planos con extensión jsm y se almacenan el el directorio /modules del aplicativo (XUL) o extensión para el que son creados. Y, se cargan usando un protocolo "resource:" (en el ejemplo) al presentar la URL como parámetro del llamado.

Sólo se pueden emplear los protocolos "chrome:" ( Requiere Gecko 2) "resource:" o "file:"para cargar módulos JavaScript.

  • Si está escribiendo una extensión para Firefox 4.x y cuenta con un archivo de manifiesto "chrome.manifest" en el que se ha declarado la ubicación del directorio "content" (mediante una instrucción content, ver tutorial XUL) puede alojar allí sus módulos JavaScript y cargarlos mediante el protocolo "chrome:", así: chrome://<yourextension>/content/<yourmodule>.jsm .
  • Si su extensión o aplicación debe soportar Mozilla 1.9.x (Firefox 3.x) será necesario registrar su ubicación en el manifiesto chrome de la misma (chrome.manifest) más adelante se explica como hacerlo.

Compartiendo objetos mediante módulos

Un comportamiento extremadamente importante de Components.utils.import es que los módulos son cacheados cuando se cargan e importaciones posteriores no recargan una nueva versión del módulo, sino que usan la version cacheada anteriormente. Esto significa que un módulo dado será compartido cuando sea importado varias veces. Cualquier modificacion a datos, objetos o funciones estarán disponibles en cualquier alcance (scope) que haya importado el módulo. Por ejemplo, si el modulo de ejemplo fue importado en dos alcances (scopes) diferentes de JavaScript, los cambios en un alcance (Scope) serán visibles desde el otro alcance (scope).

Alcance (scope) 1:

Components.utils.import("resource://app/modules/my_module.jsm");

alert(bar.size + 3);  // muestra "6"

bar.size = 10;

Alcance (scope) 2:

Components.utils.import("resource://app/modules/my_module.jsm");

alert(foo());         // muestra "foo"
alert(bar.size + 3);  // muestra "13"

Este comportamiento de compartir puede ser usado para crear objetos singleton que compartan datos entre ventanas y entre scripts XUL y componentes XPCOM.

Nota: Cada ámbito (alcance) al que sea importado un módulo recibe una copia por-valor de los símbolos exportados por el módulo. De modo que los cambios que allí se realicen para los mismos no se verán reflejados en otros lugares. (Ésto garantiza que los "nombres" de los símbolos exportados no cambien para otros sitios y se pueda hacer referencia los mismos de modo uniforme)

Alcance 1

 Components.utils.import("resource://app/my_module.jsm");

bar = "foo";
alert(bar);         // muestra "foo"

Alcance 2

Components.utils.import("resource://app/my_module.jsm");

alert(bar);         // muestra "[object Object]"

resource: Protocol

Cuando uses Components.utils.import, notarás que los módulos de código son cargados usando el protocolo "resource://". La sintaxis básica de un recurso URL es como sigue:

resource://<alias>/<ruta-relativa>/<archivo.js|jsm>

El <alias> es un alias a una ubicación, usualmente una hubicación física relativa a la aplicación o al runtime de XUL. Existen algunos alias predefinidos por defecto por el runtime de XUL runtime:

  • app - Alias a la ubicación de la aplicación de XUL.
  • gre - Alias a la ubicación del runtime de XUL.

La <ruta-relativa> puede tener múltiples niveles de profundidad y siempre es relativa a la ubicación definida por el <alias>. La ruta relativa común es "modules" y es usada por XUL Runner and Firefox. Los módulos de código son simples archivos JavaScript con la extensión .js o .jsm.

La manera mas sencilla para extensiones y aplicaciones XUL de agregar alias propios es al registrar un alias en el manifiesto chrome usando algo como esto:

resource nombrealias uri/a/los/archivos/

Por ejemplo, si el XPI de tu extension foo incluye un directorio de primer nivel de módulos conteniendo el módulo bar.js, podrías crear un alias a ese directorio mediante la instrucción:

resource foo modules/

Podrias entonces importar el módulo en tu código JavaScript mediante la sentencia:

Components.utils.import("resource://foo/bar.js");

Los alias propios pueden también ser agregados programáticamente al protocolo de recursos. Por ejemplo:

var ioService = Components.classes["@mozilla.org/network/io-service;1"]
                          .getService(Components.interfaces.nsIIOService);
var resProt = ioService.getProtocolHandler("resource")
                       .QueryInterface(Components.interfaces.nsIResProtocolHandler);

var aliasFile = Components.classes["@mozilla.org/file/local;1"]
                          .createInstance(Components.interfaces.nsILocalFile);
aliasFile.initWithPath("/some/absolute/path");

var aliasURI = ioService.newFileURI(aliasFile);
resProt.setSubstitution("myalias", aliasURI);

// asumiendo que el módulo de código está en el directorio de alias misma, no en un subdirectorio
Components.utils.import("resource://myalias/file.jsm");

// ...

Etiquetas y colaboradores del documento

Etiquetas: 
 Colaboradores en esta página: pau87x, matiast, ethertank, ibnkhaldun, RpJ, Mgjbot, Mariano
 Última actualización por: pau87x,