2017-07-05 16 views
8

Wydaje mi się, że wszystko ustawiłem poprawnie, ale dostaję dziwny problem z Webpakiem.

Rozważmy prosty app.ts plik:

'use strict'; 

import $ = require('jquery'); 
import 'jquery-ui'; 

$(function() { 
    $("#sortable").sortable(); 
}); 

Wszystko kompiluje grzywny, ale gdy strona prowadzona jest ona narzeka, że ​​Uncaught TypeError: $(...).sortable is not a function. (sortable jest funkcją jQuery UI).

Wszystko działa poprawnie, gdy zamiast tego łączę się z hostowaną wersją jQuery i jQuery na CDN, ale nie działa, gdy korzystam z modułów JS i pakietu Web Pack. Dlaczego to?

Dlaczego funkcja jQueryUI sortable() nie jest rozpoznawana?

+0

Możesz dołączyć tslint.json? Nadal nie jest jasne, dlaczego uważasz, że są one kompilowane w tej kolejności. –

+0

Rozważ pokazanie tego w swoim pytaniu. Podaj także, w jaki sposób kompilujesz kod (wersja TypeScript i flagi, jeśli je posiadasz). –

+0

Czy używasz System.JS do ładowania modułów CommonJS? Zobacz: https://stackoverflow.com/questions/44929021/import-json-file-typescript-keeps-saying-cannot-find-module/44929550#44929550 Jeśli użyjesz tego zamówienia, nie będzie już ważne, co rozwiązuje System.import wymagać. – JGFMK

Odpowiedz

9

Problemem jest to, że jQuery UI zazwyczaj automatycznie ściąga składników potrzebnych (dlatego działa, gdy jest połączony przez CDN), ale th at nie działa, gdy jest zaimportowany jako moduł (jak w pakiecie Webpack).

szczęście jak jQuery UI 1.11 można ręcznie wyciągnąć w jakichkolwiek dodatkowych elementów, które trzeba tak:

'use strict'; 

import $ = require('jquery'); 

require('jquery-ui'); 
require('jquery-ui/ui/widgets/sortable'); 
require('jquery-ui/ui/disable-selection'); 

itp

Oto niektóre official documentation to dalsze wyjaśnienia.

+0

Dziękuję, Spędziłem godzinę próbując zrobić jquery-ui z TS i widocznie to był faktyczny problem. –

2

używasz niewłaściwej składni importu ES6, ale nadal nie zadziałałaby, gdyby była właściwa. sortable nie został rozpoznany, ponieważ $ nie jest dostępny w module jquery-ui.

To rozwiązanie nie jest zoptymalizowane, ponieważ importuje się całość jquery-ui.

npm install --save jquery-ui-bundle

index.js

'use strict'; 

import 'jquery-ui-bundle'; 

$(function() { 
    $("#sortable").sortable(); 
}); 

WebPack

plugins: [ 
     new webpack.ProvidePlugin({ 
      $: 'jquery', 
      jQuery: 'jquery', 
      'window.jQuery': 'jquery', 
      'window.$': 'jquery' 
     }) 
    ] 
+1

'jquery-ui-bundle' nie wydaje się być utrzymywany przez zespół jquery-ui. Ponadto zalety importowania modułów za pomocą pakietu internetowego nie są dostępne podczas importowania kompletnego pakietu. –

+0

Tak, to najprostszy, ale nie najlepszy sposób. –

2

Ta odpowiedź jest jedynie podsumowaniem dwóch pomocny innych odpowiedzi: Answer 1, Answer 2

Po pierwsze, lepiej wiedzieć, że jquery-ui-dist i jquery-ui-bundle nie są utrzymywane przez zespół jquery-ui. Więc prawdopodobnie będziesz chciał tego unikać. Niemniej jednak, z jquery-ui w wersji 1.11 można wymagać/importować AMD, a od wersji 1.12 można użyć oficjalnego pakietu z npm.

Roztwór 1:
Korzystnym sposobem jest następnie importowania część jQuery interfejsu użytkownika, takich jak:

import 'jquery-ui/ui/widgets/draggable'; 

Jedyną wadą jest to, że jeśli wcześniej stosowane import 'jquery-ui', teraz muszą importuj poszczególne moduły, których chcesz użyć.Ale to jest lepsze, ponieważ będzie tylko pakować import, który naprawdę potrzebujesz.

Sprawdź 1.11 AMD support documentation i 1.12 npm documentation na swojej stronie.

Rozwiązanie 2:
Ale, jeśli z jakiegoś powodu chcesz używać jednego globalnego importu jQuery-UI, trzeba będzie dostosować WebPACK config:

pierwsze, zapewnić WebPack wie o jQuery aliasy:

... 
plugins: [ 
    new webpack.ProvidePlugin({ 
     '$':'jquery', 
     'jQuery':'jquery', 
     'window.jQuery':'jquery', 
     'global.jQuery': 'jquery' 
    }), 
... 

Następnie pomaga WebPack rozwiązywania jQuery-UI js lokalizację:

resolve : { 
    alias: { 
     // bind version of jquery-ui 
     "jquery-ui": "jquery-ui/jquery-ui.js",  
     // bind to modules; 
     modules: path.join(__dirname, "node_modules"), 

Następnie zapewnić jquery-ui jest załadowany tak szybko jak to możliwe (może podczas uruchamiania?)

var $ = require("jquery"), 
     require("jquery-ui"); 

Jeśli chcesz użyć motywu z jQuery UI, będziesz musiał ustawić CSS-ładowarka i odpowiednio do pliku. (Nie zapomnij zainstalować te ładowarki):

module: { 
    loaders: [ 
     { test: /\.css$/, loader: "style!css" }, 
     { test: /\.(jpe?g|png|gif)$/i, loader:"file" }, 

i poniżej ciebie importu jQuery i jQuery-ui po prostu dodają:

import 'modules/jquery-ui/themes/black-tie/jquery-ui.css'; 
import 'modules/jquery-ui/themes/black-tie/jquery-ui.theme.css'; 
Powiązane problemy