2012-04-10 8 views
6

come ho potuto vedere, la Gjs imports, carichi solo /usr/share/gjs-1.0 e /usr/lib/gjs-1.0 per impostazione predefinita. Voglio modulare un'applicazione, come possiamo fare con il nodo, ma devo trovare i moduli relativi al file di script.Come impostare un percorso incluso nel codice Gjs?

Ho trovato questo due modi per aggiungere sono i percorsi:

  1. gjs --include-path=my-modules my-script.js
  2. GJS_PATH=my-modules gjs my-script.js

... ma entrambi sono legati alla directory corrente, non al file (obliviously e dovevano essere dichiarati sulla riga di comando, rendendo questo inutilmente complesso.

come posso impostare un percorso compreso nel codice Gjs? (Quindi posso renderlo relativo al file)

Oppure ... C'è un altro modo per importare file da qualsiasi luogo, come in python?

(Per favore, non è necessario proporre di usare un lanciatore shellscript per risolvere il problema e --include-pathGJS_PATH. Questo è ovvio, ma meno potente. Se non abbiamo una soluzione migliore, si sopravvive con quello.

risposta

8

È necessario impostare o modificare imports.searchPath (che non è ovvio perché non viene visualizzato con for (x in imports)print(x)). Quindi questo:

imports.searchPath.unshift('.'); 
var foo = imports.foo; 

importa il file “foo.js” come oggetto foo.

Questo è compatibile con Seed, anche se losa che ha un searchPath.

(versioni precedenti di questa risposta sono stati sostanzialmente meno precise e più infiammatorio. Siamo spiacenti).

5

Come dice Douglas, si ha bisogno di modificare imports.searchPath per includere la posizione della libreria. L'utilizzo di . è semplice, ma dipende dai file che vengono sempre eseguiti dallo stesso percorso di directory. Sfortunatamente trovare la directory dello script attualmente in esecuzione è un enorme hack. Ecco come Gnome Shell does it for the extensions API

Ho adattato questo nel seguente funzione per uso generale:

const Gio = imports.gi.Gio; 

function getCurrentFile() { 
    let stack = (new Error()).stack; 

    // Assuming we're importing this directly from an extension (and we shouldn't 
    // ever not be), its UUID should be directly in the path here. 
    let stackLine = stack.split('\n')[1]; 
    if (!stackLine) 
     throw new Error('Could not find current file'); 

    // The stack line is like: 
    // init([object Object])@/home/user/data/gnome-shell/extensions/[email protected]/prefs.js:8 
    // 
    // In the case that we're importing from 
    // module scope, the first field is blank: 
    // @/home/user/data/gnome-shell/extensions/[email protected]/prefs.js:8 
    let match = new RegExp('@(.+):\\d+').exec(stackLine); 
    if (!match) 
     throw new Error('Could not find current file'); 

    let path = match[1]; 
    let file = Gio.File.new_for_path(path); 
    return [file.get_path(), file.get_parent().get_path(), file.get_basename()]; 
} 

Ecco come si potrebbe usarlo dal file punto di ingresso app.js, dopo aver definito la funzione getCurrentFile:

let file_info = getCurrentFile(); 

// define library location relative to entry point file 
const LIB_PATH = file_info[1] + '/lib'; 
// then add it to the imports search path 
imports.searchPath.unshift(LIB_PATH); 

Wee! ora importare le nostre biblioteche è super-facile:

// import your app libraries (if they were in lib/app_name) 
const Core = imports.app_name.core;