Posty oznaczone etykietą javascript

TypeScript w praktyce

Drodzy webdeveloperzy!

Proszę, przestańcie tworzyć oprogramowanie webowe w TypeScript!

Natywnym językiem programowania dla webdevelopmentu jest implementacja EcmaScriptu w postaci Javascriptu. Kod generowany przez kompilator TypeScriptu jest zły, nieoptymalny, przypomina sieczkę generowaną przez GWT (tam: Java->JavaScript). Sam proces kompilacji jest czymś zupełnie zbędnym (TS -> kompilacja -> JS -> interpretacja -> wykonanie). To generuje koszt, jest bezzasadnym utrudnieniem. Źródła są niemodyfikowalne bez znajomości TypeScriptu, który jest zbędny przy tworzeniu bibliotek i produktów javascriptowych o przeznaczeniu webowym.

Używajcie TypeScript tam, gdzie jest on zasadny - we własnych projektach, w swoim Visual Studio, w rozszerzeniach do swoich projektów lub ogólnie projektów "niewebowych". Tam, gdzie efekt prac jest kodem wykonywanym przez przeglądarki webowe, stosujcie JavaScript.

Programując rozwiązania webowe w TypeScript popełniacie ogromny błąd.

RESTful JavaScript client w kwadrans

Próbowałem restful.js, próbowałem jQuery REST client, aż ostatecznie dałem sobie spokój. Dla mnie były jakieś trudne/ciężkie w użyciu. A czym powinien być REST client? Cienkim wrapperem na dowolnego klienta HTTP, który gada z dowolnym url-em.

Na własne potrzeby założyłem, że:

  • interfejs ma być banalnie prosty w użyciu
  • wystarczy obsługa tylko content type application/json
  • ma być obsługa nagłówków, także defaultowych (żeby się nie powtarzać)
  • dozwolona jest zależność od jQuery (można się tego względnie łatwo wyzbyć)

Powstał prototyp:

var RestAPI = function(url, params) {
    var absoluteUrlPattern = /^https?:\/\//i,
        self=this,
        params = params || {};

    this.defaultHeaders = params.headers || {};
    this.url = url;

    function isAbsoluteUrl(url) {
        return absoluteUrlPattern.test(url);
    }

    function resourceToUrl(resource) {
        resource = resource || '';
        if(isAbsoluteUrl(resource)) {
            return resource;
        } else {
            return self.url+'/'+resource;
        }
    }

    function makeResponseObject(jqXhr, data) {
        var headers = {},
            headersList = jqXhr.getAllResponseHeaders().split('\r\n');
        $.each(headersList, function(i, headerStr) {
            var headerTuple = headerStr.split(': ');
            if(headerTuple[0]) {
                headers[headerTuple[0].toLowerCase()] = headerTuple[1];
            }
        });
        return {
            status: jqXhr.status,
            statusText: jqXhr.statusText,
            headers: headers,
            data: data 
        };
    }

    function doMethod(type, resource, data, headers) {
        var dfr = $.Deferred(),
            completeHeaders = $.extend({}, self.defaultHeaders, headers);

        $.ajax({
            url: resourceToUrl(resource),
            type: type,
            dataType: 'json',
            contentType: 'application/json',
            headers: completeHeaders,
            data: typeof(data)!=='undefined' && data!==null ? JSON.stringify(data) : null
        }).then(function(respData,respStatus,jqXhr) {
            dfr.resolve(respData, makeResponseObject(jqXhr, respData));
        }, function(jqXhr) {
            dfr.reject(makeResponseObject(jqXhr));
        });
        return dfr.promise();
    };


    this.get = function(resource, params, headers) {
        return doMethod('GET', resource, params, headers);
    }

    this.post = function(resource, payload, headers) {
        return doMethod('POST', resource, payload, headers);
    }

    this.put = function(resource, payload, headers) {
        return doMethod('PUT', resource, payload, headers);
    }

    this.patch = function(resource, payload, headers) {
        return doMethod('PATCH', resource, payload, headers);
    }

    this['delete'] = function(resource, headers) {
        return doMethod('DELETE', resource, null, headers);
    }

}

Działa? Działa, i to ciekawie.

Przykład - kto mnie śledzi na GitHub?

var github = new RestAPI('https://api.github.com');

github.get('users/marcinn').then(function(user) {
    github.get(user.followers_url).then(function(followers) {
        console.log(followers);
    });
});

Koniec, kropka. Prosto i na temat. Pobawta się sami na plunkr.

Jak kogo interesuje - publikuję na licencji "Brać! Mać..." oczywiście bez żadnej gwarancji. Wspomnijta w creditsach, że był taki Nowak, któremu to się klepać kodu nie chciało.

I jeszcze jedno - skoro się niektórzy chwalą filesize, to ja też podam:

  • Original: 2370 bytes
  • Gzipped: 764 bytes

Niech przebijają.


A AngularJS i jego ngResource albo nawet Restangular? Głupotą jest mapowanie REST na CRUD (albo stosowanie active record). W REST mamy dobrze określone VERBS. Nie ma wśród nich save. I tyle w temacie.

Angular w listopadowy wieczór

Nie mam słów i jestem zażenowany poziomem tzw. webdeveloperów portujących pluginy pod Angulara. Zdecydowana większość tego syfu to wrappery na ścierwo pisane pod jQuery. Tak, ścierwo, bo ta biblioteka sama w sobie jest jak lep na muchy, który przez swoją tandetną prostotę przyciąga tabuny amatorów przykładających swoje uszczerbione i ufajdane cegiełki do dziurawej budowli wznoszonej od lat przez nadęte i oderwane od rzeczywistości community open source. I mimo, że są perły pod jQuery, to tworząc soft pod Angulara używanie jQuery jest nadmiarem, naroślą, wrzodem na dupie i opuchlizną dręczącą i tak nie najlżejszy framework.

Jedyny sens jest portować tak, aby nie miały zależności od jQuery czy innych wynalazków tworzonych jako dodatek do HTML-a. Dlatego ciśną mi się na klawiaturę słowa: ludzie, przestańcie do cholery robić syf - albo robicie coś porządnie, albo nie róbcie tego wcale. Później mamy taki sektor IT, jaki sobie tworzymy. Poczytajta też Stack Overflow w tym temacie.

Czołem.

Django CSRF + AngularJS

Zapisuję w formie notatki, aby nikogo (w tym mnie) nie kusiło użycie csrf_exempt ;)

Dodanie obsługi CSRF w AngularJS 1.1.5+ polega na skonfigurowaniu nazw nagłówka i cookie:

.config(function($httpProvider) {
    $httpProvider.defaults.xsrfHeaderName = 'X-CSRFToken';
    $httpProvider.defaults.xsrfCookieName = 'csrftoken';
})

Doom w javascript (raycasting)

Raycasting to technika renderowania pseudo-trójwymiarowych scen. Była stosowana m.in. w Wolfenstein3D i Doom. Pamiętam czasy, kiedy Wolf wymagał odpowiedniego sprzętu, a moja Amiga ledwie zipiała wyświetlając sceny 3D. Z perspektywy czasu, po tak intensywnym rozwoju silników 3D, raycasting jest bardzo prymitywną techniką. Przeczuwam podskórnie, że jednak przeżyje swoją drugą młodość.

Minęło 18 lat (i tu uświadamiasz sobie pewne fakty ;), a silniki tego typu implementowane są w zwykłym JavaScript. Znalazłem w Google implementację Wolfa i Doom:

Swoją drogą druga pozycja (Wolf) używa tekstur bezpośrednio z Flickr.

Dla ciekawskich turorial - Pseudo3D with HTML5

Na koniec przykład we Flash (bardziej grywalny) - Wolfenstein3D