47
loading...
This website collects cookies to deliver better user experience
12/17 Update: I had incorrectly used an import path for setBasePath
below which inadvertently included the entire Shoelace library. Please review the updated import path for an optimized bundle size!
rails new rails7demo -j esbuild -c postcss
-j esbuild
argument tells Rails you'd like to use esbuild for JavaScript bundling, and -c postcss
for CSS bundling.bin/dev
to boot up Rails along with both esbuild and PostCSS watch processes.yarn add @shoelace-style/shoelace
app/javascript/application.js
file:import "@shoelace-style/shoelace/dist/components/button/button.js"
import "@shoelace-style/shoelace/dist/components/icon/icon.js"
import "@shoelace-style/shoelace/dist/components/spinner/spinner.js"
app/assets/stylesheets/application.postcss.css
:body {
font-family: -apple-system, sans-serif;
background: #eee;
}
bin/rails generate controller Articles index --skip-routes
config/routes.rb
file:Rails.application.routes.draw do
# Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html
# Defines the root path route ("/")
root "articles#index"
end
app/views/articles/index.html.erb
:<p><sl-button type="primary">
<sl-icon slot="prefix" name="twitter"></sl-icon>
Follow on Twitter
</sl-button></p>
<p><sl-spinner style="font-size: 3rem; --track-width: 6px;"></sl-spinner></p>
bin/dev
and go to http://localhost:3000
and…oh no, that doesn't look right at all! We forgot to add Shoelace's global stylesheet to include its CSS variables on the site!application.js
file, esbuild and PostCSS will take turns clobbering the output application.css
file in app/assets/builds
. 🙁 And if you try to import the stylesheet directly inside of application.postcss.css
, it doesn't work at all, because the PostCSS config doesn't do anything special to @import
statements so you can't actually import anything from the node_modules
folder. ☹️build:css
script inside package.json
to something other than application.css
, then adding a second stylesheet_link_tag
to your application layout. This is probably the best solution overall. But I thought it would be worthwhile to see if we could keep the existing build configuration as-is, and simply fix the PostCSS import issue instead. So let's try that.yarn add postcss-import
postcss.config.js
file so it looks like this:const atImport = require("postcss-import")
module.exports = {
plugins: [
atImport,
require('postcss-nesting'),
require('autoprefixer'),
],
}
application.postcss.css
file:@import "@shoelace-style/shoelace/dist/themes/light.css";
public
and call it a day.package.json
so they look like this:"scripts": {
"build": "esbuild app/javascript/*.* --bundle --sourcemap --outdir=app/assets/builds",
"build:css": "yarn shoelace:copy-assets && postcss ./app/assets/stylesheets/application.postcss.css -o ./app/assets/builds/application.css",
"shoelace:copy-assets": "mkdir -p public/shoelace-assets && cp -r node_modules/@shoelace-style/shoelace/dist/assets public/shoelace-assets"
}
yarn shoelace:copy-assets
in front of the PostCSS command, and then in the copy-assets script we create a new folder and copy the files out of node_modules
. We do this every time we boot up the site, so in future if you upgrade Shoelace, you'll always have the most up-to-date icon set.application.js
so Shoelace knows where to find the icon assets:import { setBasePath } from "@shoelace-style/shoelace/dist/utilities/base-path.js"
setBasePath("/shoelace-assets")
bin/dev
and presto! Your Shoelace button now has a Twitter icon to go with it.