RequireJS wydaje się robić wewnętrznie coś, co buforuje wymagane pliki javascript. Jeśli dokonam zmiany w jednym z wymaganych plików, muszę zmienić nazwę pliku, aby zastosować zmiany.
Powszechna sztuczka polegająca na dodawaniu numeru wersji jako parametru zapytania na końcu nazwy pliku nie działa z wymaganiem <script src="jsfile.js?v2"></script>
To, czego szukam, to sposób, aby zapobiec wewnętrznemu buforowaniu skryptów wymaganych przez RequireJS bez konieczności zmiany nazwy moich plików skryptów przy każdej aktualizacji.
Rozwiązanie wieloplatformowe:
Teraz używam urlArgs: "bust=" + (new Date()).getTime()
do automatycznego pomijania pamięci podręcznej podczas programowania iurlArgs: "bust=v2"
do produkcji, w których zwiększam zakodowaną wersję num po uruchomieniu zaktualizowanego wymaganego skryptu.
Uwaga:
@Dustin Getz wspomniał w niedawnej odpowiedzi, że Narzędzia dla programistów Chrome upuszczą punkty przerwania podczas debugowania, gdy pliki JavaScript są ciągle odświeżane w ten sposób. Jednym obejściem jest napisaniedebugger;
kodu, aby uruchomić punkt przerwania w większości debuggerów Javascript.
Rozwiązania specyficzne dla serwera:
Aby znaleźć konkretne rozwiązania, które mogą lepiej działać w środowisku serwera, takie jak Węzeł lub Apache, zapoznaj się z niektórymi odpowiedziami poniżej.
źródło
Odpowiedzi:
RequireJS można skonfigurować tak, aby dodawał wartość do każdego adresu URL skryptu w celu pomijania pamięci podręcznej.
Z dokumentacji RequireJS ( http://requirejs.org/docs/api.html#config ):
Przykład, dodając „v2” do wszystkich skryptów:
Do celów programistycznych można zmusić RequireJS do ominięcia pamięci podręcznej przez dodanie znacznika czasu:
źródło
urlArgs: "bust=" + (new Date()).getTime()
do automatycznego pomijania pamięci podręcznej podczas programowania iurlArgs: "bust=v2"
do produkcji, gdzie zwiększam zakodowaną wersję num po uruchomieniu wymaganego zaktualizowanego skryptu.urlArgs: "bust=" + (+new Date)
urlArgs
.Nie używaj do tego urlArgs!
Wymagaj, aby skrypty ładowały się zgodnie z nagłówkami buforowania HTTP. (Skrypty ładowane są dynamicznie wstawiane
<script>
, co oznacza, że żądanie wygląda jak ładowany stary zasób).Podaj zasoby javascript z odpowiednimi nagłówkami HTTP, aby wyłączyć buforowanie podczas programowania.
Korzystanie z urlArgs wymaga, że wszelkie ustawione punkty przerwania nie zostaną zachowane podczas odświeżania; w końcu musisz umieścić
debugger
instrukcje w całym kodzie. Zły. UżywamurlArgs
do pomijania pamięci podręcznej podczas aktualizacji produkcji za pomocą git sha; wtedy mogę ustawić moje zasoby do buforowania na zawsze i zagwarantować, że nigdy nie będę mieć starych zasobów.W fazie projektowania wyśmiewam wszystkie żądania ajax ze złożoną konfiguracją mockjax , a następnie mogę obsługiwać moją aplikację w trybie tylko javascript z 10-liniowym serwerem python http z wyłączonym buforowaniem . Skalowałem to dla mnie do dość dużej „korporacyjnej” aplikacji z setkami spokojnych punktów końcowych usługi internetowej. Mamy nawet zakontraktowanego projektanta, który może pracować z naszą prawdziwą bazą kodu produkcyjnego, nie dając mu dostępu do naszego kodu zaplecza.
źródło
debugger;
w kodzie wszędzie tam, gdzie chcesz, aby punkt przerwania trwał.Rozwiązanie urlArgs ma problemy. Niestety nie możesz kontrolować wszystkich serwerów proxy, które mogą znajdować się między tobą a przeglądarką użytkownika. Niektóre z tych serwerów proxy można niestety skonfigurować tak, aby ignorowały parametry adresów URL podczas buforowania plików. Jeśli tak się stanie, niewłaściwa wersja pliku JS zostanie dostarczona użytkownikowi.
W końcu poddałem się i wdrożyłem własną poprawkę bezpośrednio w pliku wymaganej.js. Jeśli chcesz zmodyfikować swoją wersję biblioteki RequJS, to rozwiązanie może Ci pomóc.
Możesz zobaczyć łatkę tutaj:
https://github.com/jbcpollak/requirejs/commit/589ee0cdfe6f719cd761eee631ce68eee09a5a67
Po dodaniu możesz zrobić coś takiego w wymaganej konfiguracji:
Do zamiany użyj systemu kompilacji lub środowiska serwerowego
buildNumber
identyfikatorem wersji / wersją oprogramowania / ulubionym kolorem.Korzystanie wymaga takiego:
Spowoduje, że zażądam tego pliku:
W naszym środowisku serwerowym używamy reguł przepisywania adresów URL w celu usunięcia buildNumber i podania poprawnego pliku JS. W ten sposób nie musimy się martwić o zmianę nazwy wszystkich naszych plików JS.
Łatka zignoruje każdy skrypt, który określa protokół, i nie wpłynie na żadne pliki inne niż JS.
Działa to dobrze w moim środowisku, ale zdaję sobie sprawę, że niektórzy użytkownicy wolą prefiks niż sufiks, więc modyfikowanie mojego zatwierdzenia powinno być łatwe.
Aktualizacja:
W dyskusji na temat żądania ściągnięcia autor Requjs sugeruje, że może to działać jako rozwiązanie do prefiksu numeru wersji:
Nie próbowałem tego, ale implikuje to, że wymagałoby to następującego adresu URL:
Co może działać bardzo dobrze dla wielu osób, które mogą używać prefiksu.
Oto kilka możliwych duplikatów pytań:
Wymagaj buforowania JS i proxy
wymagania.js - Jak ustawić wersję wymaganych modułów jako część adresu URL?
źródło
/scripts/myLib/v1.1/
. Próbowałem dodać postfiks (lub prefiks) do moich nazw plików, prawdopodobnie dlatego, że właśnie to robi jquery, ale po pewnym czasie [leniwie i] zacząłem zwiększać numer wersji w folderze nadrzędnym. Wydaje mi się, że ułatwiło mi to utrzymanie na dużej stronie, ale teraz martwię się o koszmary przepisywania adresów URL.<script data-main="${pageContext.request.contextPath}/resources/scripts/main" src="${pageContext.request.contextPath}/resources/scripts/require.js"> <jsp:text/> </script> <script> require([ 'dev/module' ]); </script>
Zainspirowani pamięcią podręczną Expire na data.js main.j zaktualizowaliśmy nasz skrypt wdrażania o następujące zadanie ant:
Gdzie wygląda początek main.js:
źródło
W produkcji
urlArgs
może powodować problemy!Główny autor requjs woli nie używać
urlArgs
:[Mój styl.]
Postępuję zgodnie z tą radą.
W rozwoju
Wolę używać serwera, który inteligentnie buforuje pliki, które mogą się często zmieniać: serwer, który emituje
Last-Modified
i odpowiada zaIf-Modified-Since
pomocą 304, gdy jest to właściwe. Nawet serwer oparty na ekspresowym zestawie Node do obsługi plików statycznych robi to od razu po wyjęciu z pudełka. Nie wymaga robienia czegokolwiek z moją przeglądarką i nie psuje punktów przerwania.źródło
Wziąłem ten fragment z AskApache i umieściłem go w osobnym pliku .conf mojego lokalnego serwera Apache (w moim przypadku /etc/apache2/others/preventcaching.conf):
W przypadku programowania działa to dobrze bez konieczności zmiany kodu. Jeśli chodzi o produkcję, mogę użyć podejścia @ dvtoever.
źródło
Szybka poprawka dla programistów
Aby opracować, możesz po prostu wyłączyć pamięć podręczną w Chrome Dev Tools ( Wyłączanie pamięci podręcznej Chrome na potrzeby tworzenia witryn internetowych) ). Wyłączenie pamięci podręcznej ma miejsce tylko wtedy, gdy okno dialogowe narzędzi deweloperskich jest otwarte, więc nie musisz martwić się przełączaniem tej opcji za każdym razem, gdy przeglądasz regularnie.
Uwaga: Używanie „ urlArgs ” jest właściwym rozwiązaniem w produkcji, dzięki czemu użytkownicy otrzymują najnowszy kod. Utrudnia to jednak debugowanie, ponieważ chrome unieważnia punkty przerwania przy każdym odświeżeniu (ponieważ za każdym razem jest obsługiwany „nowy” plik).
źródło
Nie polecam używania „ urlArgs ” do pękania pamięci podręcznej przy użyciu RequireJS. Ponieważ nie rozwiązuje to w pełni problemu. Aktualizacja wersji no spowoduje pobranie wszystkich zasobów, nawet jeśli zmieniłeś tylko jeden zasób.
Aby poradzić sobie z tym problemem, zalecam używanie modułów Grunt, takich jak „filerev”, do tworzenia wersji nr. Ponadto napisałem niestandardowe zadanie w Gruntfile, aby zaktualizować wersję, gdziekolwiek jest to wymagane.
W razie potrzeby mogę udostępnić fragment kodu dla tego zadania.
źródło
Tak to robię w Django / Flask (można łatwo dostosować do innych języków / systemów VCS):
W twoim
config.py
(używam tego w python3, więc może być konieczne dostosowanie kodowania w python2)Następnie w swoim szablonie:
git rev-parse HEAD
raz po uruchomieniu aplikacji i zapisuje ją wconfig
obiekcieźródło
Dynamiczne rozwiązanie (bez urlArgs)
Istnieje proste rozwiązanie tego problemu, dzięki czemu można załadować unikalny numer wersji dla każdego modułu.
Możesz zapisać oryginalną funkcję requjs.load, nadpisać ją własną funkcją i ponownie przeanalizować zmodyfikowany adres URL do oryginalnego Requjs.load:
W naszym procesie budowania użyłem „gulp-rev”, aby zbudować plik manifestu ze wszystkimi wersjami wszystkich używanych modułów. Uproszczona wersja mojego zadania przełknięcia:
wygeneruje to moduł AMD z numerami wersji do moduleNames, który jest zawarty jako „oRevision” w main.js, w którym zastąpisz funkcję wymaganą.jload, jak pokazano wcześniej.
źródło
Jest to dodatek do zaakceptowanej odpowiedzi @phil mccull.
Korzystam z jego metody, ale automatyzuję ten proces, tworząc szablon T4 do uruchomienia przed kompilacją.
Polecenia przed kompilacją:
Szablon T4:
Wygenerowany plik:
Przechowuj w zmiennej przed załadowaniem pliku request.config.js:
Odwołanie w pliku wymaga.config.js:
źródło
W moim przypadku chciałem ładować ten sam formularz za każdym razem, gdy klikam, nie chciałem, aby zmiany wprowadzone w pliku pozostały. Może to nie dotyczyć dokładnie tego postu, ale może to być potencjalne rozwiązanie po stronie klienta bez ustawiania konfiguracji dla wymagania. Zamiast wysyłać zawartość bezpośrednio, możesz wykonać kopię wymaganego pliku i zachować nienaruszony rzeczywisty plik.
źródło