/src/Website/Views/Documentation/GettingStarted_CombineAssetsIntoModules.cshtml
https://github.com/IanPatrickHughes/cassette · Razor · 125 lines · 114 code · 11 blank · 0 comment · 5 complexity · 215d573cfa0e3d97b75ada4af9bd9315 MD5 · raw file
- <h1>Combine assets into modules</h1>
- <p>Out of the box, Cassette runs in a very simple mode where each asset is treated separately.
- However, referencing many separate assets in production is bad for performance.
- So let's configure Cassette to combine assets into modules.
- </p>
-
- <h2>Wait a sec... Assets and modules?</h2>
- <p>An asset is any static file that ends up being used in the web browser, such JavaScript, CSS, CoffeeScript, LESS, HTML templates, etc.</p>
- <p>A module is a collection of assets that form a single resource, when deployed in production.</p>
- <p>For example, a collection of jQuery plugins can be combined into a single script. Cassette lets you keep
- each source file separate to make debugging easy. Then in production mode, Cassette will concatenate the files
- together.</p>
- <p>Cassette has three types of module:</p>
- <ul>
- <li>Scripts</li>
- <li>Stylesheets</li>
- <li>HTML Templates</li>
- </ul>
- <p>Each module is processed using a sequence of steps that transform the assets. For example, CoffeeScript assets are compiled into JavaScript.</p>
- <p>We need to tell Cassette how to build these modules.</p>
-
- <h2>Configuration</h2>
- <p>The <code>Cassette.Web</code> nuget package adds a file to your project called <code>CassetteConfiguration.cs</code>.
- The class in that file is used to configure Cassette.</p>
- <pre><code><span class="keyword">public class</span> <span class="code-type">CassetteConfiguration</span> : <span class="code-type">ICassetteConfiguration</span>
- {
- <span class="keyword">public</span> <span class="keyword">void</span> Configure(
- <span class="code-type">ModuleConfiguration</span> moduleConfiguration,
- <span class="code-type">ICassetteApplication</span> application)
- {
- <span class="comment">// ... configure Cassette here ...</span>
- }
- }</code></pre>
-
- <p class="minor">When the configuration is empty, Cassette will default to treating each asset as a separate module.</p>
-
- <h2>Group assets into directories</h2>
- <p>It's time to organise that untidy scripts directory! Each application is different, but essentially you need to
- divide the scripts into directories. Here's an example directory listing:</p>
- <pre><code>scripts/
- lib/
- jquery.js
- jquery-ui.js
- underscore.js
-
- shared/
- sidebar.js
- widget.js
- forms.js
-
- signup/
- index.js
-
- dashboard/
- index.js
- user.js
- other.js
- </code></pre>
- <p class="minor">Note that there are no <code>.min.js</code> files in there. Cassette will perform the minification for you.</p>
- <p>
- Keep in my that a module is a <em>unit of deployment</em>.
- If any asset in a module changes, then the entire module has to be downloaded again by web browsers.
- So perhaps group shared code into a module and put page scripts into their own modules.
- </p>
-
- <h2>Configure module sources</h2>
- <p>On application start up, Cassette will build the modules. A "module source" says where to look for assets and how to group them into modules.</p>
- <p>So far we've relied on the default <code>PerFileSource</code>. Let's change this to use directories instead.</p>
- <pre><code><span class="keyword">public class</span> <span class="code-type">CassetteConfiguration</span> : <span class="code-type">ICassetteConfiguration</span>
- {
- <span class="keyword">public</span> <span class="keyword">void</span> Configure(
- <span class="code-type">ModuleConfiguration</span> moduleConfiguration,
- <span class="code-type">ICassetteApplication</span> application)
- {
- moduleConfiguration.Add(
- <span class="keyword">new</span> <span class="code-type">DirectorySource</span><<span class="code-type">ScriptModule</span>>(<span class="string">"scripts/lib"</span>, <span class="string">"scripts/shared"</span>, <span class="string">"scripts/signup"</span>, <span class="string">"scripts/dashboard"</span>)
- {
- FilePattern = <span class="string">"*.js"</span>
- }
- );
- }
- }</code></pre>
- <p>Here we've added a new <code>DirectorySource<ScriptModule></code> object and listed the application relative directory paths.
- We've also set the <code>FilePattern</code> property so it only looks for JavaScript files.</p>
- <p>If there are many directories, it can be tedious to type them all in. Instead, use the <code>PerSubDirectorySource</code>:</p>
- <pre><code><span class="keyword">public class</span> <span class="code-type">CassetteConfiguration</span> : <span class="code-type">ICassetteConfiguration</span>
- {
- <span class="keyword">public</span> <span class="keyword">void</span> Configure(
- <span class="code-type">ModuleConfiguration</span> moduleConfiguration,
- <span class="code-type">ICassetteApplication</span> application)
- {
- moduleConfiguration.Add(
- <span class="keyword">new</span> <span class="code-type">PerSubDirectorySource</span><<span class="code-type">ScriptModule</span>>(<span class="string">"scripts"</span>)
- {
- FilePattern = <span class="string">"*.js"</span>
- }
- );
- }
- }</code></pre>
- <p>Cassette will now create a module for each sub-directory of the scripts directory.</p>
-
- <h2>Referencing modules</h2>
- <p>When each asset was treated separately our view pages had to reference each file. For example:</p>
- <pre><code><span class="code-tag">@@{</span>
- <span class="code-type">Assets</span>.Scripts.Reference(<span class="string">"scripts/dashboard/index.js"</span>);
- <span class="code-type">Assets</span>.Scripts.Reference(<span class="string">"scripts/dashboard/user.js"</span>);
- <span class="code-type">Assets</span>.Scripts.Reference(<span class="string">"scripts/dashboard/other.js"</span>);
- <span class="code-tag">}</span>
- </code></pre>
- <p>This can be simplified to a single reference to the module directory:</p>
- <pre><code><span class="code-tag">@@{</span>
- <span class="code-type">Assets</span>.Scripts.Reference(<span class="string">"scripts/dashboard"</span>);
- <span class="code-tag">}</span>
- </code></pre>
- <p>Please note: Referencing a specific asset file will still work, however this will also include <strong>all</strong> the assets
- in the module. Modules are "all or nothing".</p>
-
- <p>This also applies to reference within assets. For example, an asset in one module can reference other module.</p>
- <pre><code><span class="comment">/// <reference path="~/scripts/lib" /></span>
-
- <span class="comment">jQuery is in the 'lib' module, so we can now use it in this file.</span>
- jQuery(document).ready(function() {
- ...
- });</code></pre>
- <p>However, you will lose Visual Studio IntelliSense when referencing like this.</p>