Ultimate Lasso.js Tutorial - ByteScout
  • Home
  • /
  • Blog
  • /
  • Ultimate Lasso.js Tutorial

Ultimate Lasso.js Tutorial

As a client-side Javascript module bundler, Lasso.js provides powerful advantages over other bundlers. Optional dependencies, code splitting, and plugins for pre-processing are among the innovative optimizations featured. Lasso.js enables the asynchronous loading of additional JavaScript and CSS following the initial page load. Combine this with Lasso’s de-dupe feature to eliminate module redundancy, and you have the ultimate speed, efficiency, and convenience in page loading. In this ByteScout Ultimate Tutorial, you will learn to leverage asynchronous module loading and many more Lasso.js features. So let’s get started!

First, let’s install and test Lasso.js

Begin by installing Lasso.js with this command:

npm install lasso –save

Next, add the Command Line Interface (CLI) for Lasso.js globally like this:

npm install lasso-cli –global

If you don’t already have npm installed, it is the default package manager installed with Node.js. Go ahead and install that now; it’s a prerequisite to our tutorial. Run the above commands and npm will fetch all the Lasso components and install them for you. Get a quick help list of npm command line arguments by entering the npm -h command.

Lasso your first bundle!

Lasso.js enables you to write code that uses require on the client-side as you would do with Node.js on the server-side. Let’s start our first example by implementing Lasso on a command line to bundle a file called main.js with its required modules.

To set up this example, we’re going to create a new directory and initialize a new Node.js project. Next, we will install the required modules, add our JavaScript files, a StyleSheet, and an  HTML file to host the application.

First, create a new directory called “my-project.” Open a command-line inside your new directory  and create a JSON package with this command:

npm init

The package installer will choose your directory name as the default name for the project files. As you will see, it’s possible to change any of the default settings as init prompts you. For this example go ahead and hit “enter” to choose default values for the prompts from init. To get additional command line specs on “init” type “npm help json” on the command line.

Now, let’s install the module we will use for this project. Enter the following command:

npm install jquery

Next, create a main Node.js module file named “main.js” like this:

var multiply = require('./multiply');
var jquery = require('jquery');
jquery(function() {
    $(document.body).append('Result = ' + multiply(9, 5));
});

Be sure to name your test files exactly as I have to ensure that your first test bundle will work accordingly. Let’s stay on the same page for this demo!

Let’s create the simple JavaScript file implied in “main.js” to multiply two numbers, call it “multiply.js” and include this script:

module.exports = function(a, b) {
return a * b;
};

Next, add a simple StyleSheet called “style.css” like this:

body {
background-color: #6B8000;
}

And finally, a minimal HTML file as app host called “test-page.htm” like this one:


<!doctype html>
<head>
<title>My First Lasso.js Bundle!</title>
</head>
<body>
<h1>My First Lasso.js Bundle!</h1>
</body>
</html>

Now for the test, enter the following command to bundle all the files and update the test HTML file with the required <script> tags:

lasso style.css –main main.js –inject-into test-page.htm –development

If the build was successful, you will get a response from Lasso.js like,

Successfully lassoed page “test-page”!

Excellent! This means our test bundle is ready to run. Let’s have a look at some of the results. Open “test-page.htm” in your browser to confirm the bound modules worked and the output includes, “Result = 45” and the green background color from the StyleSheet. At this point, if any of your results don’t match, review the steps above. It’s important to notice how each of the dependencies is included by the bundler.

Next look at how our original test-page.htm file was transformed by Lasso.js to include all the module dependencies:


<!doctype html>
<head>
<title>My First Lasso.js Bundle!</title>
<!-- <lasso-head> --><link rel="stylesheet" href="./static/test-page/my-project$1.0.0/style.css"><!-- </lasso-head> --></head>
<body>
<h1>My First Lasso.js Bundle!</h1>
<!-- <lasso-body> --><script src="./static/test-page/lasso-modules-client$2.0.5/src/index.js"></script>
<script src="./static/test-page/my-project$1.0.0/multiply.js"></script>
<script src="./static/test-page/lasso-modules-meta.js"></script>
<script src="./static/test-page/jquery$3.2.1/dist/jquery.js"></script>
<script src="./static/test-page/my-project$1.0.0/main.js"></script>
<script src="./static/test-page/my-project$1.0.0/main-run.js"></script>
<script>$_mod.ready();</script><!-- </lasso-body> --></body>
</html>

Reopen “test-page.htm” in your editor and have a look at the updates where Lasso.js injected the <link> and <script> tags. Lasso.js created the build script and added the resource bundles and all related references to your project for you! This highlights the essential purpose of Lasso.js, which is to free you as a developer from writing build scripts and enable you to focus on creating clean code!

Easily debug and rapidly rebuild!

Let’s demo how quickly we can debug and rebuild the bundle with a code change, and while we’re at it, let’s include another great feature of Lasso.js in the bundle. Lasso.js supports LESS CSS styling on the command line via a plugin. In your project folder, simply create a file named “style.less” and add this script:

@headerColor: #6B8000;
h1 {
color: @headerColor;
}

Now, enter the Lasso.js command to include the new style via a plugin like this:

lasso style.less –main main.js –inject-into test-page.htm –plugins lasso-less …

            –production

The LESS CSS file is bundled correctly when the Lasso.js LESS plugin is added as a command-line argument. Our test-page.htm file is updated automatically by Lasso.js to reflect the changes. Note that in this build we changed from development mode to production mode (to get a full listing of commands to enter lasso –help on the command line.)

Now have a look at the new results and you will notice that the resources are concatenated and streamlined. When –production is enabled, bundled resources are concatenated and fingerprinted to increase the performance of production web apps. Now that we have completed a simple test run and all the resources are connected, let’s explore more of the performance features of Lasso.js in depth.

Going deeper into dependencies

In Lasso lingo, a JavaScript or a CSS to be bundled in a project is called a dependency. A dependency such as the LESS CSS file in our project above can be declared in a JavaScript as:

require(‘./style.less’);

But it is important to remember that on such a require() call Node.js will attempt to load the file as a JavaScript module by default! If you are loading a LESS file (or any other non-JavaScript file) then add the following to the main script:

require(‘lasso/node-require-no-op‘).enable(‘.less’, ‘.css’);

Support for conditional dependencies is another powerful feature of Lasso.js. A page may be built in various ways based on conditional flags. Frequent use of this functionality includes building a page distinctly based on the state of device flags which indicate a laptop, tablet, or phone for example. Let’s add a script to set a conditional flag so that the conditional dependency is only included on a mobile device.

The designers of Lasso.js state that bundler caching requires us to base conditional dependencies on flags, which are arbitrary names enabled or disabled prior to optimization. To code a conditional dependency so that it will only load on a mobile device browser use a snippet like this:

{
"dependencies": [
{"path": "./hi-mobile.js", "if-flag": "mobile" }
]
}

And here is a JavaScript snippet suggested by Lasso.js designers to handle the distinction between tablet and phone devices:

{
"dependencies": [
{
"path": "./hi-mobile.js",
"if": "flags.contains('phone') || flags.contains('tablet')"
}
]
}

Here is a sample script offered by Lasso.js designers which enables flags when a page is optimized:

myLasso.lassoPage({
dependencies: [
{ path: './hi-mobile.js', 'if-flag': 'mobile' }
],
flags: ['mobile', 'str1', 'str2']
})

If you want to download a resource from an external server and bundle it with your own app code when you run the Lasso command, set the external property to false as in this example:

{
"dependencies": [
{ "type": "js", "url": "https://code.jquery.com/jquery.min.js", "external": false }
]
}

Otherwise, Lasso.js will not bundle an external resource with your app by default.

Asynchronous loading of dependencies

A cornerstone feature of Lasso.js is the ability to load modules asynchronously, making page updates possible without reloading an entire page. The core of asynchronous loading in Lasso.js is the lassoLoader.async function. Modules required within the scope of lassoLoader are loaded asynchronously. Lasso.js enforces the rule that modules-load only once from the server; only one copy of a module is sent to the browser. Modules loaded previously, on initial page load are “de-duped” automatically.

This is a critical functionality according to the designers of Lasso.js for an important reason.  Auto de-duping promotes encapsulation at the module-level. When separate teams of developers are building modules they can add dependencies to a core library without concern for duplication. This also enables the creation of standalone modules.

Here is a sample usage of the LassoLoader from the designer’s documentation, updated with references to our test bundle:

var lassoLoader = require('lasso-loader');
    lassoLoader.async(function(err) {
         if (err) {
       // Handles dependencies which failed to load
        }
        var multiply = require('./multiply');
        var jquery = require('jquery');
       jquery(function() {
           $(document.body).append('Result = ' + multiply(9, 5));
      });
    });

Lasso.js sees the require(‘lasso-loader’).async(…) call during optimization and updates the code so that the function does not execute until all of the required modules in the callback are loaded.

Once defined in this way, the async resources can be referenced in JavaScript like this:

require('lasso-loader').async(
'my-module/lazy',
function() {
var a1 = require('an1');
var a2 = require('an2');
});

Async is also called “lazy loading,” as you can see in the above snippet. Pages can update without reloading.

Setting up a config for Lasso

As you can see, command-line arguments quickly mount up and get cumbersome as you add dependencies to a project. We can manage bundles more efficiently by creating a config file containing all our references. Let’s divide the config info from our test bundle into separate files for convenience. First, create a file named “lasso-config1.js” and add this script with references to our test bundle:

{
"plugins": [                      // properties enabled
"lasso-less"
],
"outputDir": "static",
"fingerprintsEnabled": true,
"minify": true,
"resolveCssUrls": true,
"bundlingEnabled": true,
"bundles": [
{
"name": "jquery",
"dependencies": [
"require: jquery"
]
},
{
"name": "math",         // altern tested 1203
"dependencies": [
"require: ./multiply"
]
}
]
}

Next, create a file named “test-page.browser.json” and add the dependencies of our test bundle above using this script:

{
"dependencies": [
"./style.less",
"require-run: ./main"
]
}

Finally, run Lasso.js on your command line and include the JSON config files like this:

lasso ./test-page.browser.json –inject-into test-page.html –config lasso-config.json

Many code samples for testing the optimization features of Lasso.js are provided by the designers at their GitHub repository. It is recommended that you download and explore those samples to deepen your knowledge of the topics covered in this ByteScout tutorial.

Now, let’s set the default configuration for Lasso.js using the following script:

var lasso = require('lasso');
lasso.configure(config);

The value of config is treated as a path to the configuration file (if the value of config is string type.) Now we have the basis for understanding how to lasso a set of resources – to bundle them – let’s look at a few of the rich development features of Lasso.js.

Going deeper into bundling

Although dependencies for a page are bundled as single JavaScript and CSS bundles, Lasso.js makes it possible to configure application-level bundles across pages and to configure multiple bundles for single pages. Lasso.js does the HTML edits automatically to include page bundles.

Since bundling occurs at the app level, any equal page-level dependencies will be included at the app level. There is a “bundles” config property which takes array type configurations; each bundle in the array should contain a bundle name and its associated dependencies.

All about code splitting

Where multiple pages share the same code, Lasso.js makes enables code splitting into separate bundles. This is done by this done by creating an intersection dependency for a bundle. The intersection is the set of dependencies in a package shared by one or more packages. This feature guarantees that code will only download once by a user’s web app.
Here is an example, provided by the architects of Lasso.js, of a bundle configuration which shows how to split common code into a separate bundle:

{
"bundles": [
{
"name": "common1",
"dependencies": [
{
"intersection": [
"./src/project/pages/home1/browser.json",
"./src/project/pages/profile1/browser.json"
]
}
]
}
]
}

A more flexible intersection condition can be implemented with the threshold property. This property can be set to find a minimum intersection of dependencies, such as two or more for example.

The final roundup

At this point, you are ready to explore fully the application of Lasso.js to optimize and enhance your web apps! If you are already using Node.js then note that Lasso.js supports transporting Node.js modules to browsers. Modules are written in standard Node.js (using require) can be loaded both on the server and client-side for the browser. Also, if you have built CommonJS modules into your project then the CommonJS runtime will be included in your Lasso.js builds. Be sure to explore the Lasso.js build options for working with CommonJS.

As a next step, check out the list of plugins for Lasso.js which can be found along with the numerous instructional code samples at the Lasso.js GitHub repository. Please continue to explore the subject of this ByteScout tutorial more in-depth by experimenting with your own with the code found here!

For additional study:

Core Lasso.js plugins

Reference of Lasso.js command line usage:

Here is a reference list of all the Lasso.js command line instructions which you will get if you run the command lasso –help

Usage: lasso [dependency, dependency2, …] [OPTIONS]

Examples:

Lasso a single Node.js module for the browser:

lasso –main run.js –name my-page

Lasso a set of dependencies:

lasso style.less foo.js template.marko

Enable CSS and JS minification:

lasso style.less foo.js template.marko –name my-page –minify

Change the output directory:

lasso style.less foo.js template.marko –name my-page –output-dir build

Options:

–name -n The name of the page being lassoed (e.g. “my-page”) [string]

–output-dir –out -o The output directory for static bundles and lassoed page JSON files [string]

–config -c Path to a JSON lasso configuration file [string]

–minify -m Enable JavaScript and CSS minification (disabled by default) [boolean]

–no-conflict Enable no-conflict build by providing unique string (e.g. “myapp”) [string]

–fingerprint Include fingerprints in filenames [boolean]

–help -h Show this help screen [boolean]

–url-prefix -u URL prefix for resource bundles (e.g. “http://mycdn/”) [string]

–development –dev -d Enable development mode (no minification, bundling or fingerprints) [boolean]

–production -prod Enable production mode (minification, bundling and fingerprints) [boolean]

–base-path -b File system path used to calculate relative paths to generated bundles [string]

–html -h Generate a JSON file that contains the HTML markup required to include the dependencies (organized by slot) [boolean]

–html-dir Output directory for JSON files (defaults to “build”) [string]

–extensions –extension Extensions to enable (legacy, use flags) [string]

–flags –flag -f Flags to enable [string]

–inject-into –inject -i Pages to inject the slot HTML into [string]

–main –entry -e The JavaScript module main entry for your app [string]

–dependencies –dependency * Page dependencies [string]

–cache-profile Caching profile (either “default” or “production”) [string]

–cache-dir Base cache directory (defaults to “CWD/.cache/lasso”) [string]

–cache-key The cache key to use when reading and persisting the result to/from disk [string]

–disk-cache Read/write lassoed pages from/to a disk cache [boolean]

–plugins -plugin -p Plugins to enable

–paths –path Additional directories to add to the application-level module search path [string]

–watch -w Watch for file changes [boolean]

–config-cache-key The configuration cache key [string]

 

   

About the Author

ByteScout Team ByteScout Team of Writers ByteScout has a team of professional writers proficient in different technical topics. We select the best writers to cover interesting and trending topics for our readers. We love developers and we hope our articles help you learn about programming and programmers.  
prev
next