Coder Social home page Coder Social logo

assets's Introduction

Hanami::Assets

Assets management for Ruby web projects

Status

Gem Version CI Test Coverage Depfu

Contact

Installation

Hanami::Assets supports Ruby (MRI) 3.1+

Add this line to your application's Gemfile:

gem "hanami-assets"

And then execute:

$ bundle

Or install it yourself as:

$ 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. 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:

<!doctype HTML>
<html>
  <head>
    <title>Assets example</title>
    <%= stylesheet_tag "reset", "app" %>
  </head>

  <body>
  <!-- ... -->
  <%= javascript_tag "app" %>
  <%= javascript_tag "https://cdn.somethirdparty.script/foo.js", async: true %>
  </body>
</html>

It will output this markup:

<!doctype HTML>
<html>
  <head>
    <title>Assets example</title>
    <link href="/assets/reset.css" type="text/css" rel="stylesheet">
    <link href="/assets/app.css" type="text/css" rel="stylesheet">
  </head>

  <body>
  <!-- ... -->
  <script src="/assets/app.js" type="text/javascript"></script>
  <script src="https://cdn.somethirdparty.script/foo.js" type="text/javascript" async></script>
  </body>
</html>

Available Helpers

The hanami gem ships with the following helpers for assets:

  • asset_url
  • javascript_tag
  • stylesheet_tag
  • favicon_tag
  • image_tag
  • video_tag
  • audio_tag
  • path_tag

App Structure

Hanami applications are generated via hanami new CLI command.

Among other directories, it generates a specific structure for assets:

$ tree app/assets
├── images
│   └── favicon.ico
├── js
│   └── app.ts
└── css
    └── app.css

Entry Points

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.

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.

The default entry points are:

  • app/assets/js/app.ts
  • slices/[slice-name]/assets/js/app.ts

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.

An example is: app/assets/js/login/app.ts to define a new Entry Point for a Login page where you want to have a more lightweight bundle.

Static Assets

Except for js and css directories, all the other directories are considered static. Their files will be copied as they are to the destination directory.

If you have a custom directory app/assets/fonts, all the fonts are copied to the destination direcotry.

Destination Directory

The destination directory is public/assets.

Deployment

To process the assets during deployment run bundle exec hanami assets compile.

The destination directory will contain the processed assets with an hashed name.

Fingerprint Mode

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.

During the deployment process, Hanami Assets appends to the file name a unique hash.

Example: app/assets/js/app.ts -> public/assets/app-QECGTTYG.js

It creates a /public/assets.json to map the original asset name to the fingerprint name.

The simple usage of the js helper, will be automatically mapped for you:

<%= assets.js "app" %>
<script src="/assets/app-QECGTTYG.js" type="text/javascript"></script>

Subresource Integrity (SRI) Mode

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.

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.

<%= assets.js "app" %>
<script src="/assets/app-QECGTTYG.js" type="text/javascript" integrity="sha384-d9ndh67iVrvaACuWjEDJDJlThKvAOdILG011RxYJt1dQynvf4JXNORcUiZ9nO7lP" crossorigin="anonymous"></script>

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).

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.

<%= javascript 'application' %>
<script src="https://123.cloudfront.net/assets/application-d1829dc353b734e3adc24855693b70f9.js" type="text/javascript"></script>
<%= assets.js "app" %>
<script src="https://123.cloudfront.net/assets/app-QECGTTYG.js" type="text/javascript"></script>

NOTE: We suggest to use SRI mode when using CDN.

Development

Install:

  • Node
  • NPM
$ npm install
$ bundle exec rake test

Versioning

Hanami::Assets uses Semantic Versioning 2.0.0

Contributing

  1. Fork it (https://github.com/hanami/assets/fork)
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request

Copyright

Copyright © 2014–2024 Hanami Team – Released under MIT License

assets's People

Contributors

accuser avatar alfonsouceda avatar artofhuman avatar awochna avatar cllns avatar davydovanton avatar deepj avatar itkrt2y avatar jodosha avatar katafrakt avatar klebervirgilio avatar landongrindheim avatar leighhalliday avatar linuus avatar lucasallan avatar malin-as avatar manuwell avatar mdorfin avatar michaeldeol avatar nerian avatar nickgnd avatar rickenharp avatar sleeplessbyte avatar solnic avatar timriley avatar tombruijn avatar unleashy avatar vyper avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

assets's Issues

Problems with JS compiler

I have main.js file with folloving code:

// main.js
!function () {
  'use strict';

  $(document).on('click', '.content__close', function () {
    $('.js-cards').show()
    $('.content').hide()
  })
}();

When I requested a page all worked fine and in assets folder I had a simular js file.
After that I change my file (server still running):

// main.js
!function () {
  'use strict';

  $(document).on('click', '.content__close', function () {
    $('.js-cards').show()
    $('.content').hide()
  })

  $(document).on('click', '.content__close', function () {
    $('.js-cards').show()
    $('.content').hide()
  })
}();

On this time compiled file in public folder still simular. But after that I added $('.js-cards').show() code to last on click event:

// main.js
!function () {
  'use strict';

  $(document).on('click', '.content__close', function () {
    $('.js-cards').show()
    $('.content').hide()
  })

  $(document).on('click', '.content__close', function () {
    $('.js-cards').show()
    $('.content').hide()
    // new line
    $('.js-cards').show()
  })
}();

And after that yy complited file was broken:

// public/assets/main.js
!function () {
  'use strict';

  $(document).on('click', '.content__close', function () {
    $('.js-cards').show()
    $('.content').hide()
    $('.js-cards').show()
  })


  $(document).on('click', '.content__close', function () {
    $('.js-cards').show()
    $('.content').hide()
  })
}();
-cards').show()
  })
}();

Yes, this is the synthetic example but I come across with such behavior often 😞

undefined method `[]' for nil:NilClass

Hello, I have this issue when trying to precompile for production:

$  HANAMI_ENV=production hanami assets precompile
Skipping compression of: `/home/piton/projects/sneakerbot/public/assets/bootstrap.bundle.min.js'
Reason: undefined method `[]' for nil:NilClass

/home/piton/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/hanami-assets-1.2.0/lib/hanami/assets/compressors/jsmin.rb:256:in `block in nextchar'

Fix undefined method with asset helpers

Why

I'm encountering undefined method errors for the asset helpers (i.e. css, js, etc) in my slice layout. For example, using:

<%= css "home/app" %>

...will result in this error:

Stack Dump
Puma caught this error: undefined method `css' for #<Home::Views::Scope _name=nil _locals={} _rendering=#<Hanami::View::Rendering:0x00000001105b5c50 @config=#<Dry::Configurable::Config values={:paths=>[#<Hanami::View::Path dir=#<Pathname:/Users/bkuhlmann/Scratch/demo/slices/home/templates> root=#<Pathname:/Users/bkuhlmann/Scratch/demo/slices/home/templates>>], :template=>"show", :template_inference_base=>nil, :layout=>"app", :layouts_dir=>"layouts", :scope=>nil, :default_context=>#<Home::Views::Context:0x000000010d21ad50 @_rendering=#<Hanami::View::RenderingMissing:0x000000010d21ada0>,>>> (NoMethodError)
/Users/bkuhlmann/.cache/frum/versions/3.2.2/lib/ruby/gems/3.2.0/bundler/gems/view-9da749567f44/lib/hanami/view/scope.rb:166:in `method_missing'
/Users/bkuhlmann/Scratch/demo/slices/home/templates/layouts/app.html.erb:26:in `__tilt_8640'
/Users/bkuhlmann/.cache/frum/versions/3.2.2/lib/ruby/gems/3.2.0/gems/tilt-2.3.0/lib/tilt/template.rb:207:in `bind_call'
/Users/bkuhlmann/.cache/frum/versions/3.2.2/lib/ruby/gems/3.2.0/gems/tilt-2.3.0/lib/tilt/template.rb:207:in `evaluate'
/Users/bkuhlmann/.cache/frum/versions/3.2.2/lib/ruby/gems/3.2.0/gems/tilt-2.3.0/lib/tilt/template.rb:102:in `render'
/Users/bkuhlmann/.cache/frum/versions/3.2.2/lib/ruby/gems/3.2.0/bundler/gems/view-9da749567f44/lib/hanami/view/renderer.rb:78:in `render'
/Users/bkuhlmann/.cache/frum/versions/3.2.2/lib/ruby/gems/3.2.0/bundler/gems/view-9da749567f44/lib/hanami/view/renderer.rb:45:in `template'
/Users/bkuhlmann/.cache/frum/versions/3.2.2/lib/ruby/gems/3.2.0/bundler/gems/view-9da749567f44/lib/hanami/view/rendering.rb:37:in `template'
/Users/bkuhlmann/.cache/frum/versions/3.2.2/lib/ruby/gems/3.2.0/bundler/gems/view-9da749567f44/lib/hanami/view.rb:577:in `call'
/Users/bkuhlmann/.cache/frum/versions/3.2.2/lib/ruby/gems/3.2.0/bundler/gems/controller-ecdd1ee09330/lib/hanami/action/response.rb:118:in `render'
/Users/bkuhlmann/.cache/frum/versions/3.2.2/lib/ruby/gems/3.2.0/bundler/gems/hanami-122c1d9d9e60/lib/hanami/extensions/action.rb:92:in `finish'
/Users/bkuhlmann/.cache/frum/versions/3.2.2/lib/ruby/gems/3.2.0/bundler/gems/controller-ecdd1ee09330/lib/hanami/action/cookies.rb:23:in `finish'
/Users/bkuhlmann/.cache/frum/versions/3.2.2/lib/ruby/gems/3.2.0/bundler/gems/controller-ecdd1ee09330/lib/hanami/action.rb:332:in `call'
/Users/bkuhlmann/.cache/frum/versions/3.2.2/lib/ruby/gems/3.2.0/bundler/gems/hanami-122c1d9d9e60/lib/hanami/slice/routing/resolver.rb:78:in `block in resolve_slice_action'
/Users/bkuhlmann/.cache/frum/versions/3.2.2/lib/ruby/gems/3.2.0/bundler/gems/router-104fb880f5db/lib/hanami/router.rb:108:in `call'
/Users/bkuhlmann/.cache/frum/versions/3.2.2/lib/ruby/gems/3.2.0/gems/rack-2.2.8/lib/rack/deflater.rb:44:in `call'
/Users/bkuhlmann/.cache/frum/versions/3.2.2/lib/ruby/gems/3.2.0/gems/rack-attack-6.7.0/lib/rack/attack.rb:110:in `call'
/Users/bkuhlmann/.cache/frum/versions/3.2.2/lib/ruby/gems/3.2.0/gems/rack-2.2.8/lib/rack/static.rb:161:in `call'
/Users/bkuhlmann/.cache/frum/versions/3.2.2/lib/ruby/gems/3.2.0/gems/rack-2.2.8/lib/rack/method_override.rb:24:in `call'
/Users/bkuhlmann/.cache/frum/versions/3.2.2/lib/ruby/gems/3.2.0/bundler/gems/hanami-122c1d9d9e60/lib/hanami/middleware/render_errors.rb:57:in `call'
/Users/bkuhlmann/.cache/frum/versions/3.2.2/lib/ruby/gems/3.2.0/gems/dry-monitor-1.0.1/lib/dry/monitor/rack/middleware.rb:36:in `block in call'
/Users/bkuhlmann/.cache/frum/versions/3.2.2/lib/ruby/gems/3.2.0/gems/dry-monitor-1.0.1/lib/dry/monitor/clock.rb:15:in `measure'
/Users/bkuhlmann/.cache/frum/versions/3.2.2/lib/ruby/gems/3.2.0/gems/dry-monitor-1.0.1/lib/dry/monitor/rack/middleware.rb:36:in `call'
/Users/bkuhlmann/.cache/frum/versions/3.2.2/lib/ruby/gems/3.2.0/bundler/gems/router-104fb880f5db/lib/hanami/middleware/app.rb:40:in `call'
/Users/bkuhlmann/.cache/frum/versions/3.2.2/lib/ruby/gems/3.2.0/bundler/gems/hanami-122c1d9d9e60/lib/hanami/slice.rb:758:in `call'
/Users/bkuhlmann/.cache/frum/versions/3.2.2/lib/ruby/gems/3.2.0/gems/puma-6.4.0/lib/puma/configuration.rb:272:in `call'
/Users/bkuhlmann/.cache/frum/versions/3.2.2/lib/ruby/gems/3.2.0/gems/puma-6.4.0/lib/puma/request.rb:100:in `block in handle_request'
/Users/bkuhlmann/.cache/frum/versions/3.2.2/lib/ruby/gems/3.2.0/gems/puma-6.4.0/lib/puma/thread_pool.rb:378:in `with_force_shutdown'
/Users/bkuhlmann/.cache/frum/versions/3.2.2/lib/ruby/gems/3.2.0/gems/puma-6.4.0/lib/puma/request.rb:99:in `handle_request'
/Users/bkuhlmann/.cache/frum/versions/3.2.2/lib/ruby/gems/3.2.0/gems/puma-6.4.0/lib/puma/server.rb:443:in `process_client'
/Users/bkuhlmann/.cache/frum/versions/3.2.2/lib/ruby/gems/3.2.0/gems/puma-6.4.0/lib/puma/server.rb:241:in `block in run'
/Users/bkuhlmann/.cache/frum/versions/3.2.2/lib/ruby/gems/3.2.0/gems/puma-6.4.0/lib/puma/thread_pool.rb:155:in `block in spawn_thread'

How

To recreate, I've built a demo application using a unreleased version of Hanamismith. Here are the steps to recreate:

  1. Download demo.tgz.
  2. Run: tar --extract --bzip2 --verbose --file demo.tgz.
  3. Run: cd demo.
  4. Run: bin/setup.
  5. Add <%= css "home/app" %> to demo/slices/home/templates/layouts/app.html.erb
  6. Run: overmind start --procfile Procfile.dev (or use Foreman).
  7. Run: open https://localhost:9050. You'll now see the error shown above.

Notes

Here's my environment:

  • Ruby: ruby 3.2.2 (2023-03-30 revision e51014f9c0) +YJIT [arm64-darwin22.4.0]
  • Hanami: 2.1.0 RC 1

Compiler tries to compile .sassc file (on Linux)

After running tests on both master and develop, I keep getting:

  1) Error:
Compiler#test_0012_compiles sass asset if a dependency is removed:
Hanami::Assets::UnknownAssetEngine: No asset engine registered for `41c7f75a-3dac-4bee-b1ed-4b09f3fe0c8e.css.sassc'
    /home/katafrakt/dev/github/hanami-assets/lib/hanami/assets/compiler.rb:192:in `rescue in compile!'
    /home/katafrakt/dev/github/hanami-assets/lib/hanami/assets/compiler.rb:190:in `compile!'
    /home/katafrakt/dev/github/hanami-assets/lib/hanami/assets/compiler.rb:132:in `compile'
    /home/katafrakt/dev/github/hanami-assets/lib/hanami/assets/compiler.rb:74:in `compile'
    /home/katafrakt/dev/github/hanami-assets/test/integration/compiler_test.rb:179:in `block (3 levels) in <top (required)>'
    /home/katafrakt/dev/github/hanami-assets/test/support/test_file.rb:25:in `touch'
    /home/katafrakt/dev/github/hanami-assets/test/integration/compiler_test.rb:178:in `block (2 levels) in <top (required)>'


  2) Error:
Compiler#test_0011_compiles sass asset if a dependency is added:
Hanami::Assets::UnknownAssetEngine: No asset engine registered for `14bf2f8f-9bd2-4782-b550-294e1eca839b.css.sassc'
    /home/katafrakt/dev/github/hanami-assets/lib/hanami/assets/compiler.rb:192:in `rescue in compile!'
    /home/katafrakt/dev/github/hanami-assets/lib/hanami/assets/compiler.rb:190:in `compile!'
    /home/katafrakt/dev/github/hanami-assets/lib/hanami/assets/compiler.rb:132:in `compile'
    /home/katafrakt/dev/github/hanami-assets/lib/hanami/assets/compiler.rb:74:in `compile'
    /home/katafrakt/dev/github/hanami-assets/test/integration/compiler_test.rb:155:in `block (3 levels) in <top (required)>'
    /home/katafrakt/dev/github/hanami-assets/test/support/test_file.rb:25:in `touch'
    /home/katafrakt/dev/github/hanami-assets/test/integration/compiler_test.rb:154:in `block (2 levels) in <top (required)>'

I managed to narrow it down to files method (https://github.com/hanami/assets/blob/master/lib/hanami/assets/config/sources.rb#L48) returning array of files formed as:

[
"/home/katafrakt/dev/github/hanami-assets/tmp/sass-cache/e0b7e4343b617a2188b0aa19dbd2153da78474d2/b2b70834-66c7-432a-96f6-c76b21f66572.css.sassc",
"/home/katafrakt/dev/github/hanami-assets/tmp/b2b70834-66c7-432a-96f6-c76b21f66572.css.sass",
"/home/katafrakt/dev/github/hanami-assets/tmp/public/assets/b2b70834-66c7-432a-96f6-c76b21f66572.css"
]

... which is obviously not the best order to take first and assume it's a good file. I took few naive attempts to fix it (e.g. by excluding path if it has sass-cache in it), but I haven't succeeded.

Assets cache doesn't "notice" changes in imported scss files in development mode

Hi,
I'm using sass to compile multiple css files into a single application.css, and in development mode the compiled file is cached, and subsequent changes to @import-ed have no effect.

// application.css.scss
@import './colors.css.scss';
// colors.css.scss
body { background: green }

Changing body color has no effect until I rm -rf public/assets or touch application.css.scss

Reproduced in v0.2.1.

Migrate from Minitest to RSpec

A few rules to follow:

  • If you want to work on this, please leave a comment here. We want to avoid many people to work on the same task.

  • We expect this migration to happen within a week from now.

  • Do not change the tests, only migrate from Minitest to RSpec syntax. If not sure, please ask here.

  • Do not remove the old tests, only add the new ones.

  • Make CI build to use RSpec tests.

  • Target develop branch, instead of master.

  • All the tests artefacts like fixtures, goes under spec/support.

  • Try to reflect the structure under lib/. Eg. lib/hanami/view.rb should be tested under spec/hanami/view_spec.rb, while test/rendering_test.rb should go under spec/integration/rendering_spec.rb.

If you want to take inspiration, please have a look at: hanami/mailer#67

Integration Tests Fail in Master

When working on #102, all specs were passing locally, but the branch would not integrate with hanami/hanami. Upon investigation, I found that script/ci was running "isolation" specs (specs in the spec/isolation/ directory). However, there is no spec/isolation directory:

 ~/oss/hanami/assets $ ls -la spec/
total 8
drwxr-xr-x   7 lgrindheim  1988998316  224 Jul 21 20:49 .
drwxr-xr-x  24 lgrindheim  1988998316  768 Jul 20 10:55 ..
drwxr-xr-x   3 lgrindheim  1988998316   96 Jul 17 11:12 integration
-rw-r--r--   1 lgrindheim  1988998316  143 Jul 20 10:55 spec_helper.rb
drwxr-xr-x  10 lgrindheim  1988998316  320 Jul 20 10:55 support
drwxr-xr-x   2 lgrindheim  1988998316   64 Jul 21 20:49 tmp
drwxr-xr-x   3 lgrindheim  1988998316   96 Jul 17 11:12 unit

I believe this has led to a series of builds that passed CI but otherwise should not have. Currently, when running bundle exec rspec spec/integration/ in master, there are 28 failing specs.

I suspect that #92, #93 and #96 correspond to specs that fail in master.

Hanami::Assets does not preserve directory structure

I'm creating an app where certain pages are displayed using different themes, based on values from the database. I put theme in apps/assets/stylesheets/themes/orbit/styles.css directory and then referenced it in the template with <%= stylesheet 'themes/orbit/styles' %>. However, this does not work. The stylesheet is not available and when I look into public/assets directory, I see styles.css in the root directory, not in public/assets/themes/orbit/ as I expected.

Is this a bug/missing feature in Hanami::Assets or is it by design? If the latter, how can I accomplish what I want. If former, what can I do to help fix/implement it?

I'm using 1.1.0.beta1 version.

Wrong assets_configuration reference when using different views for specific formats

I noticed an issue when trying to render static assets on my application using different views for specific formats (following the guides)

Hanami version: 1.2

My view for the html format looked something like this:

# apps/client/views/dashboard/html_index.rb
require_relative './index'

module Client::Views::Dashboard
  class HtmlIndex < Index
    format :html
  end
end

And on my app configuration, I enabled fingerprint:

# apps/client/application.rb
configure :production do
...
assets do
  fingerprint true
end

When I enabled the fingerprint, I would get the following error when trying to render the index page:

Hanami::Assets::MissingManifestFileError: Can't read manifest: /app/public/assets.json

Here follows the full stack trace:

Hanami::Assets::MissingManifestFileError: Can't read manifest: /Users/rodrigovasconcelos/myApp/public/assets.json
	/Users/rodrigovasconcelos/.rbenv/versions/2.4.3/lib/ruby/gems/2.4.0/gems/hanami-assets-1.2.0/lib/hanami/assets/config/manifest.rb:65:in `method_missing'
	/Users/rodrigovasconcelos/.rbenv/versions/2.4.3/lib/ruby/gems/2.4.0/gems/hanami-assets-1.2.0/lib/hanami/assets/configuration.rb:611:in `compile_path'
	/Users/rodrigovasconcelos/.rbenv/versions/2.4.3/lib/ruby/gems/2.4.0/gems/hanami-assets-1.2.0/lib/hanami/assets/configuration.rb:404:in `asset_path'
	/Users/rodrigovasconcelos/.rbenv/versions/2.4.3/lib/ruby/gems/2.4.0/gems/hanami-assets-1.2.0/lib/hanami/assets/helpers.rb:892:in `_relative_url'
	/Users/rodrigovasconcelos/.rbenv/versions/2.4.3/lib/ruby/gems/2.4.0/gems/hanami-assets-1.2.0/lib/hanami/assets/helpers.rb:773:in `block in asset_path'
	/Users/rodrigovasconcelos/.rbenv/versions/2.4.3/lib/ruby/gems/2.4.0/gems/hanami-assets-1.2.0/lib/hanami/assets/helpers.rb:845:in `_asset_url'
	/Users/rodrigovasconcelos/.rbenv/versions/2.4.3/lib/ruby/gems/2.4.0/gems/hanami-assets-1.2.0/lib/hanami/assets/helpers.rb:773:in `asset_path'
	/Users/rodrigovasconcelos/.rbenv/versions/2.4.3/lib/ruby/gems/2.4.0/gems/hanami-assets-1.2.0/lib/hanami/assets/helpers.rb:861:in `_typed_asset_path'
	/Users/rodrigovasconcelos/.rbenv/versions/2.4.3/lib/ruby/gems/2.4.0/gems/hanami-assets-1.2.0/lib/hanami/assets/helpers.rb:285:in `block in stylesheet'
	/Users/rodrigovasconcelos/.rbenv/versions/2.4.3/lib/ruby/gems/2.4.0/gems/hanami-assets-1.2.0/lib/hanami/assets/helpers.rb:837:in `block in _safe_tags'
	/Users/rodrigovasconcelos/.rbenv/versions/2.4.3/lib/ruby/gems/2.4.0/gems/hanami-assets-1.2.0/lib/hanami/assets/helpers.rb:836:in `map'
	/Users/rodrigovasconcelos/.rbenv/versions/2.4.3/lib/ruby/gems/2.4.0/gems/hanami-assets-1.2.0/lib/hanami/assets/helpers.rb:836:in `_safe_tags'
	/Users/rodrigovasconcelos/.rbenv/versions/2.4.3/lib/ruby/gems/2.4.0/gems/hanami-assets-1.2.0/lib/hanami/assets/helpers.rb:283:in `stylesheet'
	/Users/rodrigovasconcelos/.rbenv/versions/2.4.3/lib/ruby/gems/2.4.0/gems/hanami-view-1.2.0/lib/hanami/view/rendering/scope.rb:78:in `method_missing'
	/Users/rodrigovasconcelos/myApp/apps/client/templates/dashboard/index.html.erb:96:in `block in singleton class'
	/Users/rodrigovasconcelos/myApp/apps/client/templates/dashboard/index.html.erb:-6:in `instance_eval'
	/Users/rodrigovasconcelos/myApp/apps/client/templates/dashboard/index.html.erb:-6:in `singleton class'
	/Users/rodrigovasconcelos/myApp/apps/client/templates/dashboard/index.html.erb:-9:in `__tilt_70207384340200'
	/Users/rodrigovasconcelos/.rbenv/versions/2.4.3/lib/ruby/gems/2.4.0/gems/tilt-2.0.8/lib/tilt/template.rb:170:in `call'
	/Users/rodrigovasconcelos/.rbenv/versions/2.4.3/lib/ruby/gems/2.4.0/gems/tilt-2.0.8/lib/tilt/template.rb:170:in `evaluate'
	/Users/rodrigovasconcelos/.rbenv/versions/2.4.3/lib/ruby/gems/2.4.0/gems/tilt-2.0.8/lib/tilt/template.rb:109:in `render'
	/Users/rodrigovasconcelos/.rbenv/versions/2.4.3/lib/ruby/gems/2.4.0/gems/hanami-view-1.2.0/lib/hanami/view/template.rb:41:in `render'
	/Users/rodrigovasconcelos/.rbenv/versions/2.4.3/lib/ruby/gems/2.4.0/gems/hanami-view-1.2.0/lib/hanami/view/rendering.rb:140:in `rendered'
	/Users/rodrigovasconcelos/.rbenv/versions/2.4.3/lib/ruby/gems/2.4.0/gems/hanami-view-1.2.0/lib/hanami/view/rendering.rb:154:in `layout'
	/Users/rodrigovasconcelos/.rbenv/versions/2.4.3/lib/ruby/gems/2.4.0/gems/hanami-view-1.2.0/lib/hanami/view/rendering.rb:108:in `render'
	/Users/rodrigovasconcelos/.rbenv/versions/2.4.3/lib/ruby/gems/2.4.0/gems/hanami-view-1.2.0/lib/hanami/view/rendering.rb:259:in `render'
	/Users/rodrigovasconcelos/.rbenv/versions/2.4.3/lib/ruby/gems/2.4.0/gems/hanami-1.2.0/lib/hanami/rendering_policy.rb:56:in `_render_action'
	/Users/rodrigovasconcelos/.rbenv/versions/2.4.3/lib/ruby/gems/2.4.0/gems/hanami-1.2.0/lib/hanami/rendering_policy.rb:48:in `_render'
	/Users/rodrigovasconcelos/.rbenv/versions/2.4.3/lib/ruby/gems/2.4.0/gems/hanami-1.2.0/lib/hanami/rendering_policy.rb:38:in `render'
	/Users/rodrigovasconcelos/.rbenv/versions/2.4.3/lib/ruby/gems/2.4.0/gems/hanami-1.2.0/lib/hanami/application.rb:169:in `call'
	/Users/rodrigovasconcelos/.rbenv/versions/2.4.3/lib/ruby/2.4.0/delegate.rb:83:in `method_missing'
	/Users/rodrigovasconcelos/.rbenv/versions/2.4.3/lib/ruby/gems/2.4.0/gems/http_router-0.11.2/lib/http_router.rb:193:in `process_destination_path'
	(eval):34:in `call'
	/Users/rodrigovasconcelos/.rbenv/versions/2.4.3/lib/ruby/gems/2.4.0/gems/http_router-0.11.2/lib/http_router.rb:288:in `raw_call'
	/Users/rodrigovasconcelos/.rbenv/versions/2.4.3/lib/ruby/gems/2.4.0/gems/hanami-router-1.2.0/lib/hanami/routing/http_router.rb:156:in `raw_call'
	/Users/rodrigovasconcelos/.rbenv/versions/2.4.3/lib/ruby/gems/2.4.0/gems/hanami-router-1.2.0/lib/hanami/router.rb:1019:in `call'
	/Users/rodrigovasconcelos/.rbenv/versions/2.4.3/lib/ruby/gems/2.4.0/gems/newrelic_rpm-4.2.0.334/lib/new_relic/agent/instrumentation/middleware_tracing.rb:92:in `call'
	/Users/rodrigovasconcelos/.rbenv/versions/2.4.3/lib/ruby/gems/2.4.0/gems/rack-2.0.4/lib/rack/method_override.rb:22:in `call'
	/Users/rodrigovasconcelos/.rbenv/versions/2.4.3/lib/ruby/gems/2.4.0/gems/newrelic_rpm-4.2.0.334/lib/new_relic/agent/instrumentation/middleware_tracing.rb:92:in `call'
	/Users/rodrigovasconcelos/.rbenv/versions/2.4.3/lib/ruby/gems/2.4.0/gems/hanami-1.2.0/lib/hanami/assets/static.rb:49:in `call'
	/Users/rodrigovasconcelos/.rbenv/versions/2.4.3/lib/ruby/gems/2.4.0/gems/newrelic_rpm-4.2.0.334/lib/new_relic/agent/instrumentation/middleware_tracing.rb:92:in `call'
	/Users/rodrigovasconcelos/.rbenv/versions/2.4.3/lib/ruby/gems/2.4.0/gems/rack-2.0.4/lib/rack/content_length.rb:15:in `call'
	/Users/rodrigovasconcelos/.rbenv/versions/2.4.3/lib/ruby/gems/2.4.0/gems/newrelic_rpm-4.2.0.334/lib/new_relic/agent/instrumentation/middleware_tracing.rb:92:in `call'
	/Users/rodrigovasconcelos/.rbenv/versions/2.4.3/lib/ruby/gems/2.4.0/gems/rack-2.0.4/lib/rack/common_logger.rb:33:in `call'
	/Users/rodrigovasconcelos/.rbenv/versions/2.4.3/lib/ruby/gems/2.4.0/gems/newrelic_rpm-4.2.0.334/lib/new_relic/agent/instrumentation/middleware_tracing.rb:92:in `call'
	/Users/rodrigovasconcelos/.rbenv/versions/2.4.3/lib/ruby/gems/2.4.0/gems/hanami-1.2.0/lib/hanami/app.rb:44:in `call'
	/Users/rodrigovasconcelos/.rbenv/versions/2.4.3/lib/ruby/gems/2.4.0/gems/newrelic_rpm-4.2.0.334/lib/new_relic/agent/instrumentation/middleware_tracing.rb:92:in `call'
	/Users/rodrigovasconcelos/.rbenv/versions/2.4.3/lib/ruby/gems/2.4.0/gems/hanami-1.2.0/lib/hanami/assets/static.rb:49:in `call'
	/Users/rodrigovasconcelos/.rbenv/versions/2.4.3/lib/ruby/gems/2.4.0/gems/rack-2.0.4/lib/rack/lint.rb:49:in `_call'
	/Users/rodrigovasconcelos/.rbenv/versions/2.4.3/lib/ruby/gems/2.4.0/gems/rack-2.0.4/lib/rack/lint.rb:37:in `call'
	/Users/rodrigovasconcelos/.rbenv/versions/2.4.3/lib/ruby/gems/2.4.0/gems/rack-2.0.4/lib/rack/show_exceptions.rb:23:in `call'
	/Users/rodrigovasconcelos/.rbenv/versions/2.4.3/lib/ruby/gems/2.4.0/gems/puma-3.9.1/lib/puma/configuration.rb:224:in `call'
	/Users/rodrigovasconcelos/.rbenv/versions/2.4.3/lib/ruby/gems/2.4.0/gems/puma-3.9.1/lib/puma/server.rb:602:in `handle_request'
	/Users/rodrigovasconcelos/.rbenv/versions/2.4.3/lib/ruby/gems/2.4.0/gems/puma-3.9.1/lib/puma/server.rb:435:in `process_client'
	/Users/rodrigovasconcelos/.rbenv/versions/2.4.3/lib/ruby/gems/2.4.0/gems/puma-3.9.1/lib/puma/server.rb:299:in `block in run'
	/Users/rodrigovasconcelos/.rbenv/versions/2.4.3/lib/ruby/gems/2.4.0/gems/puma-3.9.1/lib/puma/thread_pool.rb:120:in `block in spawn_thread'

Doing some debugging, I figured out that the the issue was in this method of the asset helper:

def _relative_url(source)
  self.class.assets_configuration.asset_path(source)
end

More specifically, Client::Views::Dashboard::HtmlShow.assets_configuration would have a Config::NullManifest public_manifest reference, as the correct manifest was only loaded for the parent class Client::Views::Dashboard::Show.

I was able to do a workaround by adding the following class method on my subview:

# apps/client/views/dashboard/html_index.rb
require_relative './index'

module Client::Views::Dashboard
  class HtmlIndex < Index
    format :html

    def self.assets_configuration
      Client::Views::Dashboard::Show.assets_configuration
    end
  end
end

I'm not sure if this is the best approach to the issue though.

Standardize name of CLI tool to `hanami assets`

Can we change hanami-assets to hanami assets?

It would simplify things if the commands are the same regardless of whether you're using hanami-assets alone or with the rest of hanami.

  1. It'd have to check to see if the current project is a full hanami project, and if so, prefer those CLI tools instead.
  2. It would also have to add a precompile command, in order to provide the same API.
    Since right now it's hanami-assets vs hanami assets precompile

Project README says to install as gem, but gem release (0.0.0) doesn't include lotus/assets/helpers

Basically what the title says. The README says to put gem 'lotus-assets' in your Gemfile. The version that bundler would install is 0.0.0 from rubygems.org, which doesn't include the lotus/assets/helpers required in your apps/web/application.rb file.

Perhaps, until a new gem version is released, the installation section of the README should instruct users to use the projects' github:

gem 'lotus-assets', git: 'https://github.com/lotus/assets.git'

Or, release a new version if the 0.1.0 version is ready.

Sass @import not working

For file importing sass internally looks through a specified load_path:

def import
  paths = @options[:load_paths]

  if @options[:importer]
    f = @options[:importer].find_relative(
      @imported_filename, @options[:filename], options_for_importer)
    return f if f
  end

  paths.each do |p|
    f = p.find(@imported_filename, options_for_importer)
    return f if f
  end
.
.

https://github.com/sass/sass/blob/3.4.15/lib/sass/tree/import_node.rb#L44

This doesn't work with lotus-assets because lotus-assets uses tilt but doesn't pass in the proper options for it.
Tilt allows to pass in options see: https://github.com/rtomayko/tilt/blob/master/lib/tilt.rb#L42
Further when using Tilt.new this is called: https://github.com/rtomayko/tilt/blob/master/lib/tilt/mapping.rb#L136

template_class would be SassTemplate which inherits from Template which in turn allows to specify options: https://github.com/rtomayko/tilt/blob/master/lib/tilt/template.rb#L53

Finally Sass::Engine.new is called which allows to specify load_path: https://github.com/rtomayko/tilt/blob/master/lib/tilt/sass.rb#L13

lotus-assets should specify the sources as load_path for sass.

Can't load css that filename start with underscore in node_modules

Hello guys.
I tried using icheck in my hanami project by the below settings.

# apps/web/application.rb
assets do
  nested true
  
  sources << [
    'assets',
    'node_modules'
  ]
end
# apps/web/templates/application.html.erb

<%= stylesheet 'icheck/skins/all' %>

But some files are not delivered to public/assets because 'icheck' is importing CSS that filename starts with an underscore.

I think this code excludes css and js start with underscore.
Is this necessary?

If this is necessary, How do I load a file that starts with an underscore in node_module.

Bug with slim templates

Firstly clone this repo and run bundle && bundle exec lotus s.

If you look into index and application layouts you can see that it's valid slim layout. And if you open localhost:2300 you see something like in a picture:
screenshot 2016-01-20 01 51 22

Can't precompile assets with a deployed app

I deployed a small test app today, that just has an image and a bit of scss as assets. Everything works locally in development, and running ./bin/hanami assets precompile locally writes everything into public as expected.

But calling the same thing on the server, I get the following error:

deploy@sarkhan:/opt/www/mathsquad.net/current$ ./bin/hanami assets precompile
/opt/www/mathsquad.net/shared/bundle/ruby/2.3.0/gems/hanami-assets-0.2.1/lib/hanami/assets/compiler.rb:177:in rescue in compile!': No asset engine registered fornerps.png' (Hanami::Assets::UnknownAssetEngine)

What could cause the compile to fail like this on the server?

Support multiple asset manifests?

Hi all,

I was wondering about assets on a multiple apps project. Each app has its own assets, and each app can quite easily be or not deployed (for example server A and B serving app X and server C serving app Y).

Currently, AFAIK, there's no way to precompile assets for a restricted set of apps, and, in an assets-with-digest configuration, all apps use the same manifest.

Would it be possible to use the app name for the manifest file name and subdirectory for the assets?

For example, with 2 apps, Admin and Web:

- apps/
  - admin/
  - web/
- config/
- lib/
- public/
  - admin.json
  - web.json
  - assets/
    - admin/
    - web/

On the plus side:

  • no problem when multiple apps are mounted on the same base path
  • better decoupling of apps
  • possibility to parallelize assets precompilation

On the down side:

  • assets that were located at /assets/foo.css when the app was mounted at / would now be located at /assets/app/foo.css

Image helper

Implement image helper.

See Lotus::Assets::Helpers for reference.

Usage

Basic Usage

<%= image('logo.png') %>
<img src="/assets/logo.png" alt="Logo">

The alt attribute is automatically extracted from the path name

HTML Attributes

It can also accept a set of options for HTML attributes:

<%= image('logo.png', id: 'logo', class: 'image') %>
<img src="/assets/logo.png" alt="Logo" id="logo" class="image">

If the :alt attribute is specified, it should override the automatic value.

<%= image('logo.png', alt: 'My product logo') %>
<img src="/assets/logo.png" alt="My product logo">

URL Prefix

This should take account of the prefix defined in Lotus::Assets::Configuration.

That means, if an application has a prefix: /admin, when one of these helpers is used, the prefix should be used.

<%= image('logo.png') %>
<img src="/assets/admin/logo.png" alt="Logo">

Digest Mode

If "Digest Mode" is enabled (usually in production), it should generate the file name with the digest suffix (see https://github.com/lotus/assets/blob/master/lib/lotus/assets/configuration.rb#L37).

<%= image('logo.png') %>
<img src="/assets/admin/logo-78a21a377046e9ddb3bd9b509c22d4c3.png" alt="Logo">

Testing Notes

Add an integration test with Lotus::View, in order to make sure that the output isn't escaped twice and produces a valid HTML.

Destination doesn't respect root configuration

Consider following example:

require 'sass'
require 'lotus/assets'

Lotus::Assets.configure do
  compile true

  root __dir__

  prefix 'stylesheets'

  destination 'public/stylesheets'

  define :stylesheet do
    sources << [
      'assets/stylesheets'
    ]
  end
end

The root configuration is used to know where the relative path of sources starts.
When using the configure dsl like this, I would assume the destination configuration does the same and use the root path to know where it starts.

Here sources uses root path: https://github.com/lotus/assets/blob/master/lib/lotus/assets/config/sources.rb#L42

Here the destination path is created: https://github.com/lotus/assets/blob/master/lib/lotus/assets/configuration.rb#L63
I would suggest to add the root recognition here and create the proper path for it.

Cheers ❤️

Ignore file system meta files like .DS_Store

On macOS filesystems (HFS and APFS), finder metadata is written to .DS_Store which causes loads of fun in many places. Other filesystems might have similar reserved metadata files as well, but I'm not aware of any since the only other filesystem I'm really familiar with is ext on Linux.

When building the assets on macOS, these .DS_Store directories are processed as well:

image

And as a consequence, they also show up in the assets.json manifest:

  ".DS_Store": {
    "url": "/assets/.DS_Store-49C419DE"
  },

If the assets are compiled during development and not during deployment (maybe not a common scenario, but certainly not impossible) or when deploying to such a filesystem, this finder metadata is exposed to the public. There might not be critical information in there, but .DS_Store is a black box and who knows what Apple decides to persist there in the future.

Maybe, there should be a short denylist with known files like .DS_Store which should never be processed.

Asset output file name seemes to be wrong when nested true

Hello.
The output file name seems to be wrong when the nested option is enabled.

Precondition

$ tree apps/web/assets/javascript

apps/web/assets/javascripts/
└── sessions
    └── form.js.es6
# apps/web/application.rb
assets do
  nested true
end
<%# apps/web/application.html.erb %>

<%= javascript 'sessions/form' %>

expected

$ tree public/assets

public/assets/
├── web
│   └── sessions
│       └── form.js
└── favicon.ico

actual

$ tree public/assets

public/assets/
├── web
│   └── sessions
│       └── form.js.es6
└── favicon.ico

Some thoughts

Hi,

I know lotus-assets is not yet ready, but I am prototyping an app using Lotus and I am trying to get as far as I can. This are my thoughts on my experience of using lotus-assets.

I will be using bootstrap so the first thing I wanted to get is a gem for bootstrap. For Rails, the official is bootstrap-sass so I wanted to simply make that gem support Lotus too. It was a simple change.

twbs/bootstrap-sass@master...Nerian:support-lotus

The gem now works in a Lotus app. I can serve both JS and Stylesheets.

// application.css.scss
$icon-font-path: '../assets/';
@import "bootstrap";

Bootstrap packages a set of fonts for its icons.

https://github.com/twbs/bootstrap-sass/tree/master/assets/fonts/bootstrap

And includes it using css's font-face:

https://github.com/twbs/bootstrap-sass/blob/master/assets/stylesheets/bootstrap/_glyphicons.scss#L14

That line roughly translates to something like:

@font-face {
  font-family: 'Glyphicons Halflings';
  src: url(assets/glyphicons-halflings-regular.woff);
}

The issue is that this font – that comes from a gem – is not going to be automatically added to the public folder, as it is the case with javascript and stylesheets.

The reason for this – as I understand it – is that Lotus-assets adds the assets to the public folder in a lazy way. When Lotus sees a stylesheet or javascript method, it searches for said asset in the assets folders, run any preprocessors and copy it to the public folder. Then, when the browser requests the assets, rack will serve it up using rack-static.

But this is not going to be the case of fonts, because fonts are not referenced anywhere but in the css. By the time the browser requests the font, rack-static can only say "it's not here" – Lotus never knows about the font and thus cannot copy it to the public folder.

So in my case, I had to manually copy the fonts from the gem to my public folder. In an ideal case, it should just work.

I wonder what are your thoughts on using a style similar to what Rails do. Rails, or rather Sprockets, uses manifests files, so the app knows all it needs to package from the start.

Implement sassc-ruby

The sass gem is officially dead: https://sass-lang.com/ruby-sass

We should be using the sassc gem instead.

When I swapped out the sass gem for sassc, I got the following error:
#<NameError: uninitialized constant Sass Did you mean? SassC>

Remove builtin JS compressor?

See: hanami/hanami#810

As @kaikuchn said,

The builtin js compressor is a copy of the unmaintained JSMin gem.

It hasn't been updated since 2012, so new JS (ES6+) features probably break it. This will only get worse as ES continues to evolve.

I don't think we should have a builtin compressor that breaks. Especially since we don't want to encourage its use, I think we'd be better off removing it altogether. Maybe we could have a (simple) :fake compressor that just removes comments and extraneous whitespace?

What do you think @hanami/core @kaikuchn @badoet?

When does public/assets decide to recompile

I am seeing some strange behavior trying to get scss working. I have a web/assets/stylesheets/application.css.scss file that I can delete then entire contents of and a refresh with cache disabled won't show that I have deleted anything. The old css file is served up. If I then put a link to a stylesheet that cannot be found,

<%= stylesheet 'application'%>
<link href="assets/stylesheets/application.css" type="text/css" rel="stylesheet">

and refresh two times, I will get the new compiled style sheet served up. I am getting the same behavior when adding to my sass file.

Is this something borked on my end?

Should ignore hidden files beginning with a dot (.)

Some text editors create hidden files. Lotus::Assets will try to process these and fail during development:

Lotus::Assets::UnknownAssetEngine: No asset engine registered for `.app.css.scss.swp'

This isn't a big deal in production, but it adds extra steps to developing assets that get in developers' way.

Custom prefix is not respected

Problem

When you set a prefix in the configuration no assets are added to the manifest and no digest files are created. This was noticed in a Hanami container architecture application.

# apps/my_app/application.rb
...
assets do
  prefix 'foo'
end
...
$ hanami assets precompile

$ tree public
public
├── assets.json
└── foo
    └── application.css

$ cat public/assets.json
{}

$ hanami version
v0.8.0

In the tree output above you will notice there is no digest version of the .css file and the assets.json file is empty so the entire Bundler step appears to be missed. I've not tried any pre compilation yet as in the application I'm working on this is handled by Webpack. I just cared about creating the digest versions and manifest for use by the Hanami helpers.

Possible Cause

The problem appears to be that it isn't globbing these files:

There maybe more side effects to a change like this and I'm not that familiar with the codebase yet but this appears to be the cause if you decide to configure assets on a per application basis.

Hope this helps. If I've missed of any vital information please let me know and I will do what I can to provide the details.

Does not support files with multiple dots in name

The assets compiler will only support files with no dots in the pre-extension filename.

e.g. foundation.js.es6 works fine while foundation.tabs.js.es6 or foundation.util.box.js.es6 will fail.

These filenames are used in the ZURB Foundation framework ( http://foundation.zurb.com/ ) js files. (While their css files use dashes... go figure...)

Attempted to fix this in #62 but cannot get it working. The PR contains a failing test and the build shows the precompiler test exploding.

I do not believe that a simple regex tweak is good enough but needs more fundamental changes.

Nested assets with preprocessing getting wrong extension

Expected behavior

For a tree structure like:

| - my_assets/
|   - parent.css.scss
|   - nested/
|      - nested.css.scss

and a configuration file like:

require "hanami/assets"
require "sass"

Hanami::Assets.configure do
  sources << [
    "my_assets"
  ]
end

following output would be expected (omitting files with fingerprint):

- public/
-  assets/
-    parent.css
-    nested/
-      nested.css
- assets.json

Actual behavior

Instead, the following output is created:

- public/
-  assets/
-    parent.css
-    nested/
-      nested.css.scss # Notice the extension here.
- assets.json

Notice that the preprocessing happens, but the extension remains the same.

Steps to Reproduce the Problem

  1. git clone https://github.com/waiting-for-dev/hanami_assets_nested_extensions_bug
  2. cd hanami_assets_nested_extensions_bug
  3. bundle
  4. find my_assets -name "*"
  5. bundle exec hanami-assets -c config.rb
  6. find public -name "*"

LoadError: cannot load such file -- lotus/assets/helpers

I followed the README and added:

gem 'lotus-assets' to Gemfile, bundled and have a view like this:

require 'erb'
require 'lotus/assets'
require 'lotus/assets/helpers'

module Web::Views::Welcome
  class Show
    include Web::View
    include Lotus::Assets::Helpers
  end
end

When I visit the URL I get: LoadError: cannot load such file -- lotus/assets/helpers

Compile without specific files

Hi!

Is it possible to compile without specific files?
I'd like to skip compress for few js files because of js issue.

Favicon helper

Implement favicon helper.

See Lotus::Assets::Helpers for reference.

Usage

Basic Usage

<%= favicon %>
<link href="/assets/favicon.ico" rel="shortcut icon" type="image/x-icon">

Path

It also accepts an optional path

<%= favicon 'myfavicon.ico' %>
<link href="/assets/myfavicon.ico" rel="shortcut icon" type="image/x-icon">

URL Prefix

This should take account of the prefix defined in Lotus::Assets::Configuration.

That means, if an application has a prefix: /admin, when one this helper is used, the prefix should be used.

<%= favicon %>
<link href="/assets/admin/favicon.ico" rel="shortcut icon" type="image/x-icon">

Digest Mode

If "Digest Mode" is enabled (usually in production), it should generate the file name with the digest suffix (see https://github.com/lotus/assets/blob/master/lib/lotus/assets/configuration.rb#L37).

<%= favicon %>
<link href="/assets/favicon-78a21a377046e9ddb3bd9b509c22d4c3.ico" rel="shortcut icon" type="image/x-icon">

Testing Notes

Add an integration test with Lotus::View, in order to make sure that the output isn't escaped twice and produces a valid HTML.

Incorrect paths after asset compile

(Moved from Discourse)

From the guides, it’s a feature that e.g. /app/assets/fonts/hack/hack-regular.woff2 is copied to /public/assets/hack/hack-regular.woff2 during asset compile obviously dropping the first hierarchy fonts/.

However, this is a problem when you reference fonts, background images etc from another stylesheet. I’ve created a simple test app to illustrate:

https://github.com/svoop/testli/commits/main/

After bootstrapping, I’ve just added a fonts directory, added the stylesheet for it and added it via the app.js entrypoint:

svoop/testli@7e6cad8

Running hanami assets compile works fine and produces the following assets in public/:

svoop/testli@81a2615

As expected the hack.woff2 is created without fonts/ in its path:

https://github.com/svoop/testli/blob/81a26154b10f11d8f7654a9fdc7ac8e65b3e6fac/public/assets/assets.json#L12

That’s not the case in the compiled app.css which contains the fonts/ path segment.

https://github.com/svoop/testli/blob/81a26154b10f11d8f7654a9fdc7ac8e65b3e6fac/public/assets/app-QT5OCCA4.css#L1

Also, possibly unrelated, the path in the compiled app.css descends below the public/ webroot for static assets with ../../ which doesn’t seem right.

Depfu Error: Depfu is stuck and needs your help

Hello,

⚠️ We're getting errors with this repo and have given up after trying several times.

In most cases that means something is wrong with your current Bundler setup and we can't fix it automatically:

• Error details:
Bundler Error: The path `/tmp/d20220127-4-g2whyv/spec/support/fixtures/hanami-emberjs` does not exist.
• Error details:
Bundler Error: The path `/tmp/d20220127-4-7eqzji/spec/support/fixtures/hanami-emberjs` does not exist.
• Error details:
Bundler Error: The path `/tmp/d20220127-4-193mu9t/spec/support/fixtures/hanami-emberjs` does not exist.

After you've fixed the problem, please activate this project again in the Depfu Dashboard.

👉 We will not send you further PRs until this is fixed and the repo is activated again.

If you need help or this looks like an error on our side, please send us an email.

Javascript helper erroneously appends `.js` to absolute URLs

Hi, this is a small problem that took me too long to figure out:

= javascript 'https://maps.googleapis.com/maps/api/js?key=mykey&callback=init_gm'

turns into:

<script src="https://maps.googleapis.com/maps/api/js?key=mykey&callback=init_gm.js" type="text/javascript"></script>

The more I think about it, the more it seems to me that this feature could also cause trouble with relative URLs for the exact same reasons, and should be disabled by default, or even removed.

[Regression] Referencing nested assets without full path does not work in 1.3

This was brought up on Gitter and I confirmed that behaviour changed in 1.3.0, due to #88.

Steps to reproduce:

  1. Create new Hanami application with hanami 1.2.0 and hanami-assets 1.2.0
  2. Create a file in apps/web/assets/stylesheets/nested/style.css, for example setting body's background to yellow
  3. Reference it in application.html.erb by <%= stylesheet 'style' %>
  4. Create some action doing nothing and open up in a browser (there is yellow background)
  5. Update hanami and hanami-assets to 1.3.0
  6. Check the browser again (no yellow background)

In 1.3.0 it cannot find the file (you need to use <%= stylesheet 'nested/style' %>). I think behaviour in 1.2.0 is incorrect, it's not documented and not tested, but reality is that it is kind of a breaking change between 1.2.0 and 1.3.0.

What could be done about it? Bring additional fallback to 1.3.1 recreating described behaviour with deprecation warning? I haven't looked at the code yet, but as far as I remember from #88 it won't be easy.

Manage assets via Torba?

Hey guys!

I spotted that you promote using third-party assets via Rubygems, which is the thing I strongly advocate against.

I would be happy to have "torba-hanami" integration (similar to torba-rails), however, I personally don't use Hanami and don't know how to properly test it. Implementation should be pretty simple, though.

Is there anyone who wants to help with this?

support external pipeline like middleman does?

in middleman v4, rails assets pipeline has been removed and replaced by external pipeline which can be integrated with ember, gulp, webpack, and other modern font-end package tools. I am wondering if it is possible for hanami to support in the future? I feel a bit tedious to integrate hanami with webpack.

Map structure lost when compiling

Because of l compiler.rb#L119-L133, files that are under assets/xxx/file.ext or vendor/assets/yyy/file.ext will all be served as assets/file.ext and assets/file2.ext.

This breaks references in for example CSS files.

If vendor.css refers to themes/theme-logo.png the file will never be found, because theme-logo.png is now in the same directory.


Any directory structure under all the asset sources should be preserved.

Public asset files not being truncated when rewritten

During development, if an asset file is shortened due to editing, the resulting copy in public/assets folder is overwritten, but not truncated. For example, given the following source asset in apps/web/stylesheets:

html {
  position: relative;
  min-height: 100%;
}

.footer {
  position: absolute;
  bottom: 0;
  width: 100%;
  height: 60px;
  background-color: #f5f5f5;
}

When first requested, an asset file in public/assets is written thus:

html {
  position: relative;
  min-height: 100%;
}

.footer {
  position: absolute;
  bottom: 0;
  width: 100%;
  height: 60px;
  background-color: #f5f5f5;
}

If the html block is then removed from the source asset file, the resulting asset file written to the public/assets folder is:

.footer {
  position: absolute;
  bottom: 0;
  width: 100%;
  height: 60px;
  background-color: #f5f5f5;
}
00%;
  height: 60px;
  background-color: #f5f5f5;
}

Hanami::Assets::MissingManifestFileError

Hello, I'm trying to deploy Hanami project to AWS ElasticBeanstalk, but having this issue. Assets precompilation "pre" hook seems completed successfully, without any issues. But when I'm opening app in browser, I'm getting this in puma.log:

2018-07-01 08:16:09 +0000: Rack app error handling request { GET  }
#<Hanami::Assets::MissingManifestFileError: Can't read manifest: /var/app/current/public/assets.json>
/var/app/current/vendor/bundle/ruby/2.5.0/gems/hanami-assets-1.2.0/lib/hanami/assets/config/manifest.rb:65:in `method_missing'
/var/app/current/vendor/bundle/ruby/2.5.0/gems/hanami-assets-1.2.0/lib/hanami/assets/configuration.rb:608:in `compile_path'
/var/app/current/vendor/bundle/ruby/2.5.0/gems/hanami-assets-1.2.0/lib/hanami/assets/configuration.rb:403:in `asset_path'

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.