Files
docs.nestjs.com/src/app/homepage/pages/modules/modules.component.html
kamil.mysliwiec 35518da691 Initial commit
2017-08-26 10:12:55 +02:00

90 lines
4.7 KiB
HTML

<div class="content">
<h3>Modules</h3>
<p>
Module is a class with <code>@Module()</code> decorator. The <code>@Module()</code> decorator provides metadata, which <strong>Nest</strong> is using to organize the application structure.
</p>
<figure><img src="/assets/Modules_1.png" /></figure>
<p>
Every Nest application has at least one module, the <strong>root module</strong>.
The root module is the place, where Nest is starting to arrange the application tree.
In fact, the root module could be the only module in your application, especially when the app is small, but it doesn't make sense.
In most cases you'll have several modules, each with closely related set of <strong>capabilities</strong>.
</p>
<p>
The <code>@Module()</code> decorator takes the single object whose properties describe the module.
Read about them in the below table:
</p>
<table>
<tr>
<td><code>components</code></td>
<td>the components that will be instantiated by the Nest injector and may be shared at least across this module.</td>
</tr>
<tr>
<td><code>controllers</code></td>
<td>the set of controllers which have to be created</td>
</tr>
<tr>
<td><code>modules</code></td>
<td>the list of imported modules that export the components which are necessary in this module</td>
</tr>
<tr>
<td><code>exports</code></td>
<td>the subset of <code>components</code> that should be available in the other modules</td>
</tr>
</table>
<p>
The module <strong>encapsulates</strong> components by default. It means that it isn't possible to inject the components which aren't directly the part of the current module, or they're not exported from the imported modules.
</p>
<h3>CatsModule</h3>
<p>
The <code>CatsController</code> and <code>CatsService</code> belong to the same application domain.
They should be moved to the feature module, the <code>CatsModule</code>.
</p>
<span class="filename">cats/cats.module.ts</span>
<pre><code class="language-typescript">{{ catsModule }}</code></pre>
<p>
I've created the <code>cats.module.ts</code> file and moved everything related to this module into the
<code>cats</code> directory. The last thing we need to do is to import this module into the root module which name is <code>ApplicationModule</code>.
</p>
<span class="filename">app.module.ts</span>
<pre><code class="language-typescript">{{ appModule }}</code></pre>
<p>
It's everything. Now Nest knows that besides <code>ApplicationModule</code>, it's essential to register the <code>CatsModule</code> too.
</p>
<h3>Shared Module</h3>
<p>
In Nest, modules <strong>are singletons</strong> by default, so you can share the <strong>same instance</strong> of the component between 2..* modules without any effort.
</p>
<blockquote>
<strong>Notice</strong> In the previous versions of the Nest (< 4), modules weren't singletons, we had to use <code>@Shared()</code> decorator which now is <strong>deprecated</strong>.
</blockquote>
<figure><img src="/assets/Shared_Module_1.png" /></figure>
<p>
Every module is a <strong>Shared Module</strong> in fact. Once created is reused by the each module.
Let's imagine that we're gonna share the <code>CatsService</code> instance between few modules.
</p>
<span class="filename">cats.module.ts</span>
<pre><code class="language-typescript">{{ catsModuleShared }}</code></pre>
<p>
Now each module which would import the <code>CatsModule</code> has an access to the <code>CatsService</code>, and will share the same instance with all of the modules which import this module too.
</p>
<blockquote>
<strong>Notice</strong> Never export the controller!
</blockquote>
<h3>Single Scope</h3>
<p>
They're modules which shouldn't be shared at all. To prevent module from being singleton, you can use <code>@SingleScope()</code>
decorator, which makes that Nest will always create the new instance of the module, when it's imported by another one.
</p>
<pre><code class="language-typescript">{{ singleScope }}</code></pre>
<h3>Dependency Injection</h3>
<p>
It's natural that module can <strong>inject</strong> components, which belongs to it (e.g. for the configuration purposes):
</p>
<span class="filename">cats.module.ts</span>
<pre><code class="language-typescript">{{ catsModuleDi }}</code></pre>
<p>
However, modules can't be injected by the components, because it creates a <a href="/advanced/circular-dependency">circular dependency</a>.
</p>
</div>