README.md in hanami-assets-1.3.5 vs README.md in hanami-assets-2.1.0.beta2
- old
+ new
@@ -3,12 +3,12 @@
Assets management for Ruby web projects
## Status
[![Gem Version](https://badge.fury.io/rb/hanami-assets.svg)](https://badge.fury.io/rb/hanami-assets)
-[![CI](https://github.com/hanami/assets/workflows/ci/badge.svg?branch=master)](https://github.com/hanami/assets/actions?query=workflow%3Aci+branch%3Amaster)
-[![Test Coverage](https://codecov.io/gh/hanami/assets/branch/master/graph/badge.svg)](https://codecov.io/gh/hanami/assets)
+[![CI](https://github.com/hanami/assets/workflows/ci/badge.svg?branch=main)](https://github.com/hanami/assets/actions?query=workflow%3Aci+branch%3Amain)
+[![Test Coverage](https://codecov.io/gh/hanami/assets/branch/main/graph/badge.svg)](https://codecov.io/gh/hanami/assets)
[![Depfu](https://badges.depfu.com/badges/4b37347bd74042ff96477495cc16531d/overview.svg)](https://depfu.com/github/hanami/assets?project=Bundler)
[![Inline Docs](http://inch-ci.org/github/hanami/assets.svg)](http://inch-ci.org/github/hanami/assets)
## Contact
@@ -22,18 +22,18 @@
* Forum: https://discuss.hanamirb.org
* Chat: http://chat.hanamirb.org
## Rubies
-__Hanami::Assets__ supports Ruby (MRI) 2.3+ and JRuby 9.1.5.0+
+__Hanami::Assets__ supports Ruby (MRI) 3.0+
## Installation
Add this line to your application's Gemfile:
```ruby
-gem 'hanami-assets'
+gem "hanami-assets"
```
And then execute:
```shell
@@ -46,30 +46,35 @@
$ gem install hanami-assets
```
## Usage
+### Command Line (CLI)
+
+During development run `bundle exec hanami server`.
+Your app will start the assets management.
+
### Helpers
-`Hanami::Assets` provides asset-specific helpers to be used in templates.
+Hanami Assets provides asset-specific helpers to be used in templates.
They resolve one or multiple sources into corresponding HTML tags.
Those sources can be either a name of a local asset or an absolute URL.
Given the following template:
```erb
<!doctype HTML>
<html>
<head>
<title>Assets example</title>
- <%= stylesheet 'reset', 'grid', 'main' %>
+ <%= assets.css "reset", "app" %>
</head>
<body>
<!-- ... -->
- <%= javascript 'https://code.jquery.com/jquery-2.1.1.min.js', 'application' %>
- <%= javascript 'modals' %>
+ <%= assets.js "app" %>
+ <%= assets.js "https://cdn.somethirdparty.script/foo.js", async: true %>
</body>
</html>
```
It will output this markup:
@@ -78,353 +83,149 @@
<!doctype HTML>
<html>
<head>
<title>Assets example</title>
<link href="/assets/reset.css" type="text/css" rel="stylesheet">
- <link href="/assets/grid.css" type="text/css" rel="stylesheet">
- <link href="/assets/main.css" type="text/css" rel="stylesheet">
+ <link href="/assets/app.css" type="text/css" rel="stylesheet">
</head>
<body>
<!-- ... -->
- <script src="https://code.jquery.com/jquery-2.1.1.min.js" type="text/javascript"></script>
- <script src="/assets/application.js" type="text/javascript"></script>
- <script src="/assets/modals.js" type="text/javascript"></script>
+ <script src="/assets/app.js" type="text/javascript"></script>
+ <script src="https://cdn.somethirdparty.script/foo.js" type="text/javascript" async></script>
</body>
</html>
```
-Let's have a look at the corresponding Ruby code.
-In this example we use ERb, but remember that `Hanami::Assets` is compatible with
-all the rendering engines such as HAML, Slim, Mustache, etc..
-
-```ruby
-require 'erb'
-require 'hanami/assets'
-require 'hanami/assets/helpers'
-
-class View
- include Hanami::Assets::Helpers
-
- def initialize
- @template = File.read('template.erb')
- @engine = ERB.new(@template)
- end
-
- def render
- @engine.result(binding)
- end
-end
-
-View.new.render # => HTML markup
-```
-
-For advanced configurations, please have a look at
-[`Hanami::Assets::Configuration`](https://github.com/hanami/assets/blob/master/lib/hanami/assets/configuration.rb).
-
### Available Helpers
This gem ships with the following helpers:
- * `javascript`
- * `stylesheet`
+ * `javascript` (aliased as `js`)
+ * `stylesheet` (aliased as `css`)
* `favicon`
- * `image`
+ * `image` (aliased as `img`)
* `video`
* `audio`
- * `asset_path`
- * `asset_url`
+ * `path`
-### Development mode
+## App Structure
-`Hanami::Assets` can help you during the development process of your application.
-It can manage multiple source directories for each asset type or run a
-preprocessor for you.
+Hanami applications are generated via `hanami new` CLI command.
-#### Sources
+Among other directories, it generates a specific structure for assets:
-Imagine to have your application's javascripts under `app/assets/javascripts` and that
-those assets depends on a vendored version of jQuery.
-
-```ruby
-require 'hanami/assets'
-
-Hanami::Assets.configure do
- compile true
-
- sources << [
- 'app/assets',
- 'vendor/jquery'
- ]
-end
-```
-
-When from a template you do:
-
-```erb
-<%= javascript 'jquery', 'jquery-ui', 'login' %>
-```
-
-`Hanami::Assets` looks at the defined sources and **lazily copies** those files
-under `public/assets` (by default), before the markup is generated.
-
-Your public directory will have the following structure.
-
```shell
-% tree public
-public/
-└── assets
- ├── jquery.js
- ├── jquery-ui.js
- └── login.js
-
+$ tree app/assets
+├── images
+│ └── favicon.ico
+├── javascripts
+│ └── app.ts
+└── stylesheets
+ └── app.css
```
-**Please remember that sources are recursively looked up in order of declaration.**
+#### Entry Points
-If in the example above we had a `jquery.js` under `app/assets/javascripts/**/*.js`
-that file would be copied into the public directory instead of the one under
-`vendor/jquery`. The reason is because we declared `app/assets/javascripts` first.
+Entry Points are the JavaScript files or modules that serve as the starting points of your application.
+They define the scope of your bundling process and determine which parts of your code will be included in the final output.
+By understanding the dependencies of your entry points, Hanami Assets can create efficient and optimized bundles for your JavaScript or TypeScript applications.
-#### Preprocessors
+When Hanami Assets encounters an import or require statement for an asset, it process the asset file to the output directory.
+This process includes any kind of asset: other JavaScript files, stylesheets, images **referenced from the Entry Point**.
-`Hanami::Assets` is able to run assets preprocessors and **lazily compile** them
-under `public/assets` (by default), before the markup is generated.
+The default entry points are:
-Imagine you have `main.css.scss` under `app/assets/stylesheets` and `reset.css` under
-`vendor/stylesheets`.
+ * `app/assets/javascripts/app.ts`
+ * `slices/[slice-name]/assets/javascripts/app.ts`
-**The two extensions are important.**
-The first one is mandatory and it's used to understand which asset type we are
-handling: `.css` for stylesheets.
-The second one is optional and it's for a preprocessor: `.scss` for Sass.
+You can specify custom Entry Points, by adding an `app.{js,ts,mjs,mts,tsx,jsx}` file into the assets directory of the app or a slice.
-```ruby
-require 'sassc'
-require 'hanami/assets'
+An example is: `app/assets/javascripts/login/app.ts` to define a new Entry Point for a Login page where you want to have a more lightweight bundle.
-Hanami::Assets.configure do
- compile true
+#### Static Assets
- sources << [
- 'assets',
- 'vendor/assets'
- ]
-end
-```
+Except for `javascripts` and `stylesheets` directories, all the other directories are considered **static**.
+Their files will be copied as they are to the destination directory.
-And in a template you can use the `stylesheet` helper:
+If you have a custom directory `app/assets/fonts`, all the fonts are copied to the destination direcotry.
-```erb
-<%= stylesheet 'reset', 'main' %>
-```
+#### Destination Directory
-Your public directory will look like this:
+The destination directory is `public/assets`.
-```shell
-% tree public
-public/
-└── assets
- ├── reset.css
- └── main.css
-```
+### Sources
-### Preprocessors engines
+Hanami Assets works with [Yarn](https://yarnpkg.com/).
-`Hanami::Assets` uses [Tilt](https://github.com/rtomayko/tilt) to provide support for the most common preprocessors, such as [Sass](http://sass-lang.com/) (including `sassc-ruby`), [Less](http://lesscss.org/), [ES6](https://babeljs.io/), [JSX](https://jsx.github.io/), [CoffeScript](http://coffeescript.org), [Opal](http://opalrb.com), [Handlebars](http://handlebarsjs.com), [JBuilder](https://github.com/rails/jbuilder).
+In order to add/remove a source to your application, you should follow Yarn's dependencies management.
-In order to use one or more of them, be sure to add the corresponding gem to your `Gemfile` and require the library.
+### Preprocessors
-#### EcmaScript 6
+Hanami Assets is able to preprocess any kind of JavaScript and CSS flavor.
-We strongly suggest you use [EcmaScript 6](http://es6-features.org/) for your next project.
-It isn't fully [supported](https://kangax.github.io/compat-table/es6/) yet by browsers, but it's the future of JavaScript.
-
-As of today, you need to 'transpile' ES6 code into ES5, which current browsers understand.
-The most popular tool for this is [Babel](https://babeljs.io), which we support.
-
### Deployment
-`Hanami::Assets` ships with an executable (`hanami-assets`), which can be used to precompile assets and make them cacheable by browsers (via checksum suffix).
+To process the assets during deployment run `bundle exec hanami assets compile`.
-__NOTE__: If you're using `Hanami::Assets` with the full `Hanami` framework, you should use `bundle exec hanami assets precompile` instead of `hanami-assets`.
+The destination directory will contain the processed assets with an hashed name.
-Let's say we have an application that has a main file that requires the entire codebase (`config/environment.rb`), a gem that brings in Ember.js code, and the following sources:
+#### Fingerprint Mode
-```shell
-% tree .
-├── apps
-│ ├── admin
-│ │ ├── assets
-│ │ │ └── js
-│ │ │ ├── application.js
-│ │ │ └── zepto.js
-# ...
-│ ├── metrics
-│ │ ├── assets
-│ │ │ └── javascripts
-│ │ │ └── dashboard.js
-# ...
-│ └── web
-│ ├── assets
-│ │ ├── images
-│ │ │ └── bookshelf.jpg
-│ │ └── javascripts
-│ │ └── application.js
-# ...
-│ └── vendor
-│ └── assets
-│ └── javascripts
-│ └── jquery.js
-└── config
- └── environment.rb
-```
+Asset fingerprinting is a technique that involves adding a unique identifier to the filenames of static assets to ensure cache-busting.
+By doing so, you can safely cache and deliver updated versions of assets to client browsers, avoiding the use of outdated cached versions and ensuring a consistent and up-to-date user experience.
-In order to deploy, we can run:
+During the deployment process, Hanami Assets appends to the file name a unique hash.
-```shell
-bundle exec hanami-assets --config=config/environment.rb
-```
+Example: `app/assets/javascripts/app.ts` -> `public/assets/app-QECGTTYG.js`
-It will output:
+It creates a `/public/assets.json` to map the original asset name to the fingerprint name.
-```shell
-tree public
-public
-├── assets
-│ ├── admin
-│ │ ├── application-28a6b886de2372ee3922fcaf3f78f2d8.js
-│ │ ├── application.js
-│ │ ├── ember-b2d6de1e99c79a0e52cf5c205aa2e07a.js
-│ │ ├── ember-source-e74117fc6ba74418b2601ffff9eb1568.js
-│ │ ├── ember-source.js
-│ │ ├── ember.js
-│ │ ├── zepto-ca736a378613d484138dec4e69be99b6.js
-│ │ └── zepto.js
-│ ├── application-d1829dc353b734e3adc24855693b70f9.js
-│ ├── application.js
-│ ├── bookshelf-237ecbedf745af5a477e380f0232039a.jpg
-│ ├── bookshelf.jpg
-│ ├── ember-b2d6de1e99c79a0e52cf5c205aa2e07a.js
-│ ├── ember-source-e74117fc6ba74418b2601ffff9eb1568.js
-│ ├── ember-source.js
-│ ├── ember.js
-│ ├── jquery-05277a4edea56b7f82a4c1442159e183.js
-│ ├── jquery.js
-│ └── metrics
-│ ├── dashboard-7766a63ececc63a7a629bfb0666e9c62.js
-│ ├── dashboard.js
-│ ├── ember-b2d6de1e99c79a0e52cf5c205aa2e07a.js
-│ ├── ember-source-e74117fc6ba74418b2601ffff9eb1568.js
-│ ├── ember-source.js
-│ └── ember.js
-└── assets.json
-```
+The simple usage of the `js` helper, will be automatically mapped for you:
-#### Compressors
-
-Minification is a process that shrinks file size in production, by removing unnecessary spaces and characters.
-The goal of this step is to have lighter assets, which will be served faster to browsers.
-
-Hanami supports JavaScript and stylesheet minifiers.
-
-Because this framework relies on external gems for minification, this feature is **turned off by default**.
-
-To use minification, we need to specify which gem we want to use and add it to our `Gemfile`.
-
-##### JavaScript Compressors
-
-Hanami can use the following compressors (aka minifiers) for JavaScript.
-
- * `:builtin` - Ruby based implementation of jsmin. It doesn't require any external gem.
- * `:yui` - [YUI Compressor](http://yui.github.io/yuicompressor), it depends on [`yui-compressor`](https://rubygems.org/gems/yui-compressor) gem and it requires Java 1.4+
- * `:uglifier` - [UglifyJS](http://lisperator.net/uglifyjs), it depends on [`uglifier`](https://rubygems.org/gems/uglifier) gem and it requires Node.js
- * `:closure` - [Google Closure Compiler](https://developers.google.com/closure/compiler), it depends on [`closure-compiler`](https://rubygems.org/gems/closure-compiler) gem and it requires Java
-
-```ruby
-Hanami::Assets.configure do
- javascript_compressor :uglifier
-end
-```
-
-##### Stylesheet Compressors
-
-Hanami can use the following compressors (aka minifiers) for stylesheets.
-
- * `:builtin` - Ruby based compressor. It doesn't require any external gem. It's fast, but not an efficient compressor.
- * `:yui` - [YUI Compressor](http://yui.github.io/yuicompressor), it depends on [`yui-compressor`](https://rubygems.org/gems/yui-compressor) gem and it requires Java 1.4+
- * `:sass` - [Sass](http://sass-lang.com/), it depends on [`sassc`](https://rubygems.org/gems/sassc) gem
-
-```ruby
-Hanami::Assets.configure do
- stylesheet_compressor :sass
-end
-```
-
-##### Custom Compressors
-
-We can specify our own minifiers:
-
-```ruby
-Hanami::Assets.configure do
- javascript_compressor MyJavascriptCompressor.new
- stylesheet_compressor MyStylesheetCompressor.new
-end
-```
-
-### Fingerprint Mode
-
-This is a mode that can be activated via configuration and it's suitable for production environments.
-When generating files, it adds a string to the end of each file name, which is a [checksum](https://en.wikipedia.org/wiki/Checksum) of its contents.
-This lets you leverage caching while still ensuring that clients get the most up-to-date assets (this is known as *cache busting*).
-
-```ruby
-Hanami::Assets.configure do
- fingerprint true
-end
-```
-
-Once turned on, it will look at `/public/assets.json`, and helpers such as `javascript` will return a relative URL that includes the fingerprint of the asset.
-
```erb
-<%= javascript 'application' %>
+<%= assets.js "app" %>
```
```html
-<script src="/assets/application-d1829dc353b734e3adc24855693b70f9.js" type="text/javascript"></script>
+<script src="/assets/app-QECGTTYG.js" type="text/javascript"></script>
```
-### Subresource Integrity (SRI) Mode
+#### Subresource Integrity (SRI) Mode
-This is a mode that can be activated via the configuration and it's suitable for production environments.
+Subresource Integrity (SRI) is a security mechanism that allows browsers to verify the integrity of external resources by comparing their content against a cryptographic hash. It helps protect against unauthorized modifications to external scripts and enhances the security and trustworthiness of web applications.
```ruby
-Hanami::Assets.configure do
- subresource_integrity true
+module MyApp
+ class App < Hanami::App
+ config.assets.subresource_integrity = ["sha-384"]
+ end
end
```
Once turned on, it will look at `/public/assets.json`, and helpers such as `javascript` will include an `integrity` and `crossorigin` attribute.
```erb
-<%= javascript 'application' %>
+<%= assets.js "app" %>
```
```html
-<script src="/assets/application-d1829dc353b734e3adc24855693b70f9.js" type="text/javascript" integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC" crossorigin="anonymous"></script>
+<script src="/assets/app-QECGTTYG.js" type="text/javascript" integrity="sha384-d9ndh67iVrvaACuWjEDJDJlThKvAOdILG011RxYJt1dQynvf4JXNORcUiZ9nO7lP" crossorigin="anonymous"></script>
```
-### CDN Mode
+#### Content Delivery Network (CDN) Mode
+A Content Delivery Network (CDN) is a globally distributed network of servers strategically located in multiple geographical locations.
+CDNs are designed to improve the performance, availability, and scalability of websites and web applications by reducing latency and efficiently delivering content to end users.
+
A Hanami project can serve assets via a Content Delivery Network (CDN).
```ruby
-Hanami::Assets.configure do
- scheme 'https'
- host '123.cloudfront.net'
- port 443
- cdn true
+module MyApp
+ class App < Hanami::App
+ config.assets.base_url = "https://123.cloudfront.net"
+ end
end
```
From now on, helpers will return the absolute URL for the asset, hosted on the CDN specified.
@@ -434,51 +235,30 @@
```html
<script src="https://123.cloudfront.net/assets/application-d1829dc353b734e3adc24855693b70f9.js" type="text/javascript"></script>
```
-## Standalone mode
-
-If you're using `hanami-assets` without `hanami`, you must explicitly boot the framework with:
-
-```ruby
-Hanami::Assets.configure do
- # ...
-end.load!
+```erb
+<%= assets.js "app" %>
```
-or
-
-```ruby
-Hanami::Assets.configure do
- # ...
-end
-
-# ...
-
-Hanami::Assets.load!
+```html
+<script src="https://123.cloudfront.net/assets/app-QECGTTYG.js" type="text/javascript"></script>
```
-## Third party gems
+NOTE: We suggest to use SRI mode when using CDN.
-Developers can maintain gems that distribute assets for Hanami. For instance `hanami-ember` or `hanami-jquery`.
+## Development
-To do this, inside your gem you have tell `Hanami::Assets` where to look for assets:
+Install:
-```ruby
-# lib/hanami/jquery.rb
-Hanami::Assets.sources << '/path/to/jquery'
-```
+ * Node
+ * NPM
-## Running tests
-
- * Make sure you have one of [ExecJS](https://github.com/rails/execjs)
-supported runtime on your machine.
- * Java 1.4+ (for YUI Compressor and Google Closure Compiler)
-
-```sh
-bundle exec rake test
+```bash
+$ npm install
+$ bundle exec rake test
```
## Versioning
__Hanami::Assets__ uses [Semantic Versioning 2.0.0](http://semver.org)
@@ -491,8 +271,6 @@
4. Push to the branch (`git push origin my-new-feature`)
5. Create new Pull Request
## Copyright
-Copyright © 2014-2021 Luca Guidi – Released under MIT License
-
-This project was formerly known as Lotus (`lotus-assets`).
+Copyright © 2014-2023 Hanami Team – Released under MIT License