2016-06-02 21 views
6
strona

Client I skrótową się ścieżki do modułów z SystemJS, jak toMapa ścieżek dla modułów węzła dla testów jednostkowych

var systemJsConfig = { 
    baseURL: "./", 
    defaultJSExtensions: true, 
    map: { 
     'root-components': 'applicationRoot/rootComponents' 
    } 
}; 

i tak require('root-components/foo'); będzie mapować do applicationRoot/rootComponents/foo.

Problem polega na tym, że jeśli uruchomię moduł z require('root-components/foo'); w grze Mocha, węzeł nie ma pojęcia, co oznacza ta ścieżka. Czy istnieje rozsądny sposób na wykonanie tego odwzorowania ścieżki w węźle?

Czy pełnomocnik jest do tego zdolny? Przeczytałem ich dokumenty, ale nie znalazłem nic, co by wskazywało na to.

Służy to wyłącznie do testowania urządzeń, więc jestem zadowolony z dowolnego rozwiązania wykorzystującego dowolne narzędzie firmowe.

+1

Czy widziałeś tę dyskusję? https://gist.github.com/branneman/8048520. Wierzę, że wymieniono kilka rozwiązań/hacków, które byłyby istotne dla tego, co próbujesz zrobić. – user2263572

+1

Dlaczego w testach używałeś innego mechanizmu ładującego moduł? Dlaczego nie skorzystać z SystemJs? –

+0

SystemJS służy do ładowania rzeczy w przeglądarce. Mocha działa w węźle. –

Odpowiedz

5

Jeśli twoje jedyne wymaganie jest tak proste, możesz utworzyć funkcję użyteczną, która zastępuje require.

Nowe wymaganie stosuje odwzorowanie do argumentu ścieżka, szuka modułu w nowej ścieżce i można opcjonalnie zastąpić moduły, które nie istnieją w zmapowanej ścieżce. Kod powinien wyglądać tak:

const oldRequire = require; 
require = (path) => { 
    try { 
     const mapped = oldRequire(path.replace('root-components/foo', 'applicationRoot/rootComponents/foo')); 
     if (!mapped) { 
      throw new Error('module not found in mapped directory'); 
     } 
     console.log('module resolved with mapping', path); 
     return mapped; 
    } catch (e) { 
     console.log('using old require without mapped path', path); 
     return oldRequire(path); 
    } 
}; 
+0

Myślę, że to jest to! Dzięki - nie wiem, dlaczego o tym nie myślałem :) –

1

Można zrobić moduł aliasingu wiele różnych sposobów as described in this gist, ale prostszym sposobem jest po prostu ustawić ścieżkę głównego wyjścia z NODE_PATH i go stamtąd:

Oto jak to wygląda ze zmienną NODE_PATH środowiska :

NODE_PATH=./src node src/server/index.js

Następnie we wszystkich plików, bez względu na to gdzie są one w hierarchii, będzie rozwiązać z katalogu ./src. Eliminuje to potrzebę korzystania z aliasów takich jak opisywane, ale zdaję sobie sprawę, że w twoim przypadku może wymagać przeniesienia/zmiany nazwy wielu plików.

przykład: require('root-components/foo'); =>./src/root-components/foo.js

+1

Dzięki za dobre informacje - wygląda na to, że wzorce w tym sensie są próbując rozwiązać inny problem, a mianowicie eliminując takie rzeczy jak '../../../../ foo/bar'. Ładowarki po stronie klienta po stronie klienta umożliwiają proste dostosowywanie ścieżki. Po prostu próbuję sprawdzić, czy jest jakiś hack, aby te niestandardowe ścieżki działały w węźle do testowania jednostkowego. Problem z ustawieniem globalnej NODE_PATH polega na tym, że wpłynie to na * wszystko * załadowane, nie tylko na kilka rzeczy znajdujących się w 'komponentach root'a ' –

1

Wariant 1 - Modyfikowanie NODE_PATH (nie zalecane)

Modyfikacja NODE_PATH obejmować ścieżkę modułu w powłoce przed uruchomieniem node.js.

exports NODE_PATH=./path/to/module:$NODE_PATH 

To nie jest świetnym rozwiązaniem, ponieważ wymaga etapu pre-launch i - ponieważ NODE_PATH zawiera wiele ścieżek - to nie zawsze jest jasne, gdzie moduł jest ładowany z i tam możliwość kolizji nazw .

Wariant 2 - Przenieś się do modułu zewnętrznego repo

Powiedzmy przenieść komponenty do osobnego repo „rootcomponents” dostępny na swoim profilu GitHub.

Następnie można go zainstalować bezpośrednio poprzez:

npm install --save github:arackaf/rootcomponents 

Następnie powinieneś być w stanie odwzorować źródła projektu do aliasu System.js.

var systemJsConfig = { 
    baseURL: "./", 
    defaultJSExtensions: true, 
    map: { 
     'root-components': 'github:arackaf/rootcomponents' 
    } 
}; 

Stamtąd powinien działać zgodnie z oczekiwaniami:

require('root-components/foo'); 

Opcja 3 - Załaduj moduł poprzez ścieżkę względną:

Opcja config.map jest tylko do mapowania zewnętrznych zależności do aliasów .

Jedną z prostych alternatyw jest podanie względnej ścieżki. Ścieżki krewnych są oparte na podstawieURL.

Na przykład, jeśli próbujesz obciążenia:

src/rootComponents/foo.js 

wymagać będzie:

require('./src/rootComponents/foo') 

Uwaga: To wszystko zakłada, że ​​sprawozdanie require() naśladują systemu .js wzory/reguły.

Inną możliwą opcją jest opcja System.paths[], która tworzy alias do ścieżki lokalnej. Nie mogę zweryfikować, jak/czy to zadziała (tj. Nigdy tego nie próbowałem), ale szczegóły można znaleźć: here

+0

Tak, niestety rozwiązaniem może być po prostu nie użycie' map'ed' ścieżki w dowolnym module, którego muszę użyć w Mocha. * westchnienie * –

+0

@AdamRackis Może checkout "System.config.packages' https://github.com/systemjs/systemjs/blob/master/docs/config-api.md#packages. Wygląda na to, że możesz określić commonjs jako format modułu i zamapować lokalne ścieżki na aliasy. –

+0

Oczywiście, ale mapowanie ścieżek lokalnych na aliasy jest źródłem mojego problemu - Węzeł nie rozumie tych aliasów i generuje błędy, gdy próbuję uruchomić te moduły za pośrednictwem Mocha. –

Powiązane problemy