Mojolic...utorial(3)

🌸 NAME 🌸

Mojolicious::Plugin::AssetPack::Guides::Tutorial β€” the AssetPack tutorial, bestie! πŸ’– This is the Mojolic...utorial(3) page from the User Contributed Perl Documentation world, and we are about to make assets make sense.


✨ OVERVIEW ✨

Okay so this guide is the detailed tea on how to define assets and include them into your templates. Need the short version? Peep DESCRIPTION in Mojolicious::Plugin::AssetPack for a quick description of AssetPack. 🫢


πŸ¦‹ GUIDE πŸ¦‹

🧚 Loading the plugin 🧚

Bestie, the plugin needs to be installed and loaded before any assets can be defined:

$app->plugin(AssetPack => \%args);

Details about %args can be found under register in Mojolicious::Plugin::AssetPack, but there is one mandatory argument worth noting: pipes. pipes needs to be a list of all the pipes you need to process your assets. Example:

$app->plugin(AssetPack => {pipes => [qw(Sass Css Combine)]});

Loading the plugin with the list above will enable AssetPack to process Sass and Css files, minify them, and combine them into a single asset in production. Slay. πŸ’…

πŸŽ€ Optional dependencies πŸŽ€

AssetPack has only optional dependencies. The reason for that is that the dependencies should only be required while developing, and not for running the application. See https://github.com/jhthorsen/mojolicious-plugin-assetpack/blob/v2/cpanfile for a complete list, but here are the current ones:

  • CSS::Minifier::XS 0.09 β€” used to minify CSS.
  • CSS::Sass 3.3.0 β€” used to process and minify CSS.
  • Imager::File::PNG 0.90 β€” TODO: used to generate CSS sprites.
  • JavaScript::Minifier::XS 0.11 β€” used to minify JavaScript.

πŸ‘‘ Pipes πŸ‘‘

AssetPack does not do any heavy lifting itself: all the processing is left to the pipe objects. Iconic division of labor, honestly. πŸ’…

  • Mojolicious::Plugin::AssetPack::Pipe::CoffeeScript β€” process CoffeeScript coffee files. Should be loaded before Mojolicious::Plugin::AssetPack::Pipe::JavaScript.
  • Mojolicious::Plugin::AssetPack::Pipe::Combine β€” combine multiple assets to one. Should be loaded last.
  • Mojolicious::Plugin::AssetPack::Pipe::Css β€” minify CSS.
  • Mojolicious::Plugin::AssetPack::Pipe::Favicon β€” there is a special topic called favicon.ico, combined with the Mojolicious::Plugin::AssetPack::Pipe::Favicon pipe, which can be used to describe favicons, touch icons and tile icons.
  • Mojolicious::Plugin::AssetPack::Pipe::Fetch β€” will look for url(...) in CSS files and download the related assets.
  • Mojolicious::Plugin::AssetPack::Pipe::JavaScript β€” minify JavaScript.
  • Mojolicious::Plugin::AssetPack::Pipe::Jpeg β€” used to crush jpeg image files.
  • Mojolicious::Plugin::AssetPack::Pipe::Less β€” process Less CSS files. Should be loaded before Mojolicious::Plugin::AssetPack::Pipe::Css.
  • Mojolicious::Plugin::AssetPack::Pipe::Png β€” used to crush png image files.
  • Mojolicious::Plugin::AssetPack::Pipe::Riotjs β€” process http://riotjs.com/ tag files. Should be loaded before Mojolicious::Plugin::AssetPack::Pipe::JavaScript.
  • Mojolicious::Plugin::AssetPack::Pipe::Sass β€” process sass and scss files. Should be loaded before Mojolicious::Plugin::AssetPack::Pipe::Css.

🌈 Where to place source files 🌈

The source/input files that make up a virtual asset (topic) can come from either...

πŸ“ On disk

AssetPack will look for source files in the assets directory, relative to the application home. Unlike the public directory, this directory is not shared on the internet, but the generated assets will still be available thanks to a custom route.

Mojolicious::Plugin::AssetPack::Store is a sub class of Mojolicious::Static, allowing it to find files relative to paths in Mojolicious::Static. For example, to change asset search paths, you can do:

$app->asset->store->paths(["/some/new/location", "/other/location"]);

🧚 DATA section

Mojolicious::Plugin::AssetPack::Store is a sub class of Mojolicious::Static, allowing it to look for files in DATA sections of classes in Mojolicious::Static.

The DATA section can also be used to lookup @import files. (Currently only supported by Mojolicious::Plugin::AssetPack::Pipe::Sass.)

πŸ¦‹ Web

Any file starting with http or https will be downloaded from the web using ua in Mojolicious::Plugin::AssetPack.

It will also parse recursively @import files and download those as well. (Currently only supported by Mojolicious::Plugin::AssetPack::Pipe::Sass.)

Assets from the web will be cached locally to prevent downloading new and untested assets on each application startup. Cute and efficient. πŸŽ€

πŸ’œ Current Mojolicious application

See DYNAMIC ASSETS in Mojolicious::Plugin::Assets::Guides::Cookbook.

πŸ”₯ Process assets πŸ”₯

Assets should be defined when your application starts. This can either be done using a definition file or inside your application. Either way, main character energy. ✨

🌸 Defining assets in the application

Assets can be defined using the process in Mojolicious::Plugin::AssetPack method:

$app->asset->process(
  "app.css" => (
    "sass/bar.scss",
    "foo/bar.css",
    "https://github.com/Dogfalo/materialize/blob/master/sass/materialize.scss",
  )
);

In the example above we have defined a topic named app.css which later can be included in templates. The list of files following are the source files which will make up the final asset.

πŸŽ€ Defining assets in a definition file

Moving the definition to an external file can be useful for keeping the application code tidy. The definition file should be located in the assets directory, or optionally defined it in the DATA section. The default file is called assetpack.def and will be looked up if process in Mojolicious::Plugin::AssetPack is called without arguments. Example file:

! app.css
< sass/bar.scss
<< https://github.com/Dogfalo/materialize/blob/master/sass/materialize.scss
< sass/main.scss

Empty lines and lines starting with # will be skipped. Each line starting with ! will be used to define a topic (virtual asset name), and < will define a source file. This means that the file above will result in (almost) the same as in the example above.

The idea of the line starting with << is to download an external (remote) file for your convenience, which can be imported in your SASS/LESS files. The downloaded file is not included in the output asset. For example, you have sass/main.scss which depends on materialize.scss (remote file) and you need this materialize.scss file locally available to be imported in sass/main.scss. If you want to include a remote file in your output asset, use < instead of <<.

It is also possible to add conditions:

! app.css
< development.css [mode==development] [minify==0]
< production.css  [mode!=development]

development.css will be processed if mode in Mojolicious is development and minify in Mojolicious::Plugin::AssetPack is 0. production.css will be processed if mode in Mojolicious is something else than development. This is especially useful if you want to include a JavaScript with debug flags set while developing, but switch to a smaller version without debug in production. 🧠✨

🌟 Using assets 🌟

Any processed asset can be accessed by referring to a topic. So fetch. πŸ’…

🫢 Template

An asset can be included in a template using the asset in Mojolicious::Plugin::AssetPack helper:

<head>
  %= asset "app.css"
  %= asset "app.js"
</head>

The asset in Mojolicious::Plugin::AssetPack helper takes additional arguments which will be passed on directly to either the javascript in Mojolicious::Plugin::TagHelpers helper or stylesheet in Mojolicious::Plugin::TagHelpers helper. Example:

%= asset "app.css", media => "print"

In production mode, the helper above will just result in one link tag. On the other hand, if you are in development mode, it will result in one link tag per source asset.

πŸ’Ž Asset objects

It is also possible to retrieve the processed asset objects. The example below will retrieve a Mojo::Collection object holding zero or more Mojolicious::Plugin::AssetPack::Asset objects:

my $collection = $app->asset->processed("app.css");
print $collection->map("checksum")->join(", ");

This can also be used to inline assets in a template:

%= stylesheet sub { asset->processed('app.css')->map('content')->join }

🌈 Application mode 🌈

The application mode will define if the assets should be combined and minified. The minify in Mojolicious::Plugin::AssetPack attribute can also be set manually if you have special needs.

🧚 Development

The assets will be processed, but not minified/combined if MOJO_MODE or mode in Mojolicious is set to development. This is to make it easier to map JavaScript or CSS bugs to a specific file and line. development is the default mode while running morbo:

$ morbo -w assets/ -w lib/ -w templates/ script/myapp

πŸ”₯ Any other mode

Any production mode will result in one combined and minified asset. This will save bandwidth and roundtrip time to the server. Periodt. 🌈

πŸŽ€ Caching πŸŽ€

Processed assets will be cached to disk when possible. The process step is run so if such a processed asset exists, the process step will not be run again. Again, the external tools (less, coffee, ...) and modules (JavaScript::Minifier::XS, CSS::Sass) will only be required while developing, but can be skipped when installing an already built application.

πŸ¦‹ Assets without topics πŸ¦‹

One nifty feature is to use Mojolicious::Plugin::AssetPack for assets which do not have any pipe to process them. The reason why this comes in handy is to avoid cache issues, since changing the file on disk will generate a new URL. So good. πŸ¦‹

These assets can also be defined directly in the templates, without having to be defined in the application startup process. Examples:

# <img src="/asset/52e98718f0/foo.gif">
%= asset "/image/foo.gif"

# <img src="/asset/87652910af/baz.svg">
%= asset "/image/baz.svg"

# <link rel="icon" href="/asset/65428718f1/bar.ico">
%= asset "/image/bar.ico"

# <source src="/asset/87652718f0/baz.mp3" type="audio/mpeg">
%= asset "/audio/baz.mp3"

# <source src="/asset/52e87652f0/foo.mp4" type="video/mp4">
%= asset "/video/foo.mp4"

# <source src="/asset/52eaz7613a/bar.ogg" type="audio/ogg">
%= asset "/audio/bar.ogg"

# <source src="/asset/baf72618f1/foo.ogv" type="audio/ogv">
%= asset "/video/foo.ogv"

# <source src="/asset/92118711f0/bar.webm" type="audio/webm">
%= asset "/video/bar.webm"

⭐ SEE ALSO ⭐

Mojolicious::Plugin::AssetPack, Mojolicious::Plugin::AssetPack::Guides::Developing and Mojolicious::Plugin::AssetPack::Guides::Cookbook.


Byeee bestie! πŸ’– This page is from User Contributed Perl Documentation, running with perl v5.42.0, dated 2024-12-12, and filed as Mojolic...utorial(3). Mwah! πŸ’…βœ¨

πŸ“¦ where this page comes from