{"id":13452148,"url":"https://github.com/lasso-js/lasso","last_synced_at":"2025-05-15T17:08:18.438Z","repository":{"id":12912396,"uuid":"15589752","full_name":"lasso-js/lasso","owner":"lasso-js","description":"Advanced JavaScript module bundler, asset pipeline and optimizer","archived":false,"fork":false,"pushed_at":"2024-04-04T22:34:48.000Z","size":3453,"stargazers_count":584,"open_issues_count":92,"forks_count":74,"subscribers_count":16,"default_branch":"master","last_synced_at":"2025-05-08T21:37:50.301Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lasso-js.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2014-01-02T17:48:18.000Z","updated_at":"2025-04-23T18:26:39.000Z","dependencies_parsed_at":"2024-06-18T13:43:44.680Z","dependency_job_id":null,"html_url":"https://github.com/lasso-js/lasso","commit_stats":{"total_commits":1281,"total_committers":42,"mean_commits":30.5,"dds":0.3832943013270882,"last_synced_commit":"30fe251247ef7ff9a268149fa7221f550b54bc66"},"previous_names":["raptorjs/optimizer","raptorjs3/raptor-optimizer"],"tags_count":360,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lasso-js%2Flasso","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lasso-js%2Flasso/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lasso-js%2Flasso/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lasso-js%2Flasso/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lasso-js","download_url":"https://codeload.github.com/lasso-js/lasso/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254384988,"owners_count":22062422,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-31T07:01:14.755Z","updated_at":"2025-05-15T17:08:13.425Z","avatar_url":"https://github.com/lasso-js.png","language":"JavaScript","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"readme":"Lasso.js\n==================\n\n[![Build Status](https://travis-ci.org/lasso-js/lasso.svg?branch=master)](https://travis-ci.org/lasso-js/lasso)\n[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/lasso-js/lasso)\n\nLasso.js is an eBay open source Node.js-style JavaScript module bundler that also provides first-level support for optimally delivering JavaScript, CSS, images and other assets to the browser.\n\nThis tool offers many different optimizations such as a bundling, code splitting, lazy loading, conditional dependencies, compression and fingerprinted resource URLs. Plugins are provided to support pre-processors and compilers such as Less, Stylus and [Marko](https://github.com/raptorjs/marko). This developer-friendly tool does not require that you change the way that you already code and can easily be adopted by existing applications.\n\n# Example\n\nInstall the command line interface for Lasso.js:\n\n```text\nnpm install lasso-cli --global\n```\n\nInstall a helper module from npm:\n\n```text\nnpm install change-case\n```\n\nCreate the main Node.js JavaScript module file:\n\n__main.js:__\n\n```javascript\nvar changeCase = require('change-case');\nconsole.log(changeCase.titleCase('hello world')); // Output: 'Hello World'\n```\n\nCreate a StyleSheet for the page:\n\n__style.css__\n\n```css\nbody {\n    background-color: #5B83AD;\n}\n```\n\nCreate an HTML page to host the application:\n\n__my-page.html:__\n\n```html\n\u003c!doctype html\u003e\n\u003chtml lang=\"en\"\u003e\n\u003chead\u003e\n    \u003cmeta charset=\"UTF-8\"\u003e\n    \u003ctitle\u003eLasso.js Demo\u003c/title\u003e\n\u003c/head\u003e\n\u003cbody\u003e\n    \u003ch1\u003eLasso.js Demo\u003c/h1\u003e\n\u003c/body\u003e\n\u003c/html\u003e\n```\n\nRun the following command:\n\n```bash\nlasso style.css \\\n    --main main.js \\\n    --inject-into my-page.html\n```\n\nOutput:\n\n```text\nOutput for page \"my-page\":\n  Resource bundle files:\n    static/my-page-9ac9985e.js\n    static/my-page-1ae3e9bf.css\n  HTML slots file:\n    build/my-page.html.json\n  Updated HTML file:\n    my-page.html\n```\n\nOpen up `my-page.html` in your web browser and in the JavaScript console you will see the output of our program running in the browser, as well as a page styled by `style.css`.\n\nAs you can see, with Lasso.js you no longer have to struggle with managing complex build scripts. Simply let Lasso.js worry about generating all of the required resource bundles and injecting them into your page so that you can just focus on writing clean and modular code.\n\nThere's also a JavaScript API, taglib and a collection of plugins to make your job as a front-end web developer easier. Please read on to learn how you can easily utilize Lasso.js in your application.\n\n\u003c!-- START doctoc generated TOC please keep comment here to allow auto update --\u003e\n\u003c!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --\u003e\n\n# Table of Contents\n\n- [Design Philosophy](#design-philosophy)\n- [Features](#features)\n- [Another Client-side Bundler?](#another-client-side-bundler)\n- [Installation](#installation)\n- [Usage](#usage)\n\t- [Command Line Interface](#command-line-interface)\n\t- [JSON Configuration File](#json-configuration-file)\n\t- [Dependencies](#dependencies)\n\t\t- [External Dependencies](#external-dependencies)\n\t\t- [Dependency Attributes](#dependency-attributes)\n\t\t- [Conditional Dependencies](#conditional-dependencies)\n\t\t- [Enabling Flags](#enabling-flags)\n\t- [Asynchronous/Lazy Loading](#asynchronouslazy-loading)\n\t- [Using the JavaScript API](#using-the-javascript-api)\n\t\t- [Configuring the Default Lasso](#configuring-the-default-lasso)\n\t\t- [Optimizing a Page](#optimizing-a-page)\n\t\t- [Creating a New Lasso](#creating-a-new-lasso)\n\t- [Lasso.js Taglib](#lassojs-taglib)\n\t\t- [Using Lasso.js Taglib with Marko](#using-lassojs-taglib-with-marko)\n\t\t- [`\u003classo-img\u003e`](#\u003classo-img\u003e)\n\t- [Client/Server Template Rendering](#clientserver-template-rendering)\n\t- [Runtime Optimization with Express](#runtime-optimization-with-express)\n\t- [Bundling](#bundling)\n\t- [Code Splitting](#code-splitting)\n- [Configuration](#configuration)\n\t- [Default Configuration](#default-configuration)\n\t- [Complete Configuration](#complete-configuration)\n- [Node.js-style Module Support](#nodejs-style-module-support)\n- [Babel Support](#babel-support)\n- [No Conflict Builds](#no-conflict-builds)\n- [Custom attributes for Script \u0026 Style tags](#custom-attributes-for-script--style-tags)\n    - [Use of defer/async with script tags](#use-of-deferasync-with-script-tags)\n- [Content Security Policy Support](#content-security-policy-support)\n- [Available Plugins](#available-plugins)\n- [Extending Lasso.js](#extending-lassojs)\n\t- [Custom Plugins](#custom-plugins)\n\t- [Custom Dependency Types](#custom-dependency-types)\n\t\t- [Custom JavaScript Dependency Type](#custom-javascript-dependency-type)\n\t\t- [Custom CSS Dependency Type](#custom-css-dependency-type)\n\t\t- [Custom Package Type](#custom-package-type)\n\t- [Custom Output Transforms](#custom-output-transforms)\n- [JavaScript API](#javascript-api)\n- [AMD Compatibility](#amd-compatibility)\n- [Sample Projects](#sample-projects)\n- [Discuss](#discuss)\n- [Maintainers](#maintainers)\n- [Contributors](#contributors)\n- [Contribute](#contribute)\n- [License](#license)\n\n\u003c!-- END doctoc generated TOC please keep comment here to allow auto update --\u003e\n\n# Design Philosophy\n\n* Dependencies should be **declarative** _or_ discovered via **static code analysis**\n* Common **module loading** patterns should be supported\n* Must be **extensible** to support all types of resources\n* **Maximize productivity** in development\n* **Maximize performance** in production\n* Must be **easy to adopt** and not change how you write your code\n* Can be used at **runtime or build time**\n* Must be **configurable**\n\n# Features\n\n* Bundle Client-side Dependencies\n    * Supports all types of front-end resources (JavaScript, CSS, images, Less, CoffeeScript, etc.)\n    * Asynchronous/lazy loading of JS/CSS\n    * Configurable resource bundling\n    * Code splitting\n    * JavaScript minification\n    * CSS minification\n    * [Fingerprinted](https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/http-caching) resource URLs\n    * Prefix resources with CDN host name\n    * Optional Base64 image encoding inside CSS files\n    * Custom output transforms\n    * Declarative browser-side package dependencies using simple `browser.json` files\n\t* endencies\n\t* Image minification\n    * etc.\n* Browser-side Node.js Module Loader\n    * Full support for [Isomorphic JavaScript](http://nerds.airbnb.com/isomorphic-javascript-future-web-apps/)\n    * Conflict-free CommonJS module loader for the browser\n    * Complete compatibility with Node.js\n        * Supports `module.exports`, `exports`, `require`, `require.resolve`, `__dirname`, `__filename`, `process`, etc.\n    * Supports the [package.json `browser` field](https://gist.github.com/defunctzombie/4339901)\n    * Full support for [browserify](http://browserify.org/) shims and transforms\n    * Maintains line numbers in wrapped code\n* Developer Friendly\n    * Generates the HTML markup required to include bundled resources\n    * Disable bundling and minification in development\n    * Line numbers are maintained for Node.js modules source\n    * Extremely fast _incremental builds_!\n        * Only modified bundles are written to disk\n        * Disk caches are utilized to avoid repeating the same work\n* Dependency Compilation\n    * Less\n    * [Marko](https://github.com/marko-js/marko)\n    * Dust\n    * etc.\n* Extensible\n    * Custom dependency compilers\n    * Custom code transforms\n    * Custom bundle writers\n    * Custom plugins\n* Configurable\n    * Configurable resource bundles\n    * Enable/disable transforms\n    * Development-mode versus production-mode\n    * Enable/disable fingerprints\n    * etc.\n* Flexible\n    * Integrate with build tools\n    * Use with Express or any other web development framework\n    * JavaScript API, CLI and taglib\n* Security\n    * Supports the [nonce attribute](https://www.w3.org/TR/CSP2/#script-src-the-nonce-attribute) when using Content Security Policy for extra security.\n* _Future_\n    * Automatic image sprites\n\n# Another Client-side Bundler?\n\n[Browserify](http://browserify.org/) is an excellent JavaScript module bundler. We are huge supporters of writing Node.js-style modules (i.e. CommonJS), and we also believe [npm](https://www.npmjs.org/) is an excellent package manager. If you are not using a JavaScript module bundler then you are absolutely missing out. Modularity is equally important for client-side code as it is for server-side code, and a JavaScript module bundler should be part of every front-end developer's toolbox.\n\nSo why did we create Lasso.js if Browserify is such a great tool? We created Lasso.js because we wanted a top-notch JavaScript module bundler that _also_ provides first-level support for transporting CSS, \"plain\" JavaScript, images, fonts and other front-end assets to the browser in the most optimal way. In addition, we want to enable developers to easily create web applications that follow [widely accepted rules for creating faster-loading websites](http://stevesouders.com/examples/rules.php) (such as putting StyleSheets at the top, and JavaScript at the bottom). We also want to allow for developers to easily load additional JavaScript and StyleSheets after the initial page load.\n\nWhile high performance is very important for production systems, we want to also provide a more developer-friendly experience by offering fast, incremental builds, simplifying development and by producing debuggable output code. And, of course, we do not want developers to have to learn how to code their applications in a new way so Lasso.js was built to not change how you already code. You'll even find support for Browserify shims and transforms. Therefore, if you try out Lasso.js and it is not the tool for you, then feel free to switch back to something else (it'll of course be ready if your application's requirements change in the future). eBay and other large companies rely on Lasso.js for delivering high performance websites and are committed to its success. If you try it out and find gaps, please let us know!\n\n# Installation\n\nThe following command should be used to install the `lasso` module into your project:\n\n```bash\nnpm install lasso --save\n```\n\nIf you would like to use the available command line interface, then you should install the [lasso-cli](https://github.com/lasso-js/lasso-cli) module globally using the following command:\n\n```bash\nnpm install lasso-cli --global\n```\n\n# Usage\n\n## Command Line Interface\n\n\u003chr\u003e\n\n[__Sample App:__](https://github.com/lasso-js-samples/lasso-cli) To try out and experiment with the code, please see the following project:\u003cbr\u003e[lasso-js-samples/lasso-cli](https://github.com/lasso-js-samples/lasso-cli)\n\n\u003chr\u003e\n\nInstall the command line interface for Lasso.js:\n\n```bash\nnpm install lasso-cli --global\n```\n\nIn an empty directory, initialize a new Node.js project using the following command:\n\n```bash\nmkdir my-app\ncd my-app\nnpm init\n```\n\nInstall required modules into the new project:\n\n```bash\nnpm install jquery\nnpm install lasso-less\n```\n\nCreate the following files:\n\n__add.js:__\n\n```javascript\nmodule.exports = function(a, b) {\n    return a + b;\n};\n```\n\n__main.js:__\n\n```javascript\nvar add = require('./add');\nvar jquery = require('jquery');\n\njquery(function() {\n    $(document.body).append('2+2=' + add(2, 2));\n});\n```\n\n__style.less:__\n\n```css\n@headerColor: #5B83AD;\n\nh1 {\n    color: @headerColor;\n}\n```\n\n__my-page.html:__\n\n```html\n\u003c!doctype html\u003e\n\u003chtml lang=\"en\"\u003e\n\u003chead\u003e\n    \u003cmeta charset=\"UTF-8\"\u003e\n    \u003ctitle\u003eLasso.js Demo\u003c/title\u003e\n\u003c/head\u003e\n\u003cbody\u003e\n    \u003ch1\u003eLasso.js Demo\u003c/h1\u003e\n\u003c/body\u003e\n\u003c/html\u003e\n```\n\nFinally, run the following command to generate the resource bundles for the page and to also inject the required `\u003cscript\u003e` and `\u003clink\u003e` tags into the HTML page:\n\n```bash\nlasso style.less \\\n    --main main.js \\\n    --inject-into my-page.html \\\n    --plugins lasso-less \\\n    --development\n```\n\nIf everything worked correctly then you should see output similar to the following:\n\n```text\nOutput for page \"my-page\":\n  Resource bundle files:\n    static/add.js\n    static/raptor-modules-meta.js\n    static/main.js\n    static/node_modules/jquery/dist/jquery.js\n    static/raptor-modules-1.0.1/client/lib/raptor-modules-client.js\n    static/style.less.css\n  HTML slots file:\n    build/my-page.html.json\n  Updated HTML file:\n    my-page.html\n```\n\nThe updated `my-page.html` file should be similar to the following:\n\n```html\n\u003c!doctype html\u003e\n\u003chtml lang=\"en\"\u003e\n\u003chead\u003e\n    \u003cmeta charset=\"UTF-8\"\u003e\n    \u003ctitle\u003eLasso.js Demo\u003c/title\u003e\n    \u003c!-- \u003classo-head\u003e --\u003e\n    \u003clink rel=\"stylesheet\" href=\"static/style.less.css\"\u003e\n    \u003c!-- \u003c/lasso-head\u003e --\u003e\n\u003c/head\u003e\n\u003cbody\u003e\n    \u003ch1\u003eLasso.js Demo\u003c/h1\u003e\n    \u003c!-- \u003classo-body\u003e --\u003e\n    \u003cscript src=\"static/raptor-modules-1.0.1/client/lib/raptor-modules-client.js\"\u003e\u003c/script\u003e\n    \u003cscript src=\"static/add.js\"\u003e\u003c/script\u003e\n    \u003cscript src=\"static/raptor-modules-meta.js\"\u003e\u003c/script\u003e\n    \u003cscript src=\"static/node_modules/jquery/dist/jquery.js\"\u003e\u003c/script\u003e\n    \u003cscript src=\"static/main.js\"\u003e\u003c/script\u003e\n    \u003cscript\u003e$_mod.ready();\u003c/script\u003e\n    \u003c!-- \u003c/lasso-body\u003e --\u003e\n\u003c/body\u003e\n\u003c/html\u003e\n```\n\nIf you open up `my-page.html` in your web browser you should see a page styled with Less and the output of running `main.js`.\n\nNow try again with `production` mode:\n\n```bash\nlasso style.less \\\n    --main main.js \\\n    --inject-into my-page.html \\\n    --plugins lasso-less \\\n    --production\n```\n\n```\nOutput for page \"my-page\":\n  Resource bundle files:\n    static/my-page-2e3e9936.js\n    static/my-page-169ab5d9.css\n  HTML slots file:\n    build/my-page.html.json\n  Updated HTML file:\n    my-page.html\n```\n\nThe updated `my-page.html` file should be similar to the following:\n\n```html\n\u003c!doctype html\u003e\n\u003chtml lang=\"en\"\u003e\n\u003chead\u003e\n    \u003cmeta charset=\"UTF-8\"\u003e\n    \u003ctitle\u003eLasso.js Demo\u003c/title\u003e\n    \u003c!-- \u003classo-head\u003e --\u003e\n    \u003clink rel=\"stylesheet\" href=\"static/my-page-169ab5d9.css\"\u003e\n    \u003c!-- \u003c/lasso-head\u003e --\u003e\n\u003c/head\u003e\n\u003cbody\u003e\n    \u003ch1\u003eLasso.js Demo\u003c/h1\u003e\n    \u003c!-- \u003classo-body\u003e --\u003e\n    \u003cscript src=\"static/my-page-2e3e9936.js\"\u003e\u003c/script\u003e\n    \u003cscript\u003e$_mod.ready();\u003c/script\u003e\n    \u003c!-- \u003c/lasso-body\u003e --\u003e\n\u003c/body\u003e\n\u003c/html\u003e\n```\n\nWith the `--production` option enabled, all of the resources are concatenated together, minified and fingerprinted – perfect for high performance web applications running in production.\n\nFor more documentation on the Command Line Interface please see the [lasso-cli docs](https://github.com/lasso-js/lasso-cli).\n\n## JSON Configuration File\n\n\u003chr\u003e\n\n[__Sample App__](https://github.com/lasso-js-samples/lasso-config) To try out and experiment with the code, please see the following project:\u003cbr\u003e[lasso-js-samples/lasso-config](https://github.com/lasso-js-samples/lasso-config)\n\n\u003chr\u003e\n\nThe number of command line arguments can get unwieldy so it is better to split out configuration into a separate JSON file. Let's now create a configuration file and configure a few bundles to make things more interesting:\n\n__lasso-config.json:__\n\n```json\n{\n\n    \"plugins\": [\n        \"lasso-less\"\n    ],\n    \"outputDir\": \"static\",\n\t\"fingerprintsEnabled\": true,\n    \"minify\": true,\n    \"resolveCssUrls\": true,\n    \"bundlingEnabled\": true,\n    \"bundles\": [\n        {\n            \"name\": \"jquery\",\n            \"dependencies\": [\n                \"require: jquery\"\n            ]\n        },\n        {\n            \"name\": \"math\",\n            \"dependencies\": [\n                \"require: ./add\"\n            ]\n        }\n    ]\n}\n```\n\nIn addition, let's put our page dependencies in their own JSON file:\n\n__my-page.browser.json:__\n\n```json\n{\n    \"dependencies\": [\n        \"./style.less\",\n        \"require-run: ./main\"\n    ]\n}\n```\n\nNow run the page lasso using the newly created JSON config file and JSON dependencies file:\n\n```bash\nlasso ./my-page.browser.json \\\n    --inject-into my-page.html \\\n    --config lasso-config.json\n```\n\nBecause of the newly configured bundles, we'll see additional JavaScript bundles written to disk as shown below:\n\n```\nOutput for page \"my-page\":\n  Resource bundle files:\n    static/math-169c956d.js\n    static/jquery-24db89d9.js\n    static/my-page-beed0921.js\n    static/my-page-169ab5d9.css\n  HTML slots file:\n    build/my-page.html.json\n  Updated HTML file:\n    my-page.html\n```\n\n## Dependencies\n\nLasso.js walks a dependency graph to find all of the resources that need to be bundled. A dependency can either be a JavaScript or CSS resource (or a file that compiles to either JavaScript or CSS) or a dependency can be a reference to a set of transitive dependencies. Some dependencies are inferred from scanning source code and other dependencies can be made explicit by listing them out in the code of JavaScript modules or in separate `browser.json` files.\n\nIt's also possible to register your own [custom dependency types](#custom-dependency-types). With custom dependency types, you can control how resources are compiled or a custom dependency type can be used to resolve additional dependencies during optimization.\n\nBrowser dependencies can be described as shown in the following sample `browser.json` file:\n\n```json\n{\n    \"dependencies\": [\n        \"./style.less\",\n        \"../third-party/jquery.js\",\n        \"**/*.css\",\n        {\n            \"type\": \"js\",\n            \"url\": \"https://code.jquery.com/jquery-2.1.4.min.js\"\n        },\n        {\n            \"type\": \"css\",\n            \"url\": \"https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css\"\n        }\n    ]\n}\n```\n\nAlternatively, dependencies can be \"required\" inside a JavaScript module as shown in the following sample JavaScript code:\n\n```javascript\nrequire('./style.less');\n\n// ...\n```\n\nThe only caveat to using a `require()` call to add a non-JavaScript module dependency is that by default Node.js will try to load the required file as a JavaScript module if the code runs on the server. To prevent Node.js from trying to load a Less file or other non-JavaScript files as JavaScript modules you can add the following code to your main script:\n\n```javascript\nrequire('lasso/node-require-no-op').enable('.less', '.css');\n```\n\n\nFor simple paths, the dependency type is inferred from the filename extension. Alternatively, the dependency type can be made explicit using either one of the following formats:\n\n```json\n[\n    \"./style.less\",\n    \"less: ./style.less\",\n    { \"type\": \"less\", \"path\": \"./style.less\" }\n]\n```\n\n_NOTE: all of the above are equivalent_\n\nYou can also create a dependency that references dependencies in a separate `browser.json` file. Dependencies that have the `browser.json` extension are automatically resolved using the require resolver if they are not relative paths. For example:\n```js\n[\n    // Relative path:\n    \"./some-module/browser.json\",\n\n    // Look for \"my-module/browser.json\" in \"node_modules\":\n    \"my-module/browser.json\"\n]\n```\n\nIf the path does not have a file extension then it is assumed to be a path to an `browser.json` file so the following short-hand works as well:\n```js\n[\n    \"./some-module\"\n    \"my-module\"\n]\n```\nIf you use the short-hand notation for `browser.json` dependencies, the paths will still be resolved using the require resolver as long as they are not relative paths.\n\n### External Dependencies\n\nLasso.js does allow referencing external JS/CSS files in your `browser.json` files as shown below:\n\n```json\n{\n    \"dependencies\": [\n        {\n            \"type\": \"js\",\n            \"url\": \"https://code.jquery.com/jquery-2.1.4.min.js\"\n        },\n        {\n            \"type\": \"css\",\n            \"url\": \"https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css\"\n        }\n    ]\n}\n```\n\nBy default, Lasso.js will not bundle external resources with your application's JavaScript and CSS bundles. If you would prefer for an external resource to be downloaded from the remote server and bundled with your other application code during the lassoing then you can set the `external` property to `false` as shown below (`external` defaults to `true`):\n\n```json\n{\n    \"dependencies\": [\n        {\n            \"type\": \"js\",\n            \"url\": \"https://code.jquery.com/jquery-2.1.4.min.js\",\n            \"external\": false\n        }\n    ]\n}\n```\n\nSetting `external` to `false` in the above example will result in jQuery being downloaded from the CDN and bundled with all of the other JS code for the app. That is, the code for jQuery will not be served up by the jQuery CDN.\n\n### Dependency Attributes\n\nAdding an `attributes` object to a dependency definition will result in those attributes being defined on the html tag for that dependency.  For bundled dependencies, these attributes will be merged with latter dependencies taking priority.\n\nThe following is an example using the `integrity` and `crossorigin` attributes for [Subresource Integrity (SRI) checking](https://www.w3.org/TR/SRI/). This allows browsers to ensure that resources hosted on third-party servers have not been tampered with. Use of SRI is recommended as a best-practice, whenever libraries are loaded from a third-party source.\n\n```json\n{\n    \"dependencies\": [{\n        \"type\": \"js\",\n        \"url\": \"https://code.jquery.com/jquery-3.1.1.min.js\",\n        \"attributes\":{\n            \"integrity\":\"sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8=\",\n            \"crossorigin\":\"anonymous\"\n        }\n    }]\n}\n```\n\n**Generated Output:**\n```html\n\u003cscript\n  src=\"https://code.jquery.com/jquery-3.1.1.min.js\"\n  integrity=\"sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8=\"\n  crossorigin=\"anonymous\"\u003e\u003c/script\u003e\n```\n\n### Conditional Dependencies\n\nLasso.js supports conditional dependencies. Conditional dependencies is a powerful feature that allows for a page to be built differently based on certain flags (e.g. \"mobile device\" versus \"desktop\"). For caching reasons, the flags for conditional dependencies should be based on a set of enabled flag. A flag is just an arbitrary name that can be enabled/disabled before optimizing a page. For example, to make a dependency conditional such that is only included for mobile devices you can do the following:\n\n```json\n{\n    \"dependencies\": [\n        { \"path\": \"./hello-mobile.js\", \"if-flag\": \"mobile\" }\n    ]\n}\n```\n\nAlternatively, you can also include the desktop version of a file if the \"mobile\" extension is not enabled using `if-not-flag`.\n```json\n{\n    \"dependencies\": [\n        { \"path\": \"./hello-desktop.js\", \"if-not-flag\": \"mobile\" }\n    ]\n}\n```\n\nIf needed, a JavaScript expression can be used to describe a more complex condition as shown in the following sample code:\n\n```json\n{\n    \"dependencies\": [\n        {\n            \"path\": \"./hello-mobile.js\",\n            \"if\": \"flags.contains('phone') || flags.contains('tablet')\"\n        }\n    ]\n}\n```\n\nFinally, if you prefer, you can group your conditional dependencies if needed:\n\n```json\n{\n    \"dependencies\": [\n        {\n            \"if-flag\": \"mobile\",\n            \"dependencies\": [\n                \"./style-mobile.css\",\n                \"./client-mobile.js\"\n            ]\n        }\n    ]\n}\n```\n\n### Enabling Flags\n\nThe code below shows how to enable flags when optimizing a page:\n\n__Using the JavaScript API:__\n\n```javascript\nmyLasso.lassoPage({\n    dependencies: [\n        { path: './hello-mobile.js', 'if-flag': 'mobile' }\n    ],\n    flags: ['mobile', 'foo', 'bar']\n})\n```\n\n__Using the Marko taglib:__\n\n```marko\n\u003classo-page ... flags=['mobile', 'foo', 'bar']\u003e\n    ...\n\u003c/lasso-page\u003e\n```\n\n## Asynchronous/Lazy Loading\n\n\u003chr\u003e\n\n[__Sample App__](https://github.com/lasso-js-samples/lasso-async)To try out and experiment with the code, please see the following project:\u003cbr\u003e[lasso-js-samples/lasso-async](https://github.com/lasso-js-samples/lasso-async)\n\n\u003chr\u003e\n\n\nLasso.js supports asynchronously loading dependencies using the lightweight [lasso-loader](https://github.com/lasso-js/lasso-loader) module as shown in the following sample code:\n\n```javascript\nvar lassoLoader = require('lasso-loader');\n\nlassoLoader.async(function(err) {\n    // Any modules that are required within the scope\n    // of this function will be loaded asynchronously*.\n    // Lasso.js ensures that modules are only\n    // loaded once from the server.\n    //\n    // *Modules that were included as part of the initial\n    // page load will automatically be de-duped.\n\n    if (err) {\n        // Handle the case where one or more of the\n        // dependencies failed to load.\n    }\n\n    var add = require('./add');\n    var jquery = require('jquery');\n\n    jquery(function() {\n        $(document.body).append('2+2=' + add(2, 2));\n    });\n});\n```\n\nDuring optimization, Lasso.js detects the call to `require('lasso-loader').async(...)` and transforms the code such that the function is not invoked until all of the required modules referenced in the body of callback function are completely loaded.\n\nYou can also specify additional explicit dependencies if necessary:\n\n```javascript\nrequire('lasso-loader').async(\n    [\n        './style.less',\n        'some/other/browser.json'\n    ],\n    function() {\n        // All of the requires nested in this function block will be lazily loaded.\n        // When all of the required resources are loaded then the function will be invoked.\n        var foo = require('foo');\n        var bar = require('bar');\n    });\n```\n\nYou can also choose to declare async dependencies in an `browser.json` file:\n\n```json\n{\n    \"dependencies\": [\n        ...\n    ],\n    \"async\": {\n        \"my-module/lazy\": [\n            \"require: foo\",\n            \"require: bar\",\n            \"./style.less\",\n            \"some/other/browser.json\"\n        ]\n    }\n}\n```\n\nThe async dependencies can then be referenced in code:\n```javascript\nrequire('lasso-loader').async(\n    'my-module/lazy',\n    function() {\n        var foo = require('foo');\n        var bar = require('bar');\n    });\n```\n\n## Using the JavaScript API\n\n\u003chr\u003e\n\n[__Sample App__](https://github.com/lasso-js-samples/lasso-js-api) To try out and experiment with the code, please see the following project:\u003cbr\u003e[lasso-js-samples/lasso-js-api](https://github.com/lasso-js-samples/lasso-js-api)\n\n\u003chr\u003e\n\nFor added flexibility there is a JavaScript API that can be used to lasso pages as shown in the following sample code:\n\n```javascript\nvar lasso = require('lasso');\nlasso.configure('lasso-config.json');\nlasso.lassoPage({\n        name: 'my-page',\n        dependencies: [\n            \"./style.less\",\n            \"require-run: ./main\"\n        ]\n    },\n    function(err, lassoPageResult) {\n        if (err) {\n            // Handle the error\n        }\n\n        var headHtml = lassoPageResult.getHeadHtml();\n        // headHtml will contain something similar to the following:\n        // \u003clink rel=\"stylesheet\" href=\"static/my-page-169ab5d9.css\"\u003e\n\n        var bodyHtml = lassoPageResult.getBodyHtml();\n        // bodyHtml will contain something similar to the following:\n        //  \u003cscript src=\"static/my-page-2e3e9936.js\"\u003e\u003c/script\u003e\n    });\n```\n\nThe `lassoPage(options)` method supports the following options:\n\n- `data` (`Object`) - Arbitrary data that can be made available to plugins via `lassoContext.data`.\n- `cacheKey` (`String`) - A unique String to use for cache reads and writes. Defaults to `name`.\n- `dependencies` (`Array`) - An array of top-level page dependencies (e.g. `['foo.js', 'foo.css', 'require: jquery']`).\n- `flags` (`Array`) - The set of enabled flags (e.g. `['mobile', 'touch']`).\n- `from` (`String`) - The base path for resolving relative paths for top-level dependencies.\n- `name` (`String`) - The page name. Used for determining the names of the output JS/CSS bundles.\n- `packagePath` (`String`) - The path to an `browser.json` file that describes the top-level dependencies.\n\n### Configuring the Default Lasso\n```javascript\nvar lasso = require('lasso');\nlasso.configure(config);\n```\n\nIf the value of the `config` argument is a `String` then it is treated as a path to a JSON configuration file.\n\n\n### Optimizing a Page\n\nThe following code illustrates how to lasso a simple set of JavaScript and CSS dependencies using the default configured lasso:\n\n```javascript\nvar lasso = require('lasso');\nlasso.lassoPage({\n        name: 'my-page',\n        dependencies: [\n            './foo.js',\n            './bar.js',\n            './baz.js',\n            './qux.css'\n        ]\n    },\n    function(err, lassoPageResult) {\n        if (err) {\n            console.log('Failed to lasso page: ', err);\n            return;\n        }\n\n        var headHtml = lassoPageResult.getHeadHtml();\n        /*\n        String with a value similar to the following:\n        \u003clink rel=\"stylesheet\" href=\"/static/my-page-85e3288e.css\"\u003e\n        */\n\n        var bodyHtml = lassoPageResult.getBodyHtml();\n        /*\n        String with a value similar to the following:\n        \u003cscript src=\"/static/bundle1-6df28666.js\"\u003e\u003c/script\u003e\n        \u003cscript src=\"/static/bundle2-132d1091.js\"\u003e\u003c/script\u003e\n        \u003cscript src=\"/static/my-page-1de22b65.js\"\u003e\u003c/script\u003e\n        */\n\n        // Inject the generated HTML into the \u003chead\u003e and \u003cbody\u003e sections of a page...\n    });\n```\n\n### Creating a New Lasso\n\n```javascript\nvar myLasso = lasso.create(config);\nmyLasso.lassoPage(...);\n```\n\n\n## Lasso.js Taglib\n\n\u003chr\u003e\n\n[__Sample App__](https://github.com/lasso-js-samples/lasso-taglib) To try out and experiment with the code, please see the following project:\u003cbr\u003e[lasso-js-samples/lasso-taglib](https://github.com/lasso-js-samples/lasso-taglib)\n\n\u003chr\u003e\n\nFor the ultimate in usability, a taglib is provided for Marko (and Dust) to automatically lasso a page _and_ inject the required HTML markup to include the JavaScript and CSS bundles.\n\nIf you are using [Marko](https://github.com/marko-js/marko) you can utilize the available taglib for Lasso.js to easily lasso page dependencies and embed them into your page.\n\n### Using Lasso.js Taglib with Marko\n\n1. `npm install lasso --save`\n2. `npm install marko --save`\n\nYou can now add the lasso tags to your page templates. For example:\n\n```marko\n\u003classo-page package-path=\"./browser.json\"/\u003e\n\n\u003c!doctype html\u003e\n\u003chtml lang=\"en\"\u003e\n\u003chead\u003e\n    \u003cmeta charset=\"UTF-8\"\u003e\n    \u003ctitle\u003eTest Page\u003c/title\u003e\n    \u003classo-head/\u003e\n\u003c/head\u003e\n\u003cbody\u003e\n    \u003ch1\u003eTest Page\u003c/h1\u003e\n    \u003classo-body/\u003e\n\u003c/body\u003e\n\u003c/html\u003e\n```\n\nYou will then need to create an `browser.json` in the same directory as your page template. For example:\n\n_browser.json_:\n```json\n{\n    \"dependencies\": [\n        \"./jquery.js\",\n        \"./foo.js\",\n        \"./bar.js\",\n        \"./style.less\"\n    ]\n}\n```\n\nUsing Marko and Lasso.js taglib, you can simply render the page using code similar to the following:\n\n```javascript\nvar template = require('marko').load('my-page.marko');\ntemplate.render({}, function(err, html) {\n    // html will include all of the required \u003clink\u003e and \u003cscript\u003e tags\n});\n```\n\nThe output of the page rendering will be similar to the following:\n\n```html\n\u003c!doctype html\u003e\n\u003chtml lang=\"en\"\u003e\n\u003chead\u003e\n    \u003cmeta charset=\"UTF-8\"\u003e\n    \u003ctitle\u003eTest Page\u003c/title\u003e\n    \u003clink rel=\"stylesheet\" href=\"/static/my-page-85e3288e.css\"\u003e\n\u003c/head\u003e\n\u003cbody\u003e\n    \u003ch1\u003eTest Page\u003c/h1\u003e\n    \u003cscript src=\"/static/bundle1-6df28666.js\"\u003e\u003c/script\u003e\n    \u003cscript src=\"/static/bundle2-132d1091.js\"\u003e\u003c/script\u003e\n    \u003cscript src=\"/static/my-page-1de22b65.js\"\u003e\u003c/script\u003e\n\u003c/body\u003e\n\u003c/html\u003e\n```\n\nThe lasso result is cached so you can skip the build step!\n\nYou can also configure the default page lasso used by the lasso tags:\n\n```javascript\nrequire('lasso').configure({...});\n```\n\nFor more details, please see following documentation: [Lasso.js Taglib for Marko](taglib-marko.md)\n\n\u003ca name=\"\u003classo-img\"\u003e\u003c/a\u003e\n\n### `\u003classo-img\u003e`\n\nThe `\u003classo-img\u003e` tag can be used to render `\u003cimg\u003e` tags while also having the image referenced by the `src` attribute automatically go through the Lasso.js asset pipeline. In addition, if the `width` and `height` attributes are not specified then those attributes will automatically be added. This tag can be rendered on both the server and in the browser.\n\nExample:\n\n```marko\n\u003classo-img src=\"./foo.jpg\"/\u003e\n```\n\nThis might produce the following HTML output depending on how Lasso.js is configured:\n\n```html\n\u003cimg src=\"/static/foo-25b047cc.jpg\" width=\"100\" height=\"100\"\u003e\n```\n\n## Client/Server Template Rendering\n\n\u003chr\u003e\n\n[__Sample App__](https://github.com/lasso-js-samples/lasso-templates) To try out and experiment with the code, please see the following project:\u003cbr\u003e[lasso-js-samples/lasso-templates](https://github.com/lasso-js-samples/lasso-templates)\n\n\u003chr\u003e\n\nTo demonstrate rendering of the same template on the server and the client we will start with the following Marko template:\n\n__template.marko__\n\n```marko\n-- Hello ${data.name}!\n```\n\n_NOTE: The sample app includes sample code that illustrates how to also render both a Dust template and a Handlebars template on both the client and server._\n\nWe will then create a `main.js` file to render the template to the console:\n\n__main.js:__\n\n```javascript\nvar template = require('marko')\n    .load(require.resolve('./template.marko'));\n\ntemplate.render(\n    {\n        name: 'Frank'\n    },\n    function(err, html) {\n        console.log('Template output: ' + html);\n    });\n```\n\n_NOTE: The reason we use `require.resolve('./template.marko')` instead of `require('template.marko')` is that Node.js does not understand how to load `.marko` modules and the use of the `require.extensions` has been [deprecated](http://nodejs.org/api/globals.html#globals_require_extensions). `require.resolve()` is used to get the resolved path for the template and the [marko](https://github.com/marko-js/marko) module uses that path to load template into memory._\n\nRunning `node main.js` on the server will produce the following output in the console:\n\n```html\nTemplate output: Hello Frank!\n```\n\nIn order to automatically detect and compile required `*.marko` templates we\nwill need to install the [lasso-marko](https://github.com/lasso-js/lasso-marko)\nplugin and [@lasso/marko-taglib](https://github.com/lasso-js/lasso-marko-taglib)\ntaglib using the following commands:\n\n```bash\nnpm install lasso-marko\nnpm install @lasso/marko-taglib\n```\n\nWe can then lasso the page using the following command:\n\n```bash\nlasso style.less \\\n    --main main.js \\\n    --inject-into my-page.html \\\n    --plugins lasso-marko\n```\n\nAfter opening `my-page.html` in your web browser you should then see the same output written to the browser's JavaScript console.\n\n## Middleware for Express and Koa\n\nLasso includes optional middleware for both Express and Koa that can be used to serve up the static files that it generates.\n\n### `serveStatic(options)`\n\nThe `serveStatic` middleware provided by Lasso is a small wrapper around the [send](https://github.com/pillarjs/send) package.\n\nSupported options:\n\n- __lasso__ - The configured lasso instance (defaults to `require('lasso').getDefaultLasso()`)\n- __sendOptions__ - Pass through options for the `send` module. See [send » options](https://github.com/pillarjs/send#optionsd)\n\n### Using `serveStatic` with Express\n\n```javascript\napp.use(require('lasso/middleware').serveStatic(options));\n```\n\n### Using `serveStatic` with Koa\n\n```javascript\napp.use(require('lasso/middleware/koa').serveStatic(options));\n```\n\n## Runtime Optimization with Express and Koa\n\n\u003chr\u003e\n\n[__Sample App__](https://github.com/lasso-js-samples/lasso-express) To try out and experiment with the code, please see the following project:\u003cbr\u003e[lasso-js-samples/lasso-express](https://github.com/lasso-js-samples/lasso-express)\n\n\u003chr\u003e\n\nLasso.js has a smart caching layer and is fast enough so that it can be used at runtime as part of your server application. The easiest way to use Lasso.js at runtime is to use the Marko taglib and simply render the page template to the response output stream.\n\nThe first time the page renders, the page will be lassoed and cached and the output of the lasso will be used to produce the final page HTML. After the first page rendering, the only work that will be done by Lasso.js is a simple cache lookup.\n\nBy default, Lasso.js writes all resource bundles into the `static/` directory at the root of your application. In addition, by default, all resource URLs will be prefixed with `/static`. If resources are to be served up by the local Express server we will need to register the appropriate middleware as shown in the following sample code:\n\n__server.js__\n\n```javascript\nrequire('marko/node-require');\nrequire('marko/express');\n\nvar express = require('express');\nvar compression = require('compression');\nvar serveStatic = require('serve-static');\n\n// Load the page template:\nvar template = require('./template.marko');\n\n// Configure the default lasso\nrequire('lasso').configure({\n\n});\n\nvar app = express();\n\n// Enable gzip compression for all HTTP responses:\napp.use(compression());\n\n// Any URL that begins with \"/static\" will be served up\n// out of the \"static/\" directory:\napp.use(require('lasso/middleware').serveStatic());\n\napp.get('/', function(req, res) {\n    // Render the page template as normal:\n    res.marko(template, {\n            name: 'Frank'\n        });\n});\n...\n\napp.listen(8080);\n```\n\n## Bundling\n\nBy default, all dependencies required for a page will be bundled into a single JavaScript bundle and a single CSS bundle. However, Lasso.js allows application-level bundles to be configured to allow for consistent bundles across pages and for multiple bundles to be included on a single page. Because Lasso.js also generates the HTML markup to include page bundles, the page itself does not need to be changed if the bundle configuration is changed.\n\nIf a page has a dependency that is part of an application-level bundle then the dependency will be included as part of the application-level bundle instead of being aggregated with the page-level bundle.\n\nBundles can be configured using the `\"bundles\"` configuration property that accepts an array of bundle configurations. Each bundle should consist of a name and a set of dependencies to assign to that bundle.\n\n__Bundling Example:__\n\nGiven the following configured bundles:\n\n```json\n{\n    ...\n    \"bundles\": [\n        {\n            \"name\": \"bundle1\",\n            \"dependencies\": [\n                \"./foo.js\",\n                \"./baz.js\"\n            ]\n        },\n        {\n            \"name\": \"bundle2\",\n            \"dependencies\": [\n                \"./bar.js\"\n            ]\n        }\n    ]\n}\n```\n\n\nOptimizing a page that does not include any dependencies in application-level bundles:\n\n```bash\nlasso app.js style.css --name my-page -c lasso-config.json\n```\n\nOutput:\n\n```\nOutput for page \"my-page\":\n  Resource bundle files:\n    static/my-page.js\n    static/my-page.css\n  HTML slots file:\n    build/my-page.html.json\n```\n\n\nOptimizing a page that includes \"foo.js\" that is part of \"bundle1\":\n```bash\nlasso app.js foo.js style.css --name my-page -c lasso-config.json\n```\n\nOutput:\n\n```\nOutput for page \"my-page\":\n  Resource bundle files:\n    static/my-page.js\n    static/bundle1.js\n    static/my-page.css\n  HTML slots file:\n    build/my-page.html.json\n```\n\nFor more information on working with bundles. Please see the [bundling docs](docs/bundling.md).\n\n## Code Splitting\n\n\u003chr\u003e\n\n[__Sample App__](https://github.com/lasso-js-samples/lasso-code-splitting) To try out and experiment with the code, please see the following project:\u003cbr\u003e[lasso-js-samples/lasso-code-splitting](https://github.com/lasso-js-samples/lasso-code-splitting)\n\n\u003chr\u003e\n\nLasso.js supports splitting out code that multiple pages/entry points have in common into separate bundles. This is accomplished by assigning an `intersection` dependency to a bundle. The `intersection` dependency is a package dependency that produces a set of dependencies that is the intersection of one or more packages. Code splitting ensures that the same code is not downloaded twice by the user when navigating a web application.\n\nThe following bundle configuration illustrates how to split out common code into a separate bundle:\n\n```json\n{\n    \"bundles\": [\n        {\n            \"name\": \"common\",\n            \"dependencies\": [\n                {\n                    \"intersection\": [\n                        \"./src/pages/home/browser.json\",\n                        \"./src/pages/profile/browser.json\"\n                    ]\n                }\n            ]\n        }\n    ]\n}\n```\nA less strict intersection condition is also supported via a `threshold` property.\n\nFor example, to find those dependencies that are among *at least two* of the widgets:\n```json\n{\n    \"bundles\": [\n        {\n            \"name\": \"common\",\n            \"dependencies\": [\n                {\n                    \"threshold\": 2,\n                    \"intersection\": [\n                        \"require: ./a/widget\",\n                        \"require: ./b/widget\",\n                        \"require: ./c/widget\"\n                    ]\n                }\n            ]\n        }\n    ]\n}\n```\n\nThis could also be expressed as a percentage:\n```json\n{\n    \"bundles\": [\n        {\n            \"name\": \"common\",\n            \"dependencies\": [\n                {\n                    \"threshold\": \"66%\",\n                    \"intersection\": [\n                        \"require: ./a/widget\",\n                        \"require: ./b/widget\",\n                        \"require: ./c/widget\"\n                    ]\n                }\n            ]\n        }\n    ]\n}\n```\n\n# Configuration\n\n## Default Configuration\n```javascript\n{\n    // Write all bundles into the \"static\" directory\n    \"outputDir\": \"static\",\n\n    // URL prefix for all bundles\n    \"urlPrefix\": \"/static\",\n\n    // Include fingerprint in output files\n    \"fingerprintsEnabled\": true\n}\n```\n\n## Complete Configuration\n\n```javascript\n{\n    // Configure Lasso.js plugins\n    \"plugins\": [\n        // Plugin with a default config:\n        \"lasso-less\",\n        // Plugin with custom configuration:\n        {\n            \"plugin\": \"lasso-my-plugin\",\n            \"config\": { ... }\n        },\n        ...\n    ],\n    // The base output directory for generated bundles\n\t\"outputDir\": \"static\",\n\n\t// Optional URL prefix to prepend to relative bundle paths\n\t\"urlPrefix\": \"http://mycdn/static\",\n\n\t// If fingerprints are enabled then a shasum will be included in the URL.\n\t// This feature is used for cache busting.\n\t\"fingerprintsEnabled\": true,\n\n\t// If fingerprints are not enabled then the same output file would be\n\t// used for bundles that go into the head and bundles that go in the\n\t// body. Enabling this option will ensure that bundles have unique names\n\t// even if fingerprints are disabled.\n\t\"includeSlotNames\": false\n\n    // If \"minify\" is set to true then output CSS and JavaScript will run\n    // through a minification transform. (defaults to false)\n    \"minify\": false,\n\n    \"minifyJS\": false, // Minify JavaScript\n\n    \"minifyCSS\": false, // Minify CSS\n\n    \"minifyInlineOnly\": false, // Only minify inline resources\n\n    \"minifyInlineJSOnly\": false, // Only minify inline JavaScript resources\n\n    \"minifyInlineCSSOnly\": false, // Only minify inline CSS resources\n\n    // If \"resolveCssUrls\" is set to true then URLs found in CSS files will be\n    // resolved and the original URLs will be replaced with the resolved URLs.\n    // (defaults to true)\n    \"resolveCssUrls\": true,\n\n    // If \"relativeUrlsEnabled\" is set to false then URLs found in CSS files will\n    // be absolute based on the urlPrefix. This default is false, which creates\n    // relative URLs in CSS files.\n    \"relativeUrlsEnabled\": true,\n\n    // If \"bundlingEnabled\" is set to true then dependencies will be concatenated\n    // together into one or more bundles. If set to false then each dependency\n    // will be written to a separate file. (defaults to true)\n    \"bundlingEnabled\": true,\n\n    // If you want consistent bundles across pages then those shared bundles\n    // can be specified below. If a page dependency is part of a shared\n    // bundle then the shared bundle will be added to the page (instead of\n    // adding the dependency to the page bundle).\n    \"bundles\": [\n        {\n            // Name of the bundle (used for determining the output filename)\n            \"name\": \"bundle1\",\n\n            // Set of dependencies to add to the bundle\n            \"dependencies\": [\n                \"./foo.js\",\n                \"./baz.js\"\n            ]\n        },\n        {\n            \"name\": \"bundle2\",\n            \"dependencies\": [\n                \"./style/*.css\",\n                \"require: **/*.js\"\n            ]\n        }\n    ],\n\n    // The default name of the modules runtime variable is\n    // \"\"$_mod\" but you can change that with the noConflict option.\n    // This is necessary if you have a webpage that loads\n    // multiple JavaScript bundles that were\n    // built at different times with Lasso.\n    // The string you provide will be used to create\n    // a unique name for the modules runtime variable name by\n    // removing or replacing illegal characters.\n    \"noConflict\": \"myapp\"\n}\n```\n\n# Node.js-style Module Support\n\nLasso.js provides full support for transporting Node.js modules to the browser. If you write your modules in the standard Node.js way (i.e. using `require`, `module.exports` and `exports`) then the module will be able to be loaded on both the server and in the browser.\n\nThis functionality is offered by the core [lasso-require](https://github.com/lasso-js/lasso-require) plugin which introduces a new `require` dependency type. For example:\n\n```json\n[\n    \"require: ./path-to-some-module\"\n]\n```\n\nIf you want to include a module and have it run when loaded (i.e. self-executing) then you should use the `require-run` dependency type:\n\n```json\n[\n    \"require-run: ./main\"\n]\n```\n\nExamples of conditional requires:\n\n```json\n[\n    {\n        \"require-run\": \"./foo\",\n        \"if-flag\": \"bar\"\n    },\n    {\n        \"require\": \"./foo\",\n        \"if-flag\": \"bar\"\n    }\n]\n```\n\nIt's also possible to remap a require based on a flag:\n\n```json\n{\n    \"dependencies\": [\n        ...\n    ],\n    \"requireRemap\": [\n        {\n            \"from\": \"./foo.js\",\n            \"to\": \"./foo-mobile.js\",\n            \"if-flag\": \"mobile\"\n        }\n    ]\n}\n```\n\nThe [lasso-require](https://github.com/lasso-js/lasso-require) plugin will automatically scan the source to find all `require(path)` calls to determine which additional modules need to be included in the output bundles (done recursively). For a `require` to automatically be detected it must be in the form `require(\"\u003cmodule-name\u003e\")` or `require.resolve(\"\u003cmodule-name\u003e\")`.\n\nThe [lasso-require](https://github.com/lasso-js/lasso-require) plugin will automatically wrap all Node.js modules so that the psuedo globals (i.e. `require`, `module`, `exports`, `__filename` and `__dirname`) are made available to the module source code.\n\nThe `lasso-require` plugin also supports [browserify shims](https://github.com/substack/node-browserify#compatibility) and [browserify transforms](https://github.com/substack/node-browserify/wiki/list-of-transforms).\n\nFor more details on how the Node.js modules are supported on the browser, please see the documentation for the [lasso-js-samples/lasso-require](https://github.com/lasso-js/lasso-require) plugin.\n\n# Babel Support\n\nThe [lasso-babel-transform](https://github.com/lasso-js/lasso-babel-transform) module provides support for transpiling JavaScript/JSX code using [babel](https://babeljs.io/). Please see the [lasso-babel-transform](https://github.com/lasso-js/lasso-babel-transform) docs for information on how to use that transform.\n\n# No Conflict Builds\n\nIf you're using CommonJS modules in your project then this will cause the\nCommonJS runtime to be included in your build. The CommonJS runtime utilizes\na global variable (`$_mod` by default). If your build output files need to\nco-exist with other JavaScript files that were built by Lasso separately\nthen you need to make sure that your build produces a CommonJS runtime\nthat is isolated from other builds. That is, you should not use the default\n`$_mod` global.\n\nTo enable no-conflict build, you need to configure Lasso to use a unique\nCommonJS runtime global name. This can be done by setting the `noConflict`\nconfiguration property to string that is unique to your application or project.\n\nIf you're using the JavaScript API then this is possible via:\n\n```javascript\n// To configure the default Lasso for no-conflict builds:\nrequire('lasso').configure({\n    ...\n    noConflict: 'myapp'\n});\n\n// To create a new Lasso for no-conflict builds\nrequire('lasso').create({\n    ...\n    noConflict: 'myapp'\n});\n\n```\n\nSee [Configuration](#configuration) for full list of configuration options.\n\n# Custom attributes for Script \u0026 Style tags\nIt is also possible to add custom attributes to script and style tags for both inline and external resources. It is done using the attributes `inline-script-attrs`, `inline-style-attrs`, `external-style-attrs` and `external-script-attrs` as shown below.\n\n__page.marko__\n```marko\n\u003classo-page name=\"page\" package-path=\"./browser.json\"/\u003e\n\n\u003chtml\u003e\n    \u003chead\u003e\n        \u003classo-head external-style-attrs={'css-custom1': true}/\u003e\n        \u003classo-slot name=\"ext-css-slot\" external-style-attrs={'css-custom2': true}/\u003e\n        \u003classo-slot name=\"css-slot\" inline-style-attrs={'css-custom3': true}/\u003e\n    \u003c/head\u003e\n    \u003cbody\u003e\n        \u003classo-body external-script-attrs={'js-custom1': true}/\u003e\n        \u003classo-slot name=\"ext-js-slot\" external-script-attrs={'js-custom2': true}/\u003e\n        \u003classo-slot name=\"js-slot\" inline-script-attrs={'js-custom3': true}/\u003e\n    \u003c/body\u003e\n\u003c/html\u003e\n\n```\n__browser.json__\n```json\n{\n    \"dependencies\": [\n        { \"path\": \"style-ext.css\", \"slot\": \"ext-css-slot\" },\n        { \"path\": \"test-ext.js\", \"slot\": \"ext-js-slot\" },\n        \"style.css\",\n        \"test.js\",\n        { \"path\": \"style-inline.css\", \"inline\": true, \"slot\": \"css-slot\" },\n        { \"path\": \"test-inline.js\", \"inline\": true, \"slot\": \"js-slot\" }\n    ]\n}\n```\n__Output HTML__\n```html\n\u003chtml\u003e\n    \u003chead\u003e\n        \u003clink rel=\"stylesheet\" href=\"/static/page-1ae3e9bf.css\" css-custom1\u003e\n        \u003clink rel=\"stylesheet\" href=\"/static/page-244694d6.css\" css-custom2\u003e\n        \u003cstyle css-custom3\u003e\n            body .inline {\n    \t        background-color: red;\n\t    }\n\t\u003c/style\u003e\n    \u003c/head\u003e\n    \u003cbody\u003e\n        \u003cscript src=\"/static/page-ce0ad224.js\" js-custom1\u003e\u003c/script\u003e\n        \u003cscript src=\"/static/page-c3a331b0.js\" js-custom2\u003e\u003c/script\u003e\n        \u003cscript js-custom3\u003e\n            console.log('hello-inline');\n        \u003c/script\u003e\n    \u003c/body\u003e\n\u003c/html\u003e\n```\n\n## Use of defer/async with script tags\n\nIf you add `async` or `defer` to a slot for external script attrs and Lasso encounters an inline script in that slot, it will wrap the code in a listener for `DOMContentLoaded` (for defer) or `load` (for async) to ensure that the script does not execute until the rest of the deferred scripts in that slot are loaded.\n\n__page.marko__\n```marko\n\u003classo-page name=\"page\" package-path=\"./browser.json\"/\u003e\n\n\u003chtml\u003e\n    \u003cbody\u003e\n        \u003classo-body external-script-attrs={defer: true}/\u003e\n    \u003c/body\u003e\n\u003c/html\u003e\n\n```\n\n__browser.json__\n```json\n{\n    \"dependencies\": [\n        \"test.js\",\n        { \"path\": \"test-inline.js\", \"inline\": true }\n    ]\n}\n```\n\n__Output HTML__\n```html\n\u003chtml\u003e\n    \u003cbody\u003e\n        \u003cscript src=\"/static/page-ce0ad224.js\" defer\u003e\u003c/script\u003e\n        \u003cscript\u003e\n            (function() { var run = function() { console.log('hello-inline'); }; if (document.readyState === \"loading\") { document.addEventListener(\"DOMContentLoaded\", run); } else { run(); } })();\n        \u003c/script\u003e\n    \u003c/body\u003e\n\u003c/html\u003e\n```\n\n# Content Security Policy Support\n\nNewer browsers support a web standard called Content Security Policy that\nprevents, among other things, cross-site scripting attacks by whitelisting\ninline `\u003cscript\u003e` and `\u003cstyle\u003e` tags (see\n[HTML5 Rocks: An Introduction to Content Security Policy](http://www.html5rocks.com/en/tutorials/security/content-security-policy/)).\n\n## Securing Dynamically Built Pages\nThe Lasso.js taglib for Marko is used to inject the `\u003cscript\u003e` and `\u003cstyle\u003e`\ntags into the HTML output and Lasso.js provides support for injecting a nonce\nattribute. When Lasso.js is configured you just need to register a\n`cspNonceProvider` as shown below:\n\n```javascript\nrequire('lasso').configure({\n    cspNonceProvider: function(out) {\n        // Logic for determining the nonce will vary, but the following is one option:\n        var res = out.stream;\n        var nonce = res.csp \u0026\u0026 res.csp.nonce;\n\n        // NOTE:\n        // The code above assumes that there is some middleware that\n        // stores the nonce into a [non-standard] `res.csp.nonce` variable.\n        // Use whatever is appropriate for your app.\n        return nonce; // A string value\n    }\n});\n```\n\nA Lasso.js plugin can also be used to register the CSP nonce provider as shown below:\n\n```javascript\nmodule.exports = function(lasso, pluginConfig) {\n    lasso.setCSPNonceProvider(function(out) {\n        return 'abc123';\n    })\n};\n```\n\nRegistering a `cspNonceProvider` will result in a `nonce` attribute being added to all inline `\u003cscript\u003e` and `\u003cstyle\u003e` tags rendered in either the `head` slot (`\u003classo-head/\u003e`) or the `body` slot (`\u003classo-body/\u003e`).\n\n\nWith a CSP nonce enable, the HTML output for a page rendered using Marko might be similar to the following:\n\n```html\n\u003chtml\u003e\n    \u003chead\u003e\n        \u003c!-- BEGIN head slot: --\u003e\n        \u003clink rel=\"stylesheet\" type=\"text/css\" href=\"/static/page1-8b866529.css\"\u003e\n        \u003cstyle type=\"text/css\" nonce=\"abc123\"\u003e\n            body .inline {\n                background-color: red;\n            }\n        \u003c/style\u003e\n        \u003c!-- END head slot --\u003e\n    \u003c/head\u003e\n    \u003cbody\u003e\n        \u003c!-- BEGIN body slot: --\u003e\n        \u003cscript type=\"text/javascript\" src=\"/static/page1-1097e0f6.js\"\u003e\u003c/script\u003e\n        \u003cscript type=\"text/javascript\" nonce=\"abc123\"\u003e\n            console.log('hello-inline');\n        \u003c/script\u003e\n        \u003c!-- END body slot --\u003e\n    \u003c/body\u003e\n\u003c/html\u003e\n```\n\nNOTE: A `nonce` attribute is only added to inline `\u003cscript\u003e` and `\u003cstyle\u003e` tags.\n\nAs an extra convenience, Lasso.js also supports a custom `lasso-nonce`\nattribute that can be dropped onto any HTML tag in your Marko template\nfiles as shown below:\n\n```xml\n\u003cscript type=\"text/javascript\" lasso-nonce\u003econsole.log('My inline script')\u003c/script\u003e\n\u003cstyle type=\"text/css\" lasso-nonce\u003e.my-inline-style { }\u003c/style\u003e\n```\n\nThe output HTML will be similar to the following:\n\n```html\n\u003cscript type=\"text/javascript\" nonce=\"abc123\"\u003econsole.log('My inline script')\u003c/script\u003e\n\u003cstyle type=\"text/css\" nonce=\"abc123\"\u003e.my-inline-style { }\u003c/style\u003e\n```\n\n## Securing Statically Built Pages\n\nIf your page is statically built (such as when creating a Single Page App)\nthen you should enable inline code fingerprinting which is way to whitelist\nexactly which inline code blocks should be allowed. It is important to\nemphasize, that a _nonce_ (\"number once\") will not properly secure a\nstatically built application since the HTML is built once which prevents\nthe nonce from changing. To secure your statically built application,\nyou should instead fingerprint all of the inline code blocks and include\nthese fingerprints in your CSP.\n\nHere is an example of what CSP might look like if using SHA256 fingerprints:\n`script-src 'self' 'sha256-viOn97JiWZ/fvh2VGIpROjZabjdtdrgtfO1wlPz9w7w='`\n\n```javascript\nrequire('lasso').configure({\n    /* typical configuration goes here */\n\n    // Configure Lasso with a function that will be called for fingerprinting\n    // each inline code block...\n    fingerprintInlineCode: function(code) {\n        var shasum = crypto.createHash('sha256');\n        shasum.update(code);\n        return shasum.digest('base64');\n    }\n});\n\n// This is the full list of fingerprints that were captured\n// across all page builds\nvar inlineCodeFingerprints = [];\n\n// Collect all of the fingerprints as each page is built\nrequire('lasso').getDefaultLasso().on('afterLassoPage', function(event) {\n    var lassoPageResult = event.result;\n    var fingerprints = lassoPageResult.getInlineCodeFingerprints();\n    fingerprints.forEach(function(fingerprint) {\n        inlineCodeFingerprints.push(fingerprint);\n    });\n})\n\n// NOW BUILD YOUR PAGES HERE\n// ... build code goes here ...\n\n// NOW BUILD YOUR CONTENT SECURITY POLICY:\nvar csp = inlineCodeFingerprints.map(function(fingerprint) {\n    return `script-src 'self' 'sha256-${fingerprint}'`\n}).join('; ');\n\n```\n\n# Available Plugins\n\nBelow is a list of plugins that are currently available:\n\n__Core plugins:__\n\n* [lasso-require](https://github.com/lasso-js/lasso-require): Node.js-style require for the browser (similar to [browserify](https://github.com/substack/node-browserify))\n* [lasso-minify-css](https://github.com/lasso-js/lasso-minify-css): Minify CSS files using [sqwish](https://github.com/ded/sqwish)\n* [lasso-minify-js](https://github.com/lasso-js/lasso-minify-js): Minify JavaScript files using [terser](https://github.com/terser-js/terser)\n* [lasso-resolve-css-urls](https://github.com/lasso-js/lasso-resolve-css-urls): Replace each resource URL in a CSS file with an lassoed resource URL\n\n__Third-party plugins__\n\n* [lasso-dust](https://github.com/lasso-js/lasso-dust): Compile [Dust](https://github.com/linkedin/dustjs) template files to JavaScript\n* [lasso-handlebars](https://github.com/lasso-js/lasso-handlebars): Compile [Handlebars](http://handlebarsjs.com/) template files to JavaScript\n* [lasso-image](https://github.com/lasso-js/lasso-image): Get image info (including URL, width and height) for any image on both the server and client\n* [lasso-imagemin](https://github.com/lasso-js/lasso-imagemin): Minify GIF, PNG, JPG and SVG images during optimization\n* [lasso-jade](https://github.com/lasso-js/lasso-jade): Compile [Jade](http://jade-lang.com/) templates to JavaScript\n* [lasso-jsx](https://github.com/lasso-js/lasso-jsx): Compile [JSX](http://facebook.github.io/react/docs/jsx-in-depth.html) files to JavaScript\n* [lasso-less](https://github.com/lasso-js/lasso-less): Compile [Less](http://lesscss.org/) files to CSS\n* [lasso-lodash](https://github.com/lasso-js/lasso-lodash): Compile [Lo-Dash](https://lodash.com/) files to JavaScript\n* [lasso-marko](https://github.com/lasso-js/lasso-marko): Compile [Marko template](https://github.com/marko-js/marko) files to JavaScript\n* [lasso-sass](https://github.com/lasso-js/lasso-sass): Compile [Sass](https://github.com/sass/node-sass) files to CSS\n* [lasso-stylus](https://github.com/lasso-js/lasso-stylus): Compile [Stylus](http://learnboost.github.io/stylus/) files to CSS\n* [lasso-clean-css](https://github.com/yomed/lasso-clean-css): Minify CSS files using [clean-css](https://github.com/jakubpawlowicz/clean-css)\n* [lasso-autoprefixer](https://github.com/lasso-js/lasso-autoprefixer): Autoprefix CSS with vendor prefixes using [autoprefixer-core](https://github.com/postcss/autoprefixer-core)\n* [lasso-modernizr](https://github.com/darkwebdev/lasso-modernizr): Generate custom [Modernizr](https://modernizr.com) build\n* [lasso-optimize-iife](https://github.com/austinkelleher/lasso-optimize-iife): Optimize JavaScript immediately-invoked functions using [optimize-js](https://github.com/nolanlawson/optimize-js)\n* [lasso-rtl-css](https://github.com/shadiabuhilal/lasso-rtl-css): Transform CSS from left-to-right to right-to-left using [rtlcss](https://github.com/MohammadYounes/rtlcss)\n* [lasso-prepack](https://github.com/austinkelleher/lasso-prepack): Optimize JavaScript using [prepack](https://prepack.io/)\n* [lasso-typescript](https://github.com/ajay2507/lasso-typescript): compile [Typescript](https://www.typescriptlang.org/) in to Javascript.\n* [grunt-lasso](https://github.com/ajay2507/grunt-lasso): [Grunt](https://gruntjs.com/) plugin for Lasso js.\n* [lasso-analyzer](https://github.com/ajay2507/lasso-analyzer): Bundle Analyzer plugin for Lasso js.\n* [lasso-unpack](https://github.com/ajay2507/lasso-unpack): Generating an asset manifest for all source files .\n* [lasso-minify-transpile-inline](https://github.com/dsathyakumar/lasso-minify-transpile-inline): Lasso JS plugin to minify \u0026 transpile `inline` single file dependency assets that are not of `type: require`.\n* [rollup-plugin-lasso](https://github.com/dsathyakumar/rollup-plugin-lasso/): Bundles with Rollup (in cases where Lasso cannot be used) and pipes the output to Lasso - to be a part of Lasso's lifecycle.\n\nTo use a third-party plugin, you must first install it using `npm install`. For example:\n\n```bash\nnpm install lasso-less --save\n```\n\nIf you create your own plugin please send a Pull Request and it will show up above. Also, do not forget to tag your plugin with `lasso-plugin` and `lasso` in your `package.json` so that others can browse for it using [npm](https://www.npmjs.org/)\n\n# Extending Lasso.js\n\nOnly read below if you are building plugins or transforms to further enhance the `lasso` module.\n\n## Custom Plugins\n\nA plugin can be used to change how the lasso operates. This includes the following:\n\n* Register a custom dependency to support dependencies that compile to JS or CSS\n    * Examples:\n        * Register a dependency handler for \"less\" files to compiles Less to CSS\n        * Register a dependency handler for \"marko\" files to compiles Marko template files to JS\n* Register a custom bundle writer\n    * Examples:\n        * Upload bundles to a resource server that backs a CDN instead of writing them to disk\n* Register output transforms\n    * Examples:\n        * Add an output transform to minify JavaScript code\n        * Add an output transform to minify CSS code\n        * Add an output transform to remove `console.log` from JS code\n        * Add an output transform to resolve image URLs in CSS files\n* Configure the lasso\n    * Examples:\n        * Allow a plugin to automatically configure the lasso for production usage\n\nA plugin is simply a Node.js module that exports a function with the following signature:\n\n```javascript\n/**\n * A plugin for Lasso.js\n * @param  {lasso/lib/Lasso} lasso An instance of a Lasso that can be configured\n * @param  {Object} The plugin configuration provided by the user\n */\nmodule.exports = function(lasso, config) {\n    // Register dependency types:\n    lasso.dependencies.registerJavaScriptType('my-js-type', require('./dependency-my-js-type'));\n    lasso.dependencies.registerStyleSheetType('my-css-type', require('./dependency-my-css-type'));\n    lasso.dependencies.registerPackageType('my-package-type', require('./dependency-my-package-type'));\n\n    // Add an output transform\n    lasso.addTransform(require('./my-transform'));\n\n    // Register a custom Node.js/CommonJS module compiler for a custom filename extension\n    // var myModule = require('./hello.test');\n    lasso.dependencies.registerRequireExtension('test', function(path, context, callback) {\n        callback(null, \"exports.sayHello = function() { console.log('Hello!'); }\");\n    });\n};\n```\n\n## Custom Dependency Types\n\nThere are three types of dependencies that are supported:\n\n* __JavaScript dependency:__ Produces JavaScript code\n* __CSS dependency:__ Produces CSS code\n* __Package dependency:__ Produces a package of additional JavaScript and CSS dependencies\n\nEach of these dependencies is described in the next few sections. However, it is recommended to also check out the source code of [available plugins](#available-plugins) listed above (e.g. [lasso-less](https://github.com/lasso-js/lasso-less)).\n\n### Custom JavaScript Dependency Type\n\nIf you would like to introduce your own custom dependency types then you will need to have your plugin register a dependency handler. This is illustrated in the following sample code:\n\n```javascript\nconst fs = require('fs');\n\nmodule.exports = function myPlugin(lasso, config) {\n    lasso.dependencies.registerJavaScriptType(\n        'my-custom-type',\n        {\n            // Declare which properties can be passed to the dependency type\n            properties: {\n                'path': 'string'\n            },\n\n            // Validation checks and initialization based on properties:\n            async init (context) {\n                if (!this.path) {\n                    throw new Error('\"path\" is required');\n                }\n\n                // NOTE: resolvePath can be used to resolve a provided relative path to a full path\n                this.path = this.resolvePath(this.path);\n            },\n\n            // Read the resource:\n            async read (context) {\n                const src = await fs.promises.readFile(this.path, {encoding: 'utf8'});\n                return myCompiler.compile(src);\n                // NOTE: A stream can also be returned\n            },\n\n            // getSourceFile is optional and is only used to determine the last modified time\n            // stamp and to give the output file a reasonable name when bundling is disabled\n            getSourceFile: function() {\n                return this.path;\n            }\n        });\n};\n```\n\nOnce registered, the above dependency can then be referenced from an `browser.json` as shown in the following code:\n\n```json\n{\n    \"dependencies\": [\n        \"my-custom-type: hello.file\"\n    ]\n}\n```\n\nIf a custom dependency supports more than just a `path` property, additional properties could be provided as shown in the following sample code:\n\n```json\n{\n    \"dependencies\": [\n        {\n            \"type\": \"my-custom-type\",\n            \"path\": \"hello.file\",\n            \"foo\": \"bar\",\n            \"hello\": true\n        }\n    ]\n}\n```\n\n\n### Custom CSS Dependency Type\n\nIf you would like to introduce your own custom dependency types then you will need to have your plugin register a dependency handler as shown in the following sample code:\n\n```javascript\nmodule.exports = function myPlugin(lasso, config) {\n    lasso.dependencies.registerStyleSheetType(\n        'my-custom-type',\n        handler);\n};\n```\n\nThe `handler` argument for a CSS dependency has the exact same interface as a handler for a JavaScript dependency (described earlier).\n\n### Custom Package Type\n\nA custom package dependency can be used to dynamically resolve additional dependencies at optimization time. The sample package dependency handler below illustrates how a package dependency can be used to automatically include every file in a directory as a dependency:\n\n```javascript\nconst { promisify } = require('util');\nconst fs = promisify(require('fs'));\nconst path = promisify(require('path'));\n\nlasso.dependencies.registerPackageType('dir', {\n    properties: {\n        'path': 'string'\n    },\n\n    async init (context) {\n        let path = this.path;\n\n        if (!path) {\n            callback(new Error('\"path\" is required'));\n        }\n\n        this.path = path = this.resolvePath(path); // Convert the relative path to an absolute path\n\n        const stat = await fs.stat(path);\n        if (!stat.isDirectory()) {\n            throw new Error('Directory expected: ' + path);\n        }\n    },\n\n    async getDependencies (context) {\n        const dir = this.path;\n        const filenames = await fs.readdir(dir);\n\n        // Convert the filenames to full paths\n        var dependencies = filenames.map(function(filename) {\n            return path.join(dir, filename);\n        });\n\n        return dependencies;\n    },\n\n    getDir: function() {\n        // If the dependencies are associated with a directory then return that directory.\n        // Otherwise, return null\n        return this.path;\n    }\n});\n```\n\n## Custom Output Transforms\n\nRegistered output transforms are used to process bundles as they are written to disk. As an example, an output transform can be used to minify a JavaScript or CSS bundle. Another example is that an output transform may be used to remove `console.log` statements from output JavaScript code. Transforms should be registered by a plugin using the `lasso.addTransform(transform)` method.\n\nAs an example, the following unhelpful transform will convert all JavaScript source code to upper case:\n\n```javascript\nmodule.exports = function (lasso, pluginConfig) {\n    lasso.addTransform({\n\n        // Only apply to JavaScript code\n        contentType: 'js', //  'css' is the other option\n\n        // Give your module a friendly name (helpful for debugging in case something goes wrong in your code)\n        name: module.id,\n\n        // If stream is set to false then a String will be provided. Otherwise, a readable stream will be provided\n        stream: false,\n\n        // Do the magic:\n        transform: function(code, lassoContext) {\n            return code.toUpperCase();\n        }\n    });\n};\n```\n\nBelow is the streaming version of the same transform:\n\n```javascript\nvar through = require('through');\n\nmodule.exports = function (lasso, pluginConfig) {\n    lasso.addTransform({\n\n        // Only apply to JavaScript code\n        contentType: 'js', // 'css' is the other option\n\n        // Give your module a friendly name (helpful for debugging in case something goes wrong in your code)\n        name: module.id,\n\n        stream: true, // We want the code to be streamed to us\n\n        // Do the magic:\n        transform: function(inStream, lassoContext) {\n            return inStream.pipe(through(\n                function write(data) {\n                    this.queue(data.toUpperCase());\n                }));\n        }\n    });\n};\n```\n\n# JavaScript API\n\nSee [JavaScript API](./docs/javascript-api.md).\n\n# AMD Compatibility\n\nSee [AMD Compatibility](./docs/amd.md).\n\n# Sample Projects\n\n* [lasso-js-samples/lasso-async](https://github.com/lasso-js-samples/lasso-async): Demonstrates asynchronous/lazy dependency loading.\n* [lasso-js-samples/lasso-cli](https://github.com/lasso-js-samples/lasso-cli): Demonstrates the command-line interface.\n* [lasso-js-samples/lasso-code-splitting](https://github.com/lasso-js-samples/lasso-code-splitting): Demonstrates splitting out dependencies that are common across pages into a separate bundle.\n* [lasso-js-samples/lasso-config](https://github.com/lasso-js-samples/lasso-config): Demonstrates the usage of a JSON config file.\n* [lasso-js-samples/lasso-express](https://github.com/lasso-js-samples/lasso-express): Demonstrates using Lasso.js at runtime as part of an Express server app.\n* [lasso-js-samples/lasso-js-api](https://github.com/lasso-js-samples/lasso-js-api): Demonstrates how to use JavaScript API to lasso a page and inject the resulting head and body markup into a page.\n* [lasso-js-samples/lasso-taglib](https://github.com/lasso-js-samples/lasso-taglib): Demonstrates the use of the lasso taglib for Marko.\n* [lasso-js-samples/lasso-templates](https://github.com/lasso-js-samples/lasso-templates): Demonstrates the use of rendering the same templates on both the server and the client.\n\n# Discuss\n\nPlease join us in the [Gitter chat room for Lasso.js](https://gitter.im/lasso-js/lasso) or [open a new Github issue](https://github.com/lasso-js/lasso/issues).\n\n# Maintainers\n\n* [Patrick Steele-Idem](https://github.com/patrick-steele-idem) (Twitter: [@psteeleidem](http://twitter.com/psteeleidem))\n* [Phillip Gates-Idem](https://github.com/philidem/) (Twitter: [@philidem](https://twitter.com/philidem))\n* [Michael Rawlings](https://github.com/mlrawlings) (Twitter: [@mlrawlings](https://twitter.com/mlrawlings))\n\n# Contributors\n\n* Vinod Kumar (Twitter: [@vinodl](https://twitter.com/vinodl))\n    - [gulp-lasso](https://github.com/lasso-js/gulp-lasso)\n    - [lasso-jsx](https://github.com/lasso-js/lasso-jsx)\n* Merwan Rodriguez (Twitter: [@uno7](https://twitter.com/uno7))\n    - [lasso-autoprefixer](https://github.com/lasso-js/lasso-autoprefixer)\n\n# Contribute\n\nPull Requests welcome. Please submit Github issues for any feature enhancements, bugs or documentation problems.\n\n# License\n\nApache License v2.0\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flasso-js%2Flasso","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flasso-js%2Flasso","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flasso-js%2Flasso/lists"}