vanilla js를 사용하여 단일 페이지 응용 프로그램 구축

나는 이 틀과 그 틀의 변론을 자주 만난다.관찰자로서, 때로는 참여자로서, 때로는'기침'으로 변론을 시작하는 사람이 많다.이런 논쟁에서 가장 흔히 볼 수 있는 논쟁은 상대적으로 간단한 방법을 둘러싸고 일을 하거나 더 적은 코드를 작성해야 한다는 것이다.나는 사람들이 프레임워크를 사용하지 않고 vanilla js를 작성하고 프로젝트를 더 잘 구축하는 것에 대해 이야기하는 것을 보지 못했다.나를 놀라게 한 것은 많은 개발자들이 그들이 가장 좋아하는 프레임워크 이외의 것에 대해 아무것도 모르고 간단한 js 코드를 작성하는 것을 두려워한다는 것이다.만약 당신이 인코딩을 생계로 하기로 결정한다면, 당신은 어떻게 당신이 사용하는 플러그인의 구축 블록을 모를 수 있습니까?
과거에 많은 좋은 사람들이 이 일을 이야기하고 있었다.내가 가장 좋아하는 책은 zero framework manifestoLook ma, no frameworks이다.이러한 프레임워크 중 많은 것들이 좋은 마케팅 방식을 가지고 있다. 그 사이트나 개발자 블로그에서 최고급 기능이나 감지된 사용 장점을 보여주지만 나는 vanilla js를 사용하여 SPA를 구축하는 방법을 보여주는 사람을 많이 보지 못했다.그래서 저는 어떤 프레임워크도 사용하지 않고 개인 사이트를 스파로 재구성하기로 했습니다.나는 이 글이 네가 어떤 프레임워크도 사용하지 않은 상황에서 스스로 응용 프로그램을 개발하는 좋은 시작이 되기를 바란다.여기에서 인용한 모든 코드는 vinay20045.github.io repo 에서 얻을 수 있으며, this website 자체가 실시간 프레젠테이션이다.
설계
재구성하기 전에 내 사이트는 전형적인 PHP로 쓴 블로그였다.모든 페이지 요청은 서버를 왕복하여 모든 html 내용과 자산을 얻는 데 사용되며, 관리 컨트롤러 등이 있습니다. 재구성 기간에 제가 고려한 몇 가지 문제는...
  • 모든 게시물은 페이지가 불러오지 않습니다. 즉, SPA
  • 이어야 합니다.
  • 가격 인하 문법으로 작성한 게시물.
  • 블로그는 HTML+CSS+JS
  • 로만 작성 가능
  • github 페이지 또는 AWS S3
  • 에 호스팅됨
  • 이동이 편리해야 함
  • 이런 것들을 감안하면 블로그의 고위층 디자인은 이렇다.

    기본 구조
    어떤 응용 프로그램을 개발할 때, 당신이 주목해야 할 주요 문제 중 하나는 코드의 조직이다.여기에는 폴더 구조와 명명 규칙부터 선언과 정의에 이르는 모든 내용이 포함됩니다.내가 본 많은 개발자들은 2환행과 1환행을 논쟁하고 있지만, 그들은 보기나 템플릿에서 업무 논리를 사용하는 것에 동의한다.어쨌든, 일단 당신이 프로젝트를 위해 이 일을 한다면, 그것은 하나의 견본과 같아서, 당신의 미래의 프로젝트를 복제하고 확장하기 쉽다.
    블로그 응용 프로그램의 기본 구조는 다음과 같다.
    |-- assets
    |   |-- css -- All site styles go here
    |   |-- images -- All images used in the templates or page shell go here
    |   `-- js
    |       |-- config.js -- Environment specific config file
    |       |-- init.js -- Contains all instructions on load
    |       |-- controllers -- Business logic and view manipulation functions
    |       |-- templates -- context based reusable snippets of HTML
    |       |-- utils -- All internal and 3rd party libraries
    |       `-- views -- Views exposed to the user
    |-- index.html -- Page shell. Acts like a container. Actual content is populated based on route
    |-- posts -- All posts markdown files go here
    `-- uploads -- All assets used in posts go here
    
    경로
    그것은 깊이 있는 링크, 도서 표기, 더 좋은 검색 엔진 최적화를 촉진하기 위해 적당한 경로가 있는 것이 매우 중요해졌다.많은 기술은 루트에 사용할 수 있지만, 해시를 바탕으로 하는 루트는 매우 효과적이며, 실현하기 쉽다.프로그램을 불러올 때hashchange 이벤트에 따라 루트 함수를 등록합니다.
    라우팅 함수는 다음과 같이 utils library 의 일부입니다.
    router: function(route, data){
        route = route || location.hash.slice(1) || 'home';
    
        var temp = route.split('?');
        var route_split = temp.length;
        var function_to_invoke = temp[0] || false;
    
        if(route_split > 1){
            var params  = extract_params(temp[1]);
        }
    
        //fire away...
        if(function_to_invoke){
            views[function_to_invoke](data, params);
        }
    }
    
    extract_params 함수는 다음과 같다.
    var extract_params = function(params_string){
        var params = {};
        var raw_params = params_string.split('&');
    
        var j = 0;
        for(var i = raw_params.length - 1; i >= 0; i--){
            var url_params = raw_params[i].split('=');
            if(url_params.length == 2){
                params[url_params[0]] = url_params[1];
            }
            else if(url_params.length == 1){
                params[j] = url_params[0];
                j += 1;
            }
            else{
                //param not readable. pass.
            }
        }
    
        return params;
    };
    
    이벤트 탐지기가 init에 등록되었습니다.js...
    window.addEventListener(
        "hashchange", 
        function(){utils.router()}  // the router is part of the utils library
    );
    
    분석 컨트롤러
    컨트롤러가 업무 논리를 장악하고 있다.이 함수를 사용하여 보기를 조작할 수 있습니다.이러한 기능은 사용자에게 직접 공개되지 않습니다.UTIL에서 사용할 수 있는 템플릿 및 라이브러리만 액세스할 수 있습니다.그것들은 보기나 다른 컨트롤러에서 호출할 수 있다.
    홈 페이지를 담당하는 컨트롤러는 다음과 같다...
    controllers.home_page = function(data, params){
        var all_posts = JSON.parse(data);
    
        var posts_to_show = 3;
        var template_context = [];
        for (var i = 0; i < posts_to_show; i++){
            var post = all_posts[i];
            var item = {
                'link': '#post?'+post.post,
                'title': post.post.replace(/-/g, ' '),
                'snippet': post.snippet,
                'published_on': post.added_on,
            };
            template_context.push(item);
        }
    
        //get recent posts
        var recent_posts = templates.recent_posts(template_context);
    
        //get hello text
        var hello_text = templates.hello_text();
    
        var final_content = hello_text + recent_posts;
        utils.render(
            'page-content',
            final_content
        );    
    };
    
    분석 템플릿
    템플릿에는 실제 페이지 내용이 포함된 HTML 태그가 있습니다.전달된 일부 컨텍스트에 따라 함수를 원하는 HTML로 생성할 수 있을 때 재사용에 도움이 됩니다.템플릿의 모든 기능은 데이터 연결과 이벤트 등록 기술을 사용하여 컨트롤러를 호출하여 제공해야 합니다.내가 유일하게 허락하는 예외는 HREF다.
    홈페이지 헬로 부분의 템플릿은...
    templates.hello_text = function(data){
        var content = `
            <div id="hello_text">
                <h2>Hello...</h2>
                <img src="assets/images/Vinay.jpg" align="left" style="width:70px;">
                <p>
                    Thank you for visiting my blog. I am Vinay Kumar NP. I am a passionate techie...
                </p>
                <p>
                    I am currently working on a <a href="http://www.int.ai/" target = "_BLANK">startup</a> of my own. I have previously worked in various engineering leadership positions at...
                </p>
            </div>
        `;
    
        return content;
    };
    
    횡단면 뷰
    보기는 사용자에게 직접 공개되는 기능이다.i, 그것들은 공유기에서 호출되고 url의 일부분이다.보기 함수와 컨트롤러 사이에는 다른 차이가 없다.컨트롤러를 공개할 수도 있지만 모듈화에 해를 끼칠 수 있습니다.
    모든 게시물 보기 페이지는 다음과 같습니다.aax 호출을 통해posts 인덱스 파일을 가져온 후, 요청을loadshow_posts 컨트롤러에 전달하기만 하면 됩니다.
    views.all_posts = function(data, params){
        var api_stub = 'posts/index.json';
    
        utils.request(
            api_stub,
            'show_all_posts',
            'show_all_posts_error'
        );
    };
    
    API 요청 보내기
    이것은 모든 스파의 성배다.비록 나의 블로그는 외부api 호출을 위한 메커니즘이 필요하지 않다. 왜냐하면 나의 모든 게시물이 그 안에 위탁되어 있기 때문이다. 그러나 나는 이 개념을 설명하기 위해 그것을 썼다.요청 방법은api 메모리 루트, 리셋 함수, 파라미터를 가져오고 요청을 자극합니다.이것도 utils library의 일부분이다.(여기 CORS 조심하세요.)
    api 호출을 하는 함수는 다음과 같습니다...
    request: function(api_stub, success_callback, error_callback, callback_params){
        api_stub = api_stub || '';
        callback_params = callback_params || {};
    
        controllers.show_loader('page-content');
    
        var url = config.api_server + api_stub;
    
        var x = new XMLHttpRequest();
        x.onreadystatechange = function(){
            if (x.readyState == XMLHttpRequest.DONE) {
                if(x.status == 200){
                    controllers[success_callback](
                        x.responseText, 
                        callback_params
                    );
                }
                else{
                    controllers[error_callback](
                        x.status, 
                        callback_params
                    );
                }
            }
        };
        //other methods can be implemented here
        x.open('GET', url, true);
        x.send();
    }
    
    나는 아직 비교 기준 테스트를 할 기회가 없지만, 언뜻 보기에, 나의 모든 다시 그리는 것은 매우 빠르고, 거의 jank가 없다.처음 불러올 때 네트워크가 너무 많이 호출되었을 때, 나는 나의 다른 프로젝트를 위해python 기반의 사이트 패키지 프로그램을 구축할 계획이다. 일단 완성되면, 나는 그것을 발표할 것이다.
    됐어, 쉽지 않아??만약 당신이 여전히 믿지 않는다면, 브라우저를 시작하고, 나의 repo 를 복제하고, 필요한 변경 (설정, 템플릿 등) 을 한 후에 놀아라.나는 네가 자신의 js 응용 프로그램을 구축하기 시작할 뿐만 아니라 프레임워크도 없다고 확신한다.당신은 또한 개원 세계를 위해 더 많은 창고를 공헌할 것입니다...세계는 더 많은 사람들이 공유해야 한다:)
    나는 이미 모든 현대 브라우저 (IE 제외) 에서 이 코드를 테스트했는데, 그것은 아무런 문제가 없는 것 같다.자신의 응용 프로그램을 구축할 때 JSapi의 호환성을 주의하십시오. (예를 들어 저는 이전 브라우저와 호환되지 않는 반표시를 사용했습니다.)만약 코드에 어떤 오류나 문제가 있는 것을 발견하면 나에게 알려 주세요.
    이 글은 처음으로 나의 blog에 발표되었다

    좋은 웹페이지 즐겨찾기