| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8"> |
| <!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge"><![endif]--> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| <meta name="generator" content="Asciidoctor 1.5.7.1"> |
| <title>Modules</title> |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"> |
| <!-- ************* Meta ************* --> |
| <meta charset="utf-8"> |
| <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" /> |
| |
| <!-- ************* OpenGraph ************--> |
| <meta name="description" content="The Eclipse N4JS language and its IDE enable high-quality JavaScript development for large Node.js projects."> |
| |
| <meta property="og:site_name" content="Eclipse N4JS"/> |
| <meta property="og:title" content="Eclipse N4JS Language and IDE"/> |
| <meta property="og:url" content="https://numberfour.github.io/n4js"/> |
| <meta property="og:description" content="The Eclipse N4JS language and its IDE enable high-quality JavaScript development for large Node.js projects."/> |
| <meta property="og:image" content="../images/n4js.png"> |
| |
| <!-- ************* Favicon ************--> |
| <link rel="icon" href="../images/favicon.ico" /> |
| <link rel="icon" type="image/png" href="../images/favicon-32x32.png" sizes="32x32" /> |
| <link rel="icon" type="image/png" href="../images/favicon-16x16.png" sizes="16x16" /> |
| |
| <!-- ************* Back-to-top JQuery ************* --> |
| <script src="https://code.jquery.com/jquery-1.12.4.js"></script> |
| <script src="https://code.jquery.com/ui/1.12.0/jquery-ui.js"></script> |
| |
| <!-- ************* Prism.js Syntax Highlighter ******--> |
| <link href="../styles/prism.min.css" rel="stylesheet"/> |
| <script src="../scripts/prism.js"></script> |
| |
| <!-- ************* Styles ************* --> |
| |
| <link rel="stylesheet" type="text/css" href="../styles/n4js-adoc.css"> |
| |
| <!-- ****************** NavBar ****************** --> |
| <div id="menubar"> |
| <div class="banner"> |
| <a href="../index.html"><img id="logo" src="../images/n4js-logo.png" alt="Eclipse N4JS Language and IDE"></a> |
| </div> |
| <ul> |
| <li><a href="../downloads.html"></i>Download</a></li> |
| <li><a href="../community.html"></i>Community</a></li> |
| <li><a href="../userguides/index.html">Documentation</a></li> |
| </ul> |
| </div> |
| <button id="tocbutton">TOC</button> |
| </head> |
| <body class="book"> |
| <div id="header"> |
| </div> |
| <div id="content"> |
| <h1 id="_modules" class="sect0"><a class="link" href="#_modules">Modules</a></h1> |
| <div class="openblock partintro"> |
| <div class="title">Modules</div> |
| <div class="content"> |
| Large-scale projects of almost any language require good modularization for maintenance reasons. |
| It’s vital for projects that modules don’t become oversized and comprise a well-defined purpose |
| that is easy to comprehend for developers. The N4JS IDE helps for keeping track of your code modules and validates their usage. |
| </div> |
| </div> |
| <div class="sect1"> |
| <h2 id="_multiple_exports"><a class="link" href="#_multiple_exports">Multiple Exports</a></h2> |
| <div class="sectionbody"> |
| <div class="paragraph"> |
| <p>While it’s a good habit to assign one module for a single type, it may |
| be suitable to define multiple types or variables in a single module in cases where they |
| correspond or are related. |
| ECMAScript 2015 allows for this with the module syntax it defines. The good news is |
| that N4JS already supports most of it:</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="highlight"><code class="language-n4js" data-lang="n4js">export public function inc(): void { ++count; } |
| export public var count = 5; |
| export default public class Foo { |
| public callOnIt(): void { } |
| }</code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>Importing an ECMAScript 2015 module and consuming exports is as easy as the following:</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="highlight"><code class="language-n4js" data-lang="n4js">import { inc, count } from 'Counter';// Named imports |
| import Foo from 'Counter'; // Default import |
| import { readFile } from 'fs' // Node.js core modules |
| import express from 'express'; // npm modules |
| import * as plainJsModule+ from 'plainJsModule'; // Dynamic import</code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>The module could also be imported as a whole:</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="highlight"><code class="language-n4js" data-lang="n4js">import * as foo from 'Counter'; // Namespace import</code></pre> |
| </div> |
| </div> |
| <div class="admonitionblock note"> |
| <table> |
| <tr> |
| <td class="icon"> |
| <i class="fa icon-note" title="Note"></i> |
| </td> |
| <td class="content"> |
| Anonymous default exports and relative module paths are not yet supported. The module specifier is the relative path of the |
| module in its source folder. Optionally the project name can be used as prefix, e.g., in case of ambiguities. |
| </td> |
| </tr> |
| </table> |
| </div> |
| </div> |
| </div> |
| <div class="sect1"> |
| <h2 id="_n4js_ide_organizes_imports"><a class="link" href="#_n4js_ide_organizes_imports">N4JS IDE Organizes Imports</a></h2> |
| <div class="sectionbody"> |
| <div class="paragraph"> |
| <p>Manually writing import statements is not necessary: the N4JS IDE does this automatically. |
| The IDE will recognise all projects involved via various runtime and |
| library dependencies that are defined in by the user in the manifest.n4mf file. |
| Simply write the type or variable you require and press <span class="keyseq"><kbd>Ctrl</kbd>+<kbd>SPACE</kbd></span>. |
| Content assist within the IDE will add the missing import statement for you:</p> |
| </div> |
| <div class="imageblock"> |
| <div class="content"> |
| <img src="images/moduleimport.png" alt="moduleimport"> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>When pasting in a code snippet, you could use <span class="keyseq"><kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>O</kbd></span> |
| (on Windows and Linux, <span class="keyseq"><kbd>Cmd</kbd>+<kbd>Shift</kbd>+<kbd>O</kbd></span> on Mac) which organizes your imports and |
| will add any that are missing. This is also used to clean up any unused imports:</p> |
| </div> |
| <div class="imageblock"> |
| <div class="content"> |
| <img src="images/organizeimports.png" alt="organizeimports"> |
| </div> |
| </div> |
| </div> |
| </div> |
| <div class="sect1"> |
| <h2 id="_import_removal"><a class="link" href="#_import_removal">Import Removal</a></h2> |
| <div class="sectionbody"> |
| <div class="paragraph"> |
| <p>When developing in N4JS, you may notice that you sometimes need to import types to cast |
| a variable or use it for a constraint in a generic.</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="highlight"><code class="language-n4js" data-lang="n4js">import Foo from 'Counter'; |
| |
| var someOtherVar: Object; |
| (someOtherVar as Foo).callOnIt(); |
| |
| export function <T extends Foo> bar(t: T): void { }</code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>The compiler will notice that there’s no runtime code dependency on the |
| imported module and will omit loading the module.</p> |
| </div> |
| </div> |
| </div> |
| <div class="sect1"> |
| <h2 id="_read_only_views"><a class="link" href="#_read_only_views">Read-only Views</a></h2> |
| <div class="sectionbody"> |
| <div class="paragraph"> |
| <p>ES2015 modules have the concept of read-only views. Although you cannot modify anything imported from |
| a module, your binding is live. In the case that the exporting party has modified |
| the export, you will read the current value. For example:</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="highlight"><code class="language-n4js" data-lang="n4js">import {inc, count} from 'Counter'; |
| |
| console.log(count); // 5 |
| inc(); |
| console.log(count); // 6</code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>Although highly discouraged, read-only views allow to support some cyclic |
| dependencies across modules. N4JS might even reorder type definitions to achieve this.</p> |
| </div> |
| </div> |
| </div> |
| <div class="sect1"> |
| <h2 id="_loader_details"><a class="link" href="#_loader_details">Loader Details</a></h2> |
| <div class="sectionbody"> |
| <div class="paragraph"> |
| <p>So far, there’s no engine/platform that has implemented the ES2015 specification natively. N4JS |
| and most other transpilers, transpile modules into the SystemJS format.</p> |
| </div> |
| <div class="paragraph"> |
| <p>N4JS' output format goes a bit further and emits an unified format that works as well in a |
| synchronous CommonJS/Node.js environment. |
| Keep in mind, however, that when you load a module the CommonJS way, you are |
| limited to this with regard to cyclic dependencies because it has to resolve all |
| dependencies synchronously.</p> |
| </div> |
| </div> |
| </div> |
| </div> |
| <div id="footer"> |
| <div id="footer-text"> |
| </div> |
| </div> |
| <div class="Grid social" style="color:#d5dfea"> |
| <div class="Cell Cell--2-12 m-Cell--withMargin"> |
| <h2>Quick Links</h2> |
| <ul> |
| <li><a href="../downloads.html">Download</a></li> |
| <li><a href="../userguides/index.html">Documentation</a></li> |
| <li><a href="https://github.com/eclipse/n4js/">Source</a></li> |
| <li><a href="https://github.com/eclipse/n4js/issues">Issues</a></li> |
| </ul> |
| </div> |
| <div class="Cell Cell--2-12 m-Cell--withMargin"> |
| <br/><br/> |
| <ul> |
| <li><a href="https://www.eclipse.org/forums/index.php/f/365/">Forum</a></li> |
| <li><a href="http://n4js.blogspot.de/">Blog</a></li> |
| <li><a href="https://dev.eclipse.org/mailman/listinfo/n4js-dev">Mailing List</a></li> |
| <li><a href="https://projects.eclipse.org/projects/technology.n4js">Eclipse Project Page</a></li> |
| <li><a href="https://twitter.com/n4jsdev">Tweets by n4jsdev</a></li> |
| </ul> |
| </div> |
| <div class="Cell Cell--2-12 m-Cell--withMargin"> |
| <br/><br/> |
| <ul> |
| <li><a href="http://www.eclipse.org/">Eclipse Home</a></li> |
| <li><a href="http://www.eclipse.org/legal/privacy.php">Privacy Policy</a></li> |
| <li><a href="http://www.eclipse.org/legal/termsofuse.php">Terms of Use</a></li> |
| <li><a href="http://www.eclipse.org/legal/copyright.php">Copyright Agent</a></li> |
| <li><a href="http://www.eclipse.org/legal/">Legal</a></li> |
| </ul> |
| </div> |
| <div style="clear: both; height: 0; overflow: hidden;"></div> |
| </div> |
| |
| <script> |
| // Toggle the table of contents |
| $( "button#tocbutton" ).click(function() { |
| if ($("#tocbutton").css('right') == '25px') { |
| $( "#tocbutton" ).animate({right: '215px'},"slow"); |
| $( "#toc.toc2" ).animate({right: '0'},"slow"); |
| } |
| else { |
| $( "#tocbutton" ).animate({right: '25px'},"slow"); |
| $( "#toc.toc2" ).animate({right: '-13rem'},"slow"); |
| } |
| }); |
| </script> |
| |
| <script type="text/javascript"> |
| // Create a back to top button |
| $('body').prepend('<a href="#" class="back-to-top">Back to Top</a>'); |
| var amountScrolled = 300; |
| $(window).scroll(function() { |
| if ( $(window).scrollTop() > amountScrolled ) { |
| $('a.back-to-top').fadeIn('slow'); |
| } else { |
| $('a.back-to-top').fadeOut('slow'); |
| } |
| }); |
| $('a.back-to-top, a.simple-back-to-top').click(function() { |
| $('html, body').animate({ |
| scrollTop: 0 |
| }, 700); |
| return false; |
| }); |
| </script> |
| </body> |
| </html> |