By default Lucky comes set up with asset handling using Webpack through Laravel Mix. Laravel Mix is a wrapper for common Webpack functionality that makes configuring Webpack much simpler.
Lucky uses Laravel Mix because it is very simple to configure, it’s fast, and it works well for a lot of apps. It is also has methods for configuring webpack as you normally would so you have the full power of Webpack when you need something more complex.
For a lot of people the default Laravel Mix setup will work out of the box, or with little configuration.
Keep in mind that Lucky does not lock you in to using webpack. You can configure other build methods such as Gulp, Grunt, or your own custom at any time.
There is a webpack.mix.js
file in your project root. You can modify this to
set up React, change your entry points, etc.
Check out the Laravel Mix documentation for more examples of what you can do.
Babel is set up so you can use new features of JavaScript.
The entry point for JavaScript is src/js/app.js
. You’ll see that by default
it imports RailsUjs to handle AJAX, links
with PUT and DELETE requests, and a few other things. Check the
RailsUjs docs for more info.
RailsUjs is required if you are rendering HTML pages in Lucky. If you remove it, PUT and DELETE links will no longer work correctly.
To add new JavaScript add files to src/js/{filename}
and import them in src/js/app.js
The main css file is src/css/app.scss
and is rendered using SASS.
Laravel Mix also sets up autoprefixer so your styles automatically have
vendor prefixes.
You can import other files by putting them in src/css/*
, and importing
them from app.scss
. For example, you might put a component in
src/css/components/_btn.scss
. Remember to end the file with .scss
so
it’s imported correctly.
Lucky comes with some helpful plugins to make CSS a pleasure to write:
Lucky comes with a few JavaScript and CSS packages by default. If you want to
remove the ones you don’t want, run yarn remove {package_name}
.
If it is a CSS or JavaScript package you may also need to remove the imports from
src/css/app.css
or src/js/app.js
.
You can put images, fonts and other assets in the public/assets
folder.
By default there is a public/assets/images
folder, but you can add more, such
as: fonts
, pdfs
, etc.
Webpack is set up to ensure your background images are present and fingerprinted. To have Webpack check your background images and make sure they are ready for caching, make sure to use relative URLs:
// Webpack will find the image and rewrite the URL
background: url("../public/assets/images/my-background.jpg")
// Webpack will not do anything special because the path is not relative
background: url("/images/my-background.jpg")
You can get a path to your assets by using the asset
helper in pages.
# Use this in a page or component
# Will find the asset in public/assets/images/logo.png
img src: asset("images/logo.png")
Note that assets are checked at compile time so if it is not found, Lucky will let you know. It will also let you know if you had a typo and suggest an asset that is close to what you typed.
If the path of the asset is only known at runtime, you can use the dynamic_asset
helper instead.
img src: dynamic_asset("images/#{name}.png")
You can use Lucky::AssetHelpers.asset
just about anywhere:
Lucky::AssetHelpers.asset("images/logo.png")
Lucky comes with Browsersync hooked up. When you
run lucky dev
Browsersync will open a tab and automatically reload styles and
JavaScript for you. When you change any application files the browser will
reload once compilation has been successful.
You can customize Browsersync in the bs-config.js
file. You can see a list of
options for Browsersync.
Fingerprinting means that every asset has a special string of characters appended to the filename so that the browser can cache the file safely. When an asset changes, the fingerprint changes and the browser will use the new version.
Make sure to use the asset
macro to get fingerprinted assets.
Lucky supports static asset compression out of the box with a convenient middleware handler, Lucky::StaticCompressionHandler
. You can add to the set of default middleware handlers as necessary in src/app_server.cr
:
[
# ...
Lucky::StaticCompressionHandler.new("./public", file_ext: "br", content_encoding: "br"),
Lucky::StaticCompressionHandler.new("./public", file_ext: "gz", content_encoding: "gzip"),
# ...
]
Multiple instances of the StaticCompressionHandler
can be leveraged to permit different types of compression based on browser support. For example, the settings above would serve Brotli-compressed assets for browsers that support it, and gzipped assets for those that don’t.
Once your app is in production, you may want to serve up your assets through a
CDN. To specify a different
host, you’ll use the asset_host
option in config/server.cr
.
# In config/server.cr
Lucky::Server.configure do |settings|
if LuckyEnv.production?
settings.asset_host = "https://mycdnhost.com"
else
# Serve up assets locally in development and test
settings.asset_host = ""
end
end
If you deploy to Heroku, then you won’t need to do anything. Lucky is already set up to build assets in production.
If deploying outside Heroku, make sure to run yarn prod
before compiling
your project.