Development Tip

자바 스크립트의 코드 구성과 관련하여 일반적으로 인정되는 모범 사례

yourdevel 2020. 10. 3. 12:07
반응형

자바 스크립트의 코드 구성과 관련하여 일반적으로 인정되는 모범 사례 [닫힘]


jQuery와 같은 JavaScript 프레임 워크가 클라이언트 측 웹 애플리케이션을 더욱 풍부하고 기능적으로 만들면서 한 가지 문제를 발견하기 시작했습니다.

세상에서 이것을 어떻게 정리하고 있습니까?

  • 모든 핸들러를 한 자리에 놓고 모든 이벤트에 대한 함수를 작성 하시겠습니까?
  • 모든 기능을 래핑하는 함수 / 클래스를 만드시겠습니까?
  • 미친 듯이 작성하고 최선을 다하기를 바랍니다.
  • 포기하고 새로운 경력을 얻으시겠습니까?

jQuery에 대해 언급했지만 실제로는 일반적인 JavaScript 코드입니다. 줄에 줄이 쌓이기 시작하면 스크립트 파일을 관리하거나 원하는 것을 찾는 것이 더 어려워집니다. 내가 발견 한 가장 큰 문제점은 동일한 작업을 수행하는 방법이 너무 많다는 것입니다. 어떤 방법이 현재 일반적으로 허용되는 모범 사례인지 알기가 어렵습니다.

.js 파일을 나머지 애플리케이션만큼 멋지고 깔끔하게 유지하는 가장 좋은 방법에 대한 일반적인 권장 사항이 있습니까? 아니면 이것은 단지 IDE의 문제입니까? 거기에 더 나은 옵션이 있습니까?


편집하다

이 질문은 파일 구성이 아닌 코드 구성에 관한 것입니다. 파일 병합 또는 콘텐츠 분할에 대한 몇 가지 좋은 예가 있습니다.

내 질문은 : 실제 코드를 구성하는 현재 일반적으로 허용되는 모범 사례 방법은 무엇입니까? 페이지 요소와 상호 작용하고 서로 충돌하지 않는 재사용 가능한 코드를 생성하는 방법 또는 권장되는 방법은 무엇입니까?

어떤 사람들은 좋은 생각 인 네임 스페이스나열했습니다 . 페이지의 요소를보다 구체적으로 처리하고 코드를 체계적이고 깔끔하게 유지하는 다른 방법은 무엇입니까?


자바 스크립트에 네임 스페이스가 내장되어 있다면 훨씬 더 좋을 것 같지만, 여기에서 더스틴 디아즈가 설명하는 것과 같은 내용을 정리 하면 많은 도움이됩니다.

var DED = (function() {

    var private_var;

    function private_method()
    {
        // do stuff here
    }

    return {
        method_1 : function()
            {
                // do stuff here
            },
        method_2 : function()
            {
                // do stuff here
            }
    };
})();

나는 다른 "네임 스페이스"와 때로는 개별 클래스를 별도의 파일에 넣었습니다. 일반적으로 하나의 파일로 시작하고 클래스 또는 네임 스페이스가이를 보증 할 수있을만큼 커지면 파일을 자체 파일로 분리합니다. 제작을 위해 모든 파일을 결합하는 도구를 사용하는 것도 훌륭한 아이디어입니다.


HTML에 자바 스크립트를 포함하지 않으려 고합니다. 모든 코드는 클래스로 캡슐화되고 각 클래스는 자체 파일에 있습니다. 개발을 위해 각 js 파일을 포함하는 별도의 <script> 태그가 있지만 HTTP 요청의 오버 헤드를 줄이기 위해 프로덕션을 위해 하나의 더 큰 패키지로 병합됩니다.

일반적으로 각 응용 프로그램에 대해 단일 '주'js 파일이 있습니다. 따라서 "survey"애플리케이션을 작성하는 경우 "survey.js"라는 js 파일이 생겼을 것입니다. 여기에는 jQuery 코드의 진입 점이 포함됩니다. 인스턴스화하는 동안 jQuery 참조를 만든 다음 개체에 매개 변수로 전달합니다. 이는 자바 스크립트 클래스가 '순수'하고 CSS ID 또는 클래스 이름에 대한 참조를 포함하지 않음을 의미합니다.

// file: survey.js
$(document).ready(function() {
  var jS = $('#surveycontainer');
  var jB = $('#dimscreencontainer');
  var d = new DimScreen({container: jB});
  var s = new Survey({container: jS, DimScreen: d});
  s.show();
});

또한 가독성을 위해 명명 규칙이 중요하다고 생각합니다. 예 : 모든 jQuery 인스턴스 앞에 'j'를 추가합니다.

위의 예에는 DimScreen이라는 클래스가 있습니다. (이렇게하면 화면이 어두워지고 경고 상자가 표시된다고 가정합니다.) 화면을 덮도록 확대 할 수있는 div 요소가 필요하고 경고 상자를 추가해야하므로 jQuery 개체를 전달합니다. jQuery는 플러그인 개념을 가지고 있지만 실질적인 장점없이 제한적인 것처럼 보였습니다 (예 : 인스턴스가 영구적이지 않고 액세스 할 수 없음). 따라서 DimScreen 클래스는 jQuery를 사용하는 표준 자바 스크립트 클래스입니다.

// file: dimscreen.js
function DimScreen(opts) { 
   this.jB = opts.container;
   // ...
}; // need the semi-colon for minimizing!


DimScreen.prototype.draw = function(msg) {
  var me = this;
  me.jB.addClass('fullscreen').append('<div>'+msg+'</div>');
  //...
};

이 접근 방식을 사용하여 상당히 복잡한 응용 프로그램을 만들었습니다.


개발을 위해 스크립트를 별도의 파일로 나눈 다음 "릴리스"버전을 만들어 모두 함께 넣고 YUI Compressor 또는 이와 유사한 것을 실행할 수 있습니다.


이전 게시물에서 영감을 받아 WysiHat (changelog에서 언급 한 RTE)와 함께 배포 된 Rakefile공급 업체 디렉토리 의 복사본을 만들고 JSLint를 사용한 코드 검사 YUI Compressor를 사용한 축소 를 포함하도록 몇 가지 수정을했습니다 .

아이디어는 Sprockets (WysiHat에서 제공)를 사용하여 여러 JavaScript를 하나의 파일로 병합하고, 병합 된 파일의 구문을 JSLint로 확인하고 배포하기 전에 YUI Compressor로 축소하는 것입니다.

전제 조건

  • 자바 런타임
  • 루비와 레이크 젬
  • JAR을 Classpath 에 넣는 방법을 알아야합니다.

이제 해

  1. Rhino를 다운로드 하고 JAR ( "js.jar")을 클래스 경로에 넣습니다.
  2. YUI Compressor를 다운로드 하고 JAR (build / yuicompressor-xyz.jar)을 클래스 경로에 넣습니다.
  3. WysiHat을 다운로드 하고 "vendor"디렉토리를 JavaScript 프로젝트의 루트에 복사합니다.
  4. Rhino 용 JSLint를 다운로드 하여 "vendor"디렉토리에 넣습니다.

이제 JavaScript 프로젝트의 루트 디렉토리에 "Rakefile"이라는 파일을 만들고 여기에 다음 내용을 추가합니다.

require 'rake'

ROOT            = File.expand_path(File.dirname(__FILE__))
OUTPUT_MERGED   = "final.js"
OUTPUT_MINIFIED = "final.min.js"

task :default => :check

desc "Merges the JavaScript sources."
task :merge do
  require File.join(ROOT, "vendor", "sprockets")

  environment  = Sprockets::Environment.new(".")
  preprocessor = Sprockets::Preprocessor.new(environment)

  %w(main.js).each do |filename|
    pathname = environment.find(filename)
    preprocessor.require(pathname.source_file)
  end

  output = preprocessor.output_file
  File.open(File.join(ROOT, OUTPUT_MERGED), 'w') { |f| f.write(output) }
end

desc "Check the JavaScript source with JSLint."
task :check => [:merge] do
  jslint_path = File.join(ROOT, "vendor", "jslint.js")

  sh 'java', 'org.mozilla.javascript.tools.shell.Main',
    jslint_path, OUTPUT_MERGED
end

desc "Minifies the JavaScript source."
task :minify => [:merge] do
  sh 'java', 'com.yahoo.platform.yui.compressor.Bootstrap', '-v',
    OUTPUT_MERGED, '-o', OUTPUT_MINIFIED
end

모든 것을 올바르게 수행했다면 콘솔에서 다음 명령을 사용할 수 있어야합니다.

  • rake merge -다른 JavaScript 파일을 하나로 병합
  • rake check-코드 구문 확인 ( 기본 작업이므로 간단히 입력 할 수 있음 rake)
  • rake minify -JS 코드의 축소 버전 준비

소스 병합시

JavaScript 전처리 기인 Sprockets를 사용하여 require다른 JavaScript 파일을 포함 (또는 ) 할 수 있습니다. 다음 구문을 사용하여 초기 파일 ( "main.js"라는 이름의 다른 스크립트를 포함하지만 Rakefile에서 변경할 수 있음) :

(function() {
//= require "subdir/jsfile.js"
//= require "anotherfile.js"

    // some code that depends on included files
    // note that all included files can be in the same private scope
})();

그리고...

자동화 된 단위 테스트를 설정하려면 WysiHat과 함께 제공된 Rakefile을 살펴보십시오. 좋은 물건 :)

그리고 이제 대답을 위해

이것은 원래의 질문에 아주 잘 대답하지 않습니다. 저도 알고 있고 미안하지만 다른 사람이 엉망인 상태를 정리하는 데 도움이되기를 바라기 때문에 여기에 게시했습니다.

문제에 대한 나의 접근 방식은 가능한 한 많은 객체 지향 모델링을 수행하고 구현을 다른 파일로 분리하는 것입니다. 그런 다음 핸들러는 가능한 한 짧아야합니다. 와 예 List싱글도 좋은 것입니다.

그리고 네임 스페이스는 ... 더 깊은 객체 구조로 모방 될 수 있습니다.

if (typeof org === 'undefined') {
    var org = {};
}

if (!org.hasOwnProperty('example')) {
    org.example = {};
}

org.example.AnotherObject = function () {
    // constructor body
};

저는 모조품을 좋아하지는 않지만 전역 범위에서 벗어나려는 개체가 많은 경우 유용 할 수 있습니다.


코드 조직은 규칙 및 문서 표준의 채택을 요구합니다.
1. 실제 파일의 네임 스페이스 코드;

Exc = {};


2.이 네임 스페이스의 그룹 클래스 javascript;
3. 실제 개체를 나타내는 프로토 타입 또는 관련 함수 또는 클래스를 설정합니다.

Exc = {};
Exc.ui = {};
Exc.ui.maskedInput = function (mask) {
    this.mask = mask;
    ...
};
Exc.ui.domTips = function (dom, tips) {
    this.dom = gift;
    this.tips = tips;
    ...
};


4. 코드를 개선하기 위해 규칙을 설정합니다. 예를 들어, 객체 유형의 클래스 속성에서 모든 내부 함수 또는 메소드를 그룹화합니다.

Exc.ui.domTips = function (dom, tips) {
    this.dom = gift;
    this.tips = tips;
    this.internal = {
        widthEstimates: function (tips) {
            ...
        }
        formatTips: function () {
            ...
        }
    };
    ...
};


5. 네임 스페이스, 클래스, 메서드 및 변수를 문서화합니다. 필요한 경우 일부 코드 (일부 FI 및 Fors는 일반적으로 코드의 중요한 논리를 구현 함)에 대해서도 논의합니다.

/**
  * Namespace <i> Example </i> created to group other namespaces of the "Example".  
  */
Exc = {};
/**
  * Namespace <i> ui </i> created with the aim of grouping namespaces user interface.
  */
Exc.ui = {};

/**
  * Class <i> maskdInput </i> used to add an input HTML formatting capabilities and validation of data and information.
  * @ Param {String} mask - mask validation of input data.
  */
Exc.ui.maskedInput = function (mask) {
    this.mask = mask;
    ...
};

/**
  * Class <i> domTips </i> used to add an HTML element the ability to present tips and information about its function or rule input etc..
  * @ Param {String} id - id of the HTML element.
  * @ Param {String} tips - tips on the element that will appear when the mouse is over the element whose identifier is id <i> </i>.
  */
  Exc.ui.domTips = function (id, tips) {
    this.domID = id;
    this.tips = tips;
    ...
};


이것들은 단지 몇 가지 팁이지만 코드 구성에 큰 도움이되었습니다. 성공하려면 규율이 있어야합니다!


좋은 OO 디자인 원칙과 디자인 패턴을 따르는 것은 코드를 유지하고 이해하기 쉽게 만드는 데 큰 도움이됩니다. 그러나 내가 최근에 발견 한 가장 좋은 것 중 하나는 게시 / 구독이라고도하는 신호와 슬롯입니다. 한 번 봐 가지고 http://markdotmeyer.blogspot.com/2008/09/jquery-publish-subscribe.html 간단한 jQuery를 구현합니다.

이 아이디어는 GUI 개발을 위해 다른 언어에서도 잘 사용됩니다. 코드 어딘가에서 중요한 일이 발생하면 다른 개체의 다른 메서드가 구독 할 수있는 전역 합성 이벤트를 게시합니다. 이것은 물체의 우수한 분리를 제공합니다.

Dojo (및 Prototype?)에는이 기술의 내장 버전이 있다고 생각합니다.

신호 및 슬롯이란 무엇입니까?를 참조하십시오 .


이전 작업에서 Javascript 모듈 패턴 을 Ext JS 응용 프로그램에 성공적으로 적용 할 수있었습니다 . 멋지게 캡슐화 된 코드를 만드는 간단한 방법을 제공했습니다.


Dojo는 처음부터 모듈 시스템을 가졌습니다. 사실 그것은 모든 것을 하나로 묶는 접착제 인 Dojo의 초석으로 간주됩니다.

Dojo 모듈 사용은 다음 목표를 달성합니다.

  • Dojo 코드 및 사용자 정의 코드 ( dojo.declare())에 대한 네임 스페이스 — 전역 공간을 오염시키지 않고 다른 라이브러리와 공존하며 사용자의 Dojo 인식 코드가 아닙니다.
  • 이름별로 동기식 또는 비동기식으로 모듈로드 ( dojo.require()).
  • 모듈 종속성을 분석하여 단일 파일 또는 상호 의존적 인 파일 그룹 (소위 레이어)을 생성하여 웹 애플리케이션에 필요한 것만 포함하는 사용자 지정 빌드입니다. 사용자 정의 빌드에는 Dojo 모듈 및 고객 제공 모듈도 포함될 수 있습니다.
  • Dojo 및 사용자 코드에 대한 투명한 CDN 기반 액세스. AOL과 Google 모두 이러한 방식으로 Dojo를 제공하지만 일부 고객은 맞춤형 웹 애플리케이션에도이를 수행합니다.

JavasciptMVC를 확인하십시오 .

다음을 수행 할 수 있습니다.

  • 코드를 모델,보기 및 컨트롤러 레이어로 분할합니다.

  • 모든 코드를 단일 프로덕션 파일로 압축

  • 코드 자동 생성

  • 단위 테스트 생성 및 실행

  • 그리고 훨씬 더 ...

무엇보다도 jQuery를 사용하므로 다른 jQuery 플러그인도 활용할 수 있습니다.


제 상사는 여전히 그들이 모듈 식 코드 (C 언어)를 작성했을 때에 대해 말하고, 요즘 코드가 얼마나 엉망인지 불평합니다! 프로그래머는 모든 프레임 워크에서 어셈블리를 작성할 수 있다고합니다. 코드 구성을 극복하기위한 전략은 항상 있습니다. 기본적인 문제는 자바 스크립트를 장난감으로 취급하고 배우려고하지 않는 사람들에게 있습니다.

제 경우에는 적절한 init_screen ()을 사용하여 UI 테마 또는 애플리케이션 화면 기반으로 js 파일을 작성합니다. 적절한 ID 명명 규칙을 사용하여 루트 요소 수준에서 네임 스페이스 충돌이 없는지 확인합니다. 눈에 거슬리지 않는 window.load ()에서 나는 최상위 ID를 기반으로 사물을 묶습니다.

모든 개인 메서드를 숨기기 위해 자바 스크립트 클로저와 패턴을 엄격하게 사용합니다. 이렇게 한 후에는 속성 / 함수 정의 / 변수 정의가 충돌하는 문제에 직면하지 않았습니다. 그러나 팀과 함께 작업 할 때 동일한 엄격함을 적용하는 것은 종종 어렵습니다.


아무도 MVC 프레임 워크를 언급하지 않았다는 것에 놀랐습니다. 저는 Backbone.js사용하여 코드를 모듈화하고 분리 해 왔으며 매우 귀중했습니다.

이런 종류의 프레임 워크는 꽤 많이 있으며 대부분은 매우 작습니다. 내 개인적인 의견은 화려한 UI를 위해 jQuery 몇 줄 이상을 작성하거나 풍부한 Ajax 애플리케이션을 원한다면 MVC 프레임 워크가 당신의 삶을 훨씬 더 쉽게 만들어 준다는 것입니다.


"미친 것처럼 작성하고 최선을 다하기를 바라는가?", 저는 자바 스크립트 코드가 많은 거대한 애플리케이션 인 2 명의 개발자가 개발하고 유지하는 이와 같은 프로젝트를 보았습니다. 그 위에 생각할 수있는 모든 가능한 jquery 함수에 대해 다른 바로 가기가 있습니다. 클래스, 모듈, 네임 스페이스 및 전체 유니버스에 해당하는 jquery이므로 코드를 플러그인으로 구성 할 것을 제안했습니다. 하지만 상황은 훨씬 더 나빠졌습니다. 이제 그들은 프로젝트에 사용 된 3 줄의 코드 조합을 모두 대체하는 플러그인을 작성하기 시작했습니다. Personaly jQuery는 악마라고 생각하며 자바 스크립트가 많은 프로젝트에서는 사용하지 말아야합니다. 게으르고 어떤 식 으로든 코드를 구성하는 것을 생각하지 않도록 장려하기 때문입니다. 40 개의 체인화 된 jQuery 함수가있는 한 줄보다는 100 줄의 자바 스크립트를 읽고 싶습니다. 농담이 아닙니다). 대중적인 믿음과는 달리 자바 스크립트 코드를 네임 스페이스 및 클래스와 동일한 방식으로 구성하는 것은 매우 쉽습니다. 그것이 YUI와 Dojo가하는 일입니다. 원하는 경우 쉽게 자신을 굴릴 수 있습니다. YUI의 접근 방식이 훨씬 더 좋고 효율적이라고 생각합니다. 그러나 유용한 것을 작성하려면 YUI 명명 규칙을 보완하기 위해 스 니펫을 지원하는 멋진 편집기가 필요합니다.


화면에서 여러 번 인스턴스화 할 필요가없는 모든 것에 대한 싱글 톤, 다른 모든 것에 대한 클래스를 만듭니다. 그리고 그들 모두는 동일한 파일의 동일한 네임 스페이스에 배치됩니다. 모든 것이 주석 처리되고 UML 상태 다이어그램으로 설계되었습니다. 자바 스크립트 코드는 HTML이 없어서 인라인 자바 스크립트가 없으며 jquery를 사용하여 브라우저 간 문제를 최소화하는 경향이 있습니다.


저의 마지막 프로젝트 인 Viajeros.com에서는 몇 가지 기술을 조합하여 사용했습니다. 웹 앱을 구성하는 방법을 모르겠습니다. Viajeros는 잘 정의 된 섹션이있는 여행자를위한 소셜 네트워킹 사이트이므로 각 지역의 코드를 쉽게 구분할 수 있습니다.

사이트 섹션에 따라 네임 스페이스 시뮬레이션과 모듈의 지연로드를 사용합니다. 각 페이지로드에서 "vjr"객체를 선언하고 항상 공통 함수 집합 (vjr.base.js)을로드합니다. 그런 다음 각 HTML 페이지는 간단한 방법으로 필요한 모듈을 결정합니다.

vjr.Required = ["vjr.gallery", "vjr.comments", "vjr.favorites"];

Vjr.base.js는 서버에서 각각을 gzip으로 압축하여 실행합니다.

vjr.include(vjr.Required);
vjr.include = function(moduleList) {
  if (!moduleList) return false;
  for (var i = 0; i < moduleList.length; i++) {
    if (moduleList[i]) {
      $.ajax({
        type: "GET", url: vjr.module2fileName(moduleList[i]), dataType: "script"
      });
    }
  }
};

모든 "모듈"에는 다음 구조가 있습니다.

vjr.comments = {}

vjr.comments.submitComment = function() { // do stuff }
vjr.comments.validateComment = function() { // do stuff }

// Handlers
vjr.comments.setUpUI = function() {
    // Assign handlers to screen elements
}

vjr.comments.init = function () {
  // initialize stuff
    vjr.comments.setUpUI();
}

$(document).ready(vjr.comments.init);

제한된 Javascript 지식을 감안할 때 이것을 관리하는 더 좋은 방법이 있어야한다는 것을 알고 있지만 지금까지는 우리에게 잘 작동합니다.


Jquery 중심의 NameSpace 방식으로 코드를 구성하면 다음과 같이 보일 수 있으며 Prototype, Ext와 같은 다른 Javascript API와 충돌하지 않습니다.

<script src="jquery/1.3.2/jquery.js" type="text/javascript"></script>
<script type="text/javascript">

var AcmeJQ = jQuery.noConflict(true);
var Acme = {fn: function(){}};

(function($){

    Acme.sayHi = function()
    {
        console.log('Hello');
    };

    Acme.sayBye = function()
    {
        console.log('Good Bye');
    };
})(AcmeJQ);

// Usage
//          Acme.sayHi();
// or
// <a href="#" onclick="Acme.sayHi();">Say Hello</a>


</script>

도움이 되었기를 바랍니다.


OO + MVC의 좋은 교장은 복잡한 자바 스크립트 앱을 관리하는 데 확실히 먼 길을 갈 것입니다.

기본적으로 내 앱과 자바 스크립트를 다음과 같은 친숙한 디자인으로 구성하고 있습니다 (데스크톱 프로그래밍 시절부터 Web 2.0까지 거슬러 올라감).

JS OO 및 MVC

이미지의 숫자 값에 대한 설명 :

  1. 내 애플리케이션의보기를 나타내는 위젯. 이것은 확장 가능하고 깔끔하게 분리되어 MVC가 내 위젯을 스파게티 코드로 바꾸는 것보다 달성하려고하는 좋은 분리를 가져야합니다 (웹 앱에서 큰 Javascript 블록을 HTML에 직접 넣는 것과 동일 함). 각 위젯은 다른 위젯에 의해 생성 된 이벤트를 수신하여 다른 위젯을 통해 통신하므로 관리 할 수없는 코드로 이어질 수있는 위젯 간의 강력한 결합을 줄입니다 (스크립트 태그의 전역 함수를 가리키는 모든 곳에 onclick을 추가 한 날을 기억하십니까? Urgh ...).
  2. 위젯에 채우고 서버로 앞뒤로 전달하려는 데이터를 나타내는 개체 모델입니다. 데이터를 모델에 캡슐화함으로써 애플리케이션은 데이터 형식에 구애받지 않습니다. 예를 들어, 당연히 Javascript에서는 이러한 객체 모델이 대부분 직렬화되고 JSON으로 역 직렬화되지만 서버가 통신을 위해 XML을 사용하는 경우 변경해야 할 것은 직렬화 / 역 직렬화 계층을 변경하는 것이며 반드시 모든 위젯 클래스를 변경할 필요는 없습니다. .
  3. 비즈니스 로직 및 서버와의 통신을 관리하는 컨트롤러 클래스 + 때때로 캐싱 계층. 이 계층은 서버에 대한 통신 프로토콜을 제어하고 필요한 데이터를 개체 모델에 넣습니다.
  4. 클래스는 해당 네임 스페이스에 깔끔하게 래핑됩니다. 나는 우리 모두가 자바 스크립트에서 글로벌 네임 스페이스가 얼마나 불쾌한 지 알고 있다고 확신합니다.

과거에는 파일을 자체 js로 분리하고 일반적인 관행을 사용하여 Javascript에서 OO 원칙을 만들었습니다. JS OO를 작성하는 방법에는 여러 가지가 있으며 모든 팀원이 반드시 동일한 접근 방식을 가지고있는 것은 아닙니다. 팀이 커짐에 따라 (제 경우에는 15 명 이상) Object Oriented Javascript에 대한 표준 접근 방식이 없기 때문에 이것은 복잡해집니다. 동시에 나는 내 자신의 프레임 워크를 작성하고 내가 해결 한 것보다 더 똑똑하다고 확신하는 일부 작업을 반복하고 싶지 않습니다.

jQuery는 Javascript Framework만큼 훌륭하고 좋아하지만 프로젝트가 커짐에 따라 특히 OO 연습을 표준화하기 위해 웹 앱에 대한 추가 구조가 필요합니다. 나 자신을 위해 몇 번의 실험 끝에 YUI3 Base 및 Widget ( http://yuilibrary.com/yui/docs/widget/http://yuilibrary.com/yui/docs/base/index.html ) 인프라가 정확히 내가 필요한 것. 내가 그것들을 사용하는 몇 가지 이유.

  1. 네임 스페이스 지원을 제공합니다. OO 및 코드의 깔끔한 구성에 대한 진정한 요구
  2. 클래스와 객체의 개념을 지원합니다.
  3. 클래스에 인스턴스 변수를 추가하는 표준화 수단을 제공합니다.
  4. 예쁘게 수업 연장에 대응
  5. 생성자와 소멸자를 제공합니다.
  6. 렌더링 및 이벤트 바인딩을 제공합니다.
  7. 기본 위젯 프레임 워크가 있습니다.
  8. 이제 각 위젯은 표준 이벤트 기반 모델을 사용하여 서로 통신 할 수 있습니다.
  9. 가장 중요한 것은 모든 엔지니어에게 Javascript 개발을위한 OO 표준을 제공한다는 것입니다.

많은 뷰와 달리 jQuery와 YUI3 중에서 반드시 선택할 필요는 없습니다. 이 둘은 평화롭게 공존 할 수 있습니다. YUI3는 복잡한 웹 앱에 필요한 OO 템플릿을 제공하지만 jQuery는 여전히 우리 팀에게 우리 모두가 좋아하고 친숙하게 된 사용하기 쉬운 JS Abstraction을 제공합니다.

YUI3를 사용하여 Base를 Model로 확장하는 클래스, Widget을 View로 확장하는 클래스, 필요한 로직 및 서버 측 호출을 수행하는 Controller 클래스가있는 클래스를 분리하여 MVC 패턴을 만들었습니다.

위젯은 이벤트 기반 모델을 사용하고 이벤트를 수신하고 미리 정의 된 인터페이스를 기반으로 필요한 작업을 수행하여 서로 통신 할 수 있습니다. 간단히 말해서 OO + MVC 구조를 JS에 넣는 것은 저에게 기쁨입니다.

면책 조항 일뿐입니다. 저는 Yahoo!에서 일하지 않습니다. 그리고 단순히 원래의 질문에서 제기 된 것과 동일한 문제에 대처하려는 건축가입니다. 누군가 동등한 OO 프레임 워크를 찾으면 이것도 작동 할 것이라고 생각합니다. 원칙적으로이 질문은 다른 기술에도 적용됩니다. OO Principles + MVC 프로그램을보다 쉽게 ​​관리 할 수 ​​있도록 도와 주신 모든 분들께 감사드립니다.


내가 사용하는 Dojo의 패키지 관리 ( dojo.requiredojo.provide) 및 (클래스 시스템을 dojo.declare별도의 파일로 내 수업 / 위젯을 모두 모듈화하는 것이 간단한 다중 상속을 허용). 이렇게하면 코드를 체계적으로 유지할 수있을뿐만 아니라 클래스 / 위젯을 지연 / 시간로드 할 수 있습니다.


며칠 전 37Signals의 직원 들은 RTE 컨트롤을 출시했습니다 . 그들은 일종의 전 처리기 명령을 사용하여 자바 스크립트 파일을 묶는 라이브러리를 만들었습니다.

그 이후로 JS 파일을 분리 한 다음 결국 하나로 병합했습니다. 그렇게하면 우려 사항을 분리 할 수 ​​있고 결국 파이프를 통과하는 파일이 하나만 있습니다 (gzipped, 그 이하도 아님).

템플릿에서 개발 모드에 있는지 확인하고 별도의 파일을 포함하고 프로덕션에있는 경우 최종 파일을 포함합니다 (사용자가 직접 "빌드"해야 함).


가짜 클래스를 만들고 의미있는 별도의 함수에 던져 질 수있는 모든 것이 그렇게되는지 확인하십시오. 또한 많은 주석을 달고 스파게티 코드를 작성하지 말고 모든 것을 섹션으로 유지하십시오. 예를 들어, 내 이상을 묘사하는 말도 안되는 코드. 분명히 실생활에서는 기본적으로 기능을 포함하는 많은 라이브러리를 작성합니다.

$(function(){
    //Preload header images
    $('a.rollover').preload();

    //Create new datagrid
    var dGrid = datagrid.init({width: 5, url: 'datalist.txt', style: 'aero'});
});

var datagrid = {
    init: function(w, url, style){
        //Rendering code goes here for style / width
        //code etc

        //Fetch data in
        $.get(url, {}, function(data){
            data = data.split('\n');
            for(var i=0; i < data.length; i++){
                //fetching data
            }
        })
    },
    refresh: function(deep){
        //more functions etc.
    }
};

상속 패턴을 사용하여 대규모 jQuery 애플리케이션을 구성합니다.


나는 이것이 아마도 DDD (Domain-Driven Design)와 관련이 있다고 생각합니다. 내가 작업중인 애플리케이션은 공식 API가 없지만 서버 측 코드 (클래스 / 파일 이름 등)를 통해 힌트를 제공합니다. 이것으로 무장하여 전체 문제 도메인에 대한 컨테이너로 최상위 개체를 만들었습니다. 그런 다음 필요한 곳에 네임 스페이스를 추가했습니다.

var App;
(function()
{
    App = new Domain( 'test' );

    function Domain( id )
    {
        this.id = id;
        this.echo = function echo( s )
        {
            alert( s );
        }
        return this;
    }
})();

// separate file
(function(Domain)
{
    Domain.Console = new Console();

    function Console()
    {
        this.Log = function Log( s )
        {
            console.log( s );
        }
        return this;
    }
})(App);

// implementation
App.Console.Log('foo');

JavaScript 조직의 경우 다음을 사용하고 있습니다.

  1. 모든 자바 스크립트를위한 폴더
  2. 페이지 수준 자바 스크립트는 페이지 이름이 같은 자체 파일을 가져옵니다. ProductDetail.aspx는 ProductDetail.js가됩니다.
  3. 라이브러리 파일의 javascript 폴더 안에 lib 폴더가 있습니다.
  4. 응용 프로그램 전체에서 사용하려는 lib 폴더에 관련 라이브러리 함수를 넣습니다.
  5. Ajax는 javascript 폴더 외부로 이동하여 자체 폴더를 가져 오는 유일한 javascript입니다. 그런 다음 두 개의 하위 폴더 클라이언트와 서버를 추가합니다.
  6. 클라이언트 폴더는 모든 .js 파일을 가져오고 서버 폴더는 모든 서버 측 파일을 가져옵니다.

이 작은 것을 사용하고 있습니다. JS 및 HTML 템플릿 모두에 대해 '포함'지시문을 제공합니다. 그것은 혼란을 완전히 없애줍니다.

https://github.com/gaperton/include.js/

$.include({
    html: "my_template.html" // include template from file...
})
.define( function( _ ){ // define module...
    _.exports = function widget( $this, a_data, a_events ){ // exporting function...
        _.html.renderTo( $this, a_data ); // which expands template inside of $this.

        $this.find( "#ok").click( a_events.on_click ); // throw event up to the caller...
        $this.find( "#refresh").click( function(){
            widget( $this, a_data, a_events ); // ...and update ourself. Yep, in that easy way.
        });
    }
});

당신은 사용할 수 있습니다 JQuery와 MX 는 모델, 뷰, 컨트롤러를 사용할 수 있도록 스크립트의 집합입니다 (javascriptMVC에서 사용 참조). 나는 그것을 프로젝트에서 사용했고 압축으로 인해 최소한의 스크립트 크기로 구조화 된 자바 스크립트를 만드는 것을 도왔습니다. 다음은 컨트롤러의 예입니다.

$.Controller.extend('Todos',{
  ".todo mouseover" : function( el, ev ) {
   el.css("backgroundColor","red")
  },
  ".todo mouseout" : function( el, ev ) {
   el.css("backgroundColor","")
  },
  ".create click" : function() {
   this.find("ol").append("<li class='todo'>New Todo</li>"); 
  }
})

new Todos($('#todos'));

뷰 및 모델 부분에 관심이없는 경우 jquerymx 의 컨트롤러 측만 사용할 수도 있습니다 .


당신의 질문은 작년 말에 저를 괴롭 혔습니다. 차이점은 개인 및 공개 방법에 대해 들어 본 적이없는 새로운 개발자에게 코드를 넘겨주는 것입니다. 나는 단순한 것을 만들어야했다.

최종 결과는 객체 리터럴을 jQuery로 변환하는 작은 (약 1KB) 프레임 워크였습니다. 구문은 시각적으로 더 쉽게 스캔 할 수 있으며 js가 정말 커지면 재사용 가능한 쿼리를 작성하여 사용 된 선택기,로드 된 파일, 종속 함수 등과 같은 항목을 찾을 수 있습니다.

여기에 작은 프레임 워크를 게시하는 것은 비실용적이므로 예제 가 포함 된 블로그 게시물을 작성했습니다 (첫 번째는 모험이었습니다!). 살펴 보셔도 좋습니다.

잠시 시간을내어 여기에있는 다른 분들에게 피드백을 주셔서 대단히 감사합니다!

FireFox는 객체 쿼리 예제에 대해 toSource ()를 지원하므로 권장됩니다.

건배!

아담


저는 Ben Nolan의 행동에서 영감을받은 커스텀 스크립트를 사용합니다 (슬프게도 더 이상 현재 링크를 찾을 수 없습니다). 이러한 이벤트 핸들러는 예를 들어 className 또는 Id 요소에 의해 트리거됩니다. 예:

Behaviour.register({ 
    'a.delete-post': function(element) {
        element.observe('click', function(event) { ... });
    },

    'a.anotherlink': function(element) {
        element.observe('click', function(event) { ... });
    }

});

전역 동작을 포함하는 라이브러리를 제외하고 대부분의 Javascript 라이브러리를 즉시 포함하고 싶습니다. 내가 사용하는 젠드 프레임 워크의 headScript () 자리 도우미 이를 위해,하지만 당신은 할 수 즉시 다른 스크립트를로드하는 자바 스크립트 사용Ajile 예를 들어.


서버 측 언어가 무엇인지 언급하지 않습니다. 또는 더 적절하게는 서버 측에서 사용중인 프레임 워크 (있는 경우)입니다.

IME, 나는 서버 측에서 모든 것을 구성하고 웹 페이지에 모두 표시합니다. 프레임 워크에는 모든 페이지가로드해야하는 JS뿐만 아니라 생성 된 마크 업과 함께 작동하는 JS 프래그먼트도 구성하는 작업이 제공됩니다. 이러한 조각은 일반적으로 두 번 이상 내 보내지 않기를 원하므로 해당 코드가 해당 문제를 처리 할 수 ​​있도록 프레임 워크로 추상화됩니다. :-)

자체 JS를 내 보내야하는 최종 페이지의 경우 일반적으로 생성 된 마크 업에 논리적 구조가 있음을 알 수 있습니다. 이러한 지역화 된 JS는 종종 그러한 구조의 시작 및 / 또는 끝에서 조합 될 수 있습니다.

이 중 어느 것도 효율적인 자바 스크립트 작성을 방해하지 않습니다! :-)


Lazy 필요할 때 필요한 코드를로드합니다. Google은 google.loader로 이와 같은 작업을 수행합니다.

참고 URL : https://stackoverflow.com/questions/247209/commonly-accepted-best-practices-around-code-organization-in-javascript

반응형