JavaScript 코드 모듈 사용하기

  • 리비전 슬러그: JavaScript_code_modules/Using_JavaScript_code_modules
  • 리비전 제목: JavaScript 코드 모듈 사용하기
  • 리비전 아이디: 127300
  • 제작일시:
  • 만든이: Dyhan81
  • 현재 리비전인가요? 아니오
  • 댓글 33 words added, 5 words removed

리비전 내용

{{ Fx_minversion_header("3") }}

JavaScript code modules are a concept introduced in Firefox 3 (Gecko 1.9) and can be used for sharing code between different privileged scopes. Modules can also be used to create global JavaScript singletons that previously required using JavaScript XPCOM objects. A JavaScript code module is simply some JavaScript code located in registered location. The module is loaded into a specific JavaScript scope, such as XUL script or JavaScript XPCOM script, using Components.utils.import.

JavaScript 코드 모듈은 Firefox 3 (Gecko 1.9)부터 도입된 개념이며 서로 다른 권한이 부여된 유효 범위들 간에 코드를 공유하는데 사용될 수 있습니다. 모듈은 전역 JavaScript XPCOM 객체를 사용 해야만 만들 수 있었던 전역 JavaScript 싱글톤(singleton)을 생성하는데도 사용할 수 있습니다. JavaScript 코드 모듈은 간단히 말하자면 등록된 위치에 존재하는 몇 개의 JavaScript 코드라고 할 수 있습니다. 모듈은 특정 JavaScript 유효 범위 안에서 불러올 수 있습니다. 즉, XUL 스크립트 또는 JavaScript XPCOM 스크립트에 Components.utils.import를 사용해서 불러오면 됩니다.

A very simple JavaScript module looks like this:

JavaScript 모듈의 아주 간단한 예는 다음과 같습니다:

var EXPORTED_SYMBOLS = ["foo", "bar"];

function foo() {
  return "foo";
}

var bar = {
  name : "bar",
  size : "3"
};

var dummy = "dummy";

Notice that the module uses normal JavaScript to create functions, objects, constants and any other JavaScript type. The module also defines a special Array named EXPORTED_SYMBOLS. Any JavaScript item named in EXPORTED_SYMBOLS will be exported from the module and injected into the importing scope. For example:

함수, 객체, 상수 그리고 기타 JavaScript 타입을 생성하기 위해 모듈이 보통의 JavaScript를 사용함을 주목해주십시오. 또한 모듈은 EXPORTED_SYMBOLS 이라는 특수한 배열을 정의합니다. EXPORTED_SYMBOLS 이름이 붙여진 어떤 JavaScript 항목이라도 모듈에서 내보내져서 가져오기로 다시 유효 범위 안에 주입될 수 있습니다. 예를 들자면 다음과 같습니다:

Components.utils.import("resource://app/my_module.jsm");

alert(foo());         // displays "foo"
alert(bar.size + 3);  // displays "6"
alert(dummy);         // displays "dummy is not defined" because 'dummy' was not exported from the module

An extremely important behavior of Components.utils.import is that modules are cached when loaded and subsequent imports do not reload a new version of the module, but instead use the previously cached version. This means that a given module will be shared when imported multiple times. Any modifications to data, objects or functions will be available in any scope that has imported the module. For example, if the simple module were imported into two different JavaScript scopes, changes in one scope can be observed in the other scope.

Components.utils.import의 대단히 중요한 동작 특성으로서 염두 해두셔야 할 점은 모듈은 캐쉬되기 때문에 이후에 다시 가져오기 하더라도 모듈의 새로운 버전이 다시 가져오기 되지않고 기존에 캐쉬된 버전을 대신 사용 한다는 것입니다. 이 의미는 주어진 모듈은 여러 번 가져오기를 시도해도 한 번만 가져와서 해당 모듈을 공유하게 된다는 것입니다. 데이터, 객체 또는 함수의 변경점은 해당 모듈을 가져오기 한 모든 유효 범위에서 사용 가능하게 됩니다. 예를 들어, 만약 어떤 모듈이 두 개의 서로 다른 JavaScript 유효 범위에서 가져오기 되었다면, 한 유효 범위에서 일어난 변경이 다른 유효 범위에도 영향을 미쳐 해당 변경 사항을 볼 수 있게 됩니다.

유효 범위 1:

Components.utils.import("resource://app/my_module.jsm");

alert(bar.size + 3);  // displays "6"

bar.size = 10;

유효 범위 2:

Components.utils.import("resource://app/my_module.jsm");

alert(foo());         // displays "foo"
alert(bar.size + 3);  // displays "13"

This sharing behavior can be used to create singleton objects that can share data across windows and between XUL script and XPCOM components.

이와 같이 공유하는 특성은 싱글톤 객체, 즉 창들 간의 데이터 공유나 XUL 스크립트와 XPCOM 컴포넌트 사이의 데이터 공유를 가능하게 하는 객체를 생성하는데 사용될 수 있습니다.

{{ Note("Each scope which imports a module receives a by-value copy of the exported symbols in that module. Changes to the symbol\'s value will not propagate to other scopes.") }}

Scope 1:

Components.utils.import("resource://app/my_module.jsm");

bar = "foo";
alert(bar);         // displays "foo"

Scope 2:

Components.utils.import("resource://app/my_module.jsm");

alert(bar);         // displays "[object Object]"

The main effect of the by-value copy is global variables of simple types won't be shared across scopes. Always put variables in a wrapper class and export the wrapper (such as bar in the above example).

resource URL

When using Components.utils.import, you will notice that code modules are loaded using a "resource://" URL. The basic syntax of a resource URL is as follows:

resource://<alias>/<relative-path>/<file.js|jsm>

The <alias> is an alias to a location, usually a physical location relative to the application or XUL runtime. There are several pre-defined aliases setup by the XUL runtime:

  • app - Alias to the location of the XUL application.
  • gre - Alias to the location of the XUL runtime.

The <relative-path> can be multiple levels deep and is always relative to the location defined by the <alias>. The common relative path is "modules" and is used by XUL Runner and Firefox. Code modules are simple JavaScript files with a .js or .jsm extension.

The easiest way for extensions and XUL applications to add custom aliases is by registering an alias in the chrome manifest using a line like this:

resource aliasname uri/to/files/

For example, if the XPI for your foo extension includes a top-level modules/ directory containing the bar.js module (that is, the modules/ directory is a sibling to chrome.manifest and install.rdf), you could create an alias to that directory via the instruction:

resource foo modules/

(Don't forget the trailing slash!) You could then import the module into your JavaScript code via the statement:

Components.utils.import("resource://foo/bar.js");

Programmatically adding aliases

Custom aliases can be programmatically added to the resource URL as well. For example:

var ioService = Components.classes["@mozilla.org/network/io-service;1"]
                          .getService(Components.interfaces.nsIIOService);
var resProt = ioService.getProtocolHandler("resource")
                       .QueryInterface(Components.interfaces.nsIResProtocolHandler);

var aliasFile = Components.classes["@mozilla.org/file/local;1"]
                          .createInstance(Components.interfaces.nsILocalFile);
aliasFile.initWithPath("/some/absolute/path");

var aliasURI = ioService.newFileURI(aliasFile);
resProt.setSubstitution("myalias", aliasURI);

// assuming the code modules are in the alias folder itself, not a s

See also

 

{{ languages( { "es": "es/Usando_m\u00f3dulos_de_c\u00f3digo_JavaScript", "fr": "fr/Utilisation_de_modules_de_code_JavaScript", "ja": "ja/Using_JavaScript_code_modules", "pl": "pl/Zastosowanie_modu\u0142\u00f3w_JavaScript" } ) }}

리비전 소스

<p>{{ Fx_minversion_header("3") }}</p>
<p>JavaScript code modules are a concept introduced in Firefox 3 (Gecko 1.9) and can be used for sharing code between different privileged scopes. Modules can also be used to create global JavaScript singletons that previously required using JavaScript XPCOM objects. A JavaScript code module is simply some JavaScript code located in registered location. The module is loaded into a specific JavaScript scope, such as XUL script or JavaScript XPCOM script, using <a href="/en/Components.utils.import" title="en/Components.utils.import">Components.utils.import</a>.<br>
<br>
JavaScript 코드 모듈은 Firefox 3 (Gecko 1.9)부터 도입된 개념이며 서로 다른 권한이 부여된 유효 범위들 간에 코드를 공유하는데 사용될 수 있습니다. 모듈은 전역 JavaScript XPCOM 객체를 사용 해야만 만들 수 있었던 전역 JavaScript 싱글톤(singleton)을 생성하는데도 사용할 수 있습니다. JavaScript 코드 모듈은 간단히 말하자면 등록된 위치에 존재하는 몇 개의 JavaScript 코드라고 할 수 있습니다. 모듈은 특정 JavaScript 유효 범위 안에서 불러올 수 있습니다. 즉, XUL 스크립트 또는 JavaScript XPCOM 스크립트에 <a href="/en/Components.utils.import" title="en/Components.utils.import">Components.utils.import</a>를 사용해서 불러오면 됩니다.</p>
<p>A very simple JavaScript module looks like this:<br>
<br>
JavaScript 모듈의 아주 간단한 예는 다음과 같습니다:</p>
<pre class="brush: js">var EXPORTED_SYMBOLS = ["foo", "bar"];

function foo() {
  return "foo";
}

var bar = {
  name : "bar",
  size : "3"
};

var dummy = "dummy";
</pre>
<p>Notice that the module uses normal JavaScript to create functions, objects, constants and any other JavaScript type. The module also defines a special Array named <code>EXPORTED_SYMBOLS</code>. Any JavaScript item named in <code>EXPORTED_SYMBOLS</code> will be exported from the module and injected into the importing scope. For example:<br>
<br>
함수, 객체, 상수 그리고 기타 JavaScript 타입을 생성하기 위해 모듈이 보통의 JavaScript를 사용함을 주목해주십시오. 또한 모듈은 <code>EXPORTED_SYMBOLS 이라는 </code>특수한 배열을 정의합니다. <code>EXPORTED_SYMBOLS</code> 이름이 붙여진 어떤 JavaScript 항목이라도 모듈에서 내보내져서 가져오기로 다시 유효 범위 안에 주입될 수 있습니다. 예를 들자면 다음과 같습니다:</p>
<pre class="brush: js">Components.utils.import("resource://app/my_module.jsm");

alert(foo());         // displays "foo"
alert(bar.size + 3);  // displays "6"
alert(dummy);         // displays "dummy is not defined" because 'dummy' was not exported from the module
</pre>
<p>An extremely important behavior of <a href="/en/Components.utils.import" title="en/Components.utils.import">Components.utils.import</a> is that modules are cached when loaded and subsequent imports do not reload a new version of the module, but instead use the previously cached version. This means that a given module will be shared when imported multiple times. Any modifications to data, objects or functions will be available in any scope that has imported the module. For example, if the simple module were imported into two different JavaScript scopes, changes in one scope can be observed in the other scope.<br>
<br>
<a href="/en/Components.utils.import" title="en/Components.utils.import">Components.utils.import</a>의 대단히 중요한 동작 특성으로서 염두 해두셔야 할 점은 모듈은 캐쉬되기 때문에 이후에 다시 가져오기 하더라도 모듈의 새로운 버전이 다시 가져오기 되지않고 기존에 캐쉬된 버전을 대신 사용 한다는 것입니다. 이 의미는 주어진 모듈은 여러 번 가져오기를 시도해도 한 번만 가져와서 해당 모듈을 공유하게 된다는 것입니다. 데이터, 객체 또는 함수의 변경점은 해당 모듈을 가져오기 한 모든 유효 범위에서 사용 가능하게 됩니다. 예를 들어, 만약 어떤 모듈이 두 개의 서로 다른 JavaScript 유효 범위에서 가져오기 되었다면, 한 유효 범위에서 일어난 변경이 다른 유효 범위에도 영향을 미쳐 해당 변경 사항을 볼 수 있게 됩니다.</p>
<p>유효 범위 1:</p>
<pre class="brush: js">Components.utils.import("resource://app/my_module.jsm");

alert(bar.size + 3);  // displays "6"

bar.size = 10;
</pre>
<p>유효 범위 2:</p>
<pre class="brush: js">Components.utils.import("resource://app/my_module.jsm");

alert(foo());         // displays "foo"
alert(bar.size + 3);  // displays "13"
</pre>
<p>This sharing behavior can be used to create singleton objects that can share data across windows and between XUL script and XPCOM components.<br>
<br>
이와 같이 공유하는 특성은 싱글톤 객체, 즉 창들 간의 데이터 공유나 XUL 스크립트와 XPCOM 컴포넌트 사이의 데이터 공유를 가능하게 하는 객체를 생성하는데 사용될 수 있습니다.</p>
<p>{{ Note("Each scope which imports a module receives a by-value copy of the exported symbols in that module. Changes to the symbol\'s value will not propagate to other scopes.") }}</p>
<p>Scope 1:</p>
<pre class="brush: js">Components.utils.import("resource://app/my_module.jsm");

bar = "foo";
alert(bar);         // displays "foo"
</pre>
<p>Scope 2:</p>
<pre class="brush: js">Components.utils.import("resource://app/my_module.jsm");

alert(bar);         // displays "[object Object]"
</pre>
<p>The main effect of the by-value copy is global variables of simple types won't be shared across scopes. Always put variables in a wrapper class and export the wrapper (such as <code>bar</code> in the above example).</p>
<h3 id="resource:_Protocol" name="resource:_Protocol">resource URL</h3>
<p>When using <a href="/en/Components.utils.import" title="en/Components.utils.import">Components.utils.import</a>, you will notice that code modules are loaded using a "resource://" URL. The basic syntax of a resource URL is as follows:</p>
<pre class="eval">resource://&lt;alias&gt;/&lt;relative-path&gt;/&lt;file.js|jsm&gt;
</pre>
<p>The <code>&lt;alias&gt;</code> is an alias to a location, usually a physical location relative to the application or XUL runtime. There are several pre-defined aliases setup by the XUL runtime:</p>
<ul> <li><code>app</code> - Alias to the location of the XUL application.</li> <li><code>gre</code> - Alias to the location of the XUL runtime.</li>
</ul>
<p>The <code>&lt;relative-path&gt;</code> can be multiple levels deep and is always relative to the location defined by the <code>&lt;alias&gt;</code>. The common relative path is "modules" and is used by XUL Runner and Firefox. Code modules are simple JavaScript files with a .js or .jsm extension.</p>
<p>The easiest way for extensions and XUL applications to add custom aliases is by registering an alias in the <a href="/en/Chrome_Registration" title="en/Chrome_Registration">chrome manifest</a> using a line like this:</p>
<pre class="eval">resource <em>aliasname</em> <em>uri/to/files/</em>
</pre>
<p>For example, if the XPI for your <em>foo</em> extension includes a top-level modules/ directory containing the <em>bar.js</em> module (that is, the modules/ directory is a sibling to chrome.manifest and install.rdf), you could create an alias to that directory via the instruction:</p>
<pre class="eval">resource foo modules/
</pre>
<p>(Don't forget the trailing slash!) You could then import the module into your JavaScript code via the statement:</p>
<pre class="brush: js">Components.utils.import("<a class=" external" href="resource://foo/bar.js" rel="freelink">resource://foo/bar.js</a>");
</pre>
<h2 id="Programmatically_adding_aliases" name="Programmatically_adding_aliases">Programmatically adding aliases</h2>
<p>Custom aliases can be programmatically added to the resource URL as well. For example:</p>
<pre class="brush: js">var ioService = Components.classes["@mozilla.org/network/io-service;1"]
                          .getService(Components.interfaces.nsIIOService);
var resProt = ioService.getProtocolHandler("resource")
                       .QueryInterface(Components.interfaces.nsIResProtocolHandler);

var aliasFile = Components.classes["@mozilla.org/file/local;1"]
                          .createInstance(Components.interfaces.nsILocalFile);
aliasFile.initWithPath("/some/absolute/path");

var aliasURI = ioService.newFileURI(aliasFile);
resProt.setSubstitution("myalias", aliasURI);

// assuming the code modules are in the alias folder itself, not a s
</pre>
<h2 id="See_also" name="See_also">See also</h2>
<ul> <li><a class="external" href="http://wiki.mozilla.org/Labs/JS_Modules">Mozilla Labs JS Modules</a> - This page features a list of JS modules, along with download links and documentation, that extension developers can use in their code.<a href="/En/Code_snippets/Modules" title="En/Code_snippets/Modules"><br> </a></li> <li><a href="/En/Code_snippets/Modules" title="En/Code_snippets/Modules">Code snippets: Modules</a></li>
</ul>
<p> </p>
<p>{{ languages( { "es": "es/Usando_m\u00f3dulos_de_c\u00f3digo_JavaScript", "fr": "fr/Utilisation_de_modules_de_code_JavaScript", "ja": "ja/Using_JavaScript_code_modules", "pl": "pl/Zastosowanie_modu\u0142\u00f3w_JavaScript" } ) }}</p>
Revert to this revision