2013-12-09 14 views
5

UPDATE: ho cercato la risposta di Jeff Barczewski qui sotto, e anche se non ho più l'errore sotto per i plugin, ora sto ottenendo un errore diverso:Requirejs non può compilare il modulo dojo-dipendente

Error: TypeError: Cannot read property 'normalize' of undefined 
In module tree: 
    mymodule/core 

    at Object.<anonymous> (/usr/local/lib/node_modules/requirejs/bin/r.js:1193:35) 

UPDATE 2: Dal momento che Jeff ha ragione sul fatto che i plug-in di Dojo non sono compatibili con RequireJS, ho deciso di passare a utilizzare grunt-dojo invece di creare dojo. Uso ancora RequireJS per il mio codice e semplicemente sovrascrivo le dipendenze del dojo per essere ignorato.

originale del messaggio:

Sto cercando di utilizzare grugnito per compilare un unico file JS per abbassare la quantità di richieste HTTP browser devono fare. Dal momento che Dojo 1.9 è compatibile con AMD, ho pensato di utilizzare il plugin requirejs di Grunt per ottimizzare il mio codice. Tuttavia, sto ricevendo il seguente errore, sia quando si utilizza il plugin Grunt e quando si utilizza r.js direttamente:

>> Tracing dependencies for: mymodule/core 
>> TypeError: Cannot call method 'createElement' of undefined 
>> In module tree: 
>>  mymodule/core 
>>  dojo/behavior 
>>   dojo/query 
>>   dojo/selector/_loader 
{ [Error: TypeError: Cannot call method 'createElement' of undefined 
In module tree: 
    mymodule/core 
     dojo/behavior 
     dojo/query 
      dojo/selector/_loader 

    at eval (eval at <anonymous> (/Users/EugeneZ/Workspace/presentment/web/js/node_modules/grunt-contrib-requirejs/node_modules/requirejs/bin/r.js:23690:38), <anonymous>:6:24) 
] 
    originalError: 
    { [TypeError: Cannot call method 'createElement' of undefined] 
    moduleTree: 
     [ 'dojo/selector/_loader', 
     'dojo/query', 
     'dojo/behavior', 
     'mymodule/core' ], 
    fileName: '/Users/EugeneZ/Workspace/presentment/web/js/dojo_release/dojo/selector/_loader.js' } } 

Guardando il codice per il modulo _loader Dojo, è ammesso che è in esecuzione in un browser e basandosi su il document globale:

var document; 
var testDiv = document.createElement("div"); 

Ma perché requirejs non consente questo? Ho cercato la loro documentazione e non riesco a trovare alcun modo per disattivare questo controllo. Presumo che sto fraintendendo qualcosa o facendo qualcosa di sbagliato, ma non riesco a capirlo.

Ecco la parte requirejs rilevanti delle mie Gruntfile.js:

requirejs: { 
     compile: { 
      options: { 
       'baseUrl': './', 
       'paths': { 
        'dojo': 'dojo_release/dojo', 
        'dojox': 'dojo_release/dojox', 
        'dijit': 'dojo_release/dijit', 
        'mymodule' : 'core/mymodule', 
        'osi': 'osi', 
        'demo': 'demo', 
        'slick': 'core/slick' 
       }, 
       'name': 'mymodule/core', 
       'out': './mymodule.js' 
      } 
     } 
    } 
+0

Hai mai trovato una soluzione al problema "Impossibile leggere la proprietà 'normalizza' di non definito"? –

+1

Non l'ho fatto. Alla fine, ho dovuto fare un passo indietro e chiedermi perché volevo usare r.js. Ho appena finito di usare il costruttore di dojo, che è molto più potente in ogni caso, anche se è anche molto più complesso, che è quello che inizialmente cercavo di evitare. – EugeneZ

risposta

4

Dojo ha diversi plugin che si usi che non sono compatibili con il r.js costruttore/ottimizzatore. La cosa migliore da fare è registrare un problema su https://bugs.dojotoolkit.org per fare in modo che qualcuno aggiunga i ganci plugin necessari, in modo che questo possa essere risolto.

Un'alternativa è passare a utilizzare il generatore di dojo, ma non sembra creare codice che requirejs può utilizzare, quindi è necessario utilizzare anche il caricatore, non requirejs. (Dojo Builder usa un'opzione proprietaria? {cache:...} per fare le sue dipendenze invece di definire solo inlining, quindi non sono riuscito a trovare un modo per creare e caricare con requirejs).

Un altro lavoro (fino a quando il dojo risolve i plugin per essere compatibili) se si vuole stare con requirejs (come ho fatto io), è possibile escludere i file che usano questi plugin dojo dall'ottimizzazione e basta caricare quei file separatamente non ottimizzati . Quindi la maggior parte dei tuoi file può essere ottimizzata tranne quelli che usano questi plugin. Non è perfetto ma ti avvicina. Requirejs caricherà semplicemente la maggior parte dei file in modo ottimizzato e quindi recupererà solo quelli esclusi singolarmente in fase di runtime.

Per eseguire questa operazione, aggiungi le esclusioni r.js build.js per i file specifici che utilizzano i plug-in con errore. Quindi, dopo aver eseguito la build e ottenuto questo errore, aggiungi ai tuoi percorsi il file che sta usando il plugin, es. il secondo all'ultimo nella traccia dello stack.

Quindi aggiungere ai vostri r.js costruire opzioni

paths: { 
    'dojo/query': 'empty:', // this will exclude it from the build 

quindi eseguire di nuovo il vostro costruire e ripetere fino a quando non hanno ottenuto tutti gli altri file che errore.

Quando stavo cercando di costruire dgrid del dojo, ho finito con le seguenti esclusioni:

paths: { 
    // r.js having issues building these, the plugins are not 
    // compatible so let them load normally unoptimized 
    'dgrid/extensions/ColumnHider': 'empty:', 
    'put-selector/put': 'empty:' 
    'dojo/i18n': 'empty:', 
    'dojo/selector/_loader': 'empty:', 
    'dojo/query': 'empty:', 
    'dgrid/extensions/ColumnResizer': 'empty:', 
    'dgrid/List': 'empty:', 
    'xstyle/css': 'empty:' 

L'elenco può variare in base a ciò che si sta utilizzando.

Quindi basta avere questi file (e le loro dipendenze) disponibili durante l'esecuzione e requirejs li caricherà come fa in fase di sviluppo. Quindi almeno la maggior parte dei tuoi file verrà caricata ottimizzata da un file, quindi questi verranno caricati dopo.

Nota: chiedere al dojo di rendere i plugin compatibili con r.js builder/optimizer è la soluzione definitiva, quindi non è necessario eseguire questa operazione. Quindi, anche se usi questo lavoro, per favore aggiungi un problema al dojo in modo che questo possa essere risolto una volta per tutte. Indica tutti i file che hai dovuto escludere per aiutare gli sviluppatori a sapere cosa risolvere. Quindi pubblica qui un commento per gli altri a +1.

+1

Grazie, mi ha fatto un passo avanti. Seguirò il dojo bug tracker quando ne avrò la possibilità. Tuttavia, sto ancora ricevendo errori: 'Errore: TypeError: Impossibile leggere la proprietà' normalize 'of undefined' su r.js: 1193: 35. Quando rimuovo la dipendenza del modulo specificato dal plugin, l'errore per quel modulo scompare ma è ancora presente per il modulo successivo con una dipendenza da plugin. – EugeneZ

+0

Selezionare questa risposta perché, in definitiva, Jeff ha ragione sul fatto che i plugin Dojo non sono ancora compatibili con il builder RequireJS. La mia soluzione, tuttavia, consisteva nell'usare il compito [grunt-dojo] (https://github.com/phated/grunt-dojo) per eseguire invece la mia dojo build. – EugeneZ

Problemi correlati