Load dynamic SCSS file with Rails + Webpack

1.3k views Asked by At

I'm using the gem rails/webpack to build the assets, but I need build a dynamic SCSS according by a brand, like:

//admin.scss
@import 'variables-<%= 'brand-name' %>';

body {
   background: $primary-color;
}

I have tried adding the loader:

{
  test: /\.scss(\.erb)?/,
  loader: 'sass-loader',
  options: { importExtensions: ['.scss', '.scss.erb', '.css'] }
}

but that didn't work. Is there a way to do something like that?

2

There are 2 answers

0
Matrix On

variable in rails app :

module Constants
  COLORS = {
     COLOR1: '#ff0000',
     COLOR2: '#880000',
  }
end

pass to sass with Hash var :

$colors: (<% Constants::COLORS.each do |name, color| %><%= name %>: <%= color %>,<% end %>)

use variable in ur style file :

body
  color: map-get($colors, 'COLOR1')
2
barnaclebarnes On

Do this in a separate controller action:

layout.html.erb

<%= stylesheet_link_tag stylesheet_path() %>

Stylesheet show controller action

# Render the template to a string
css = Sass::Engine.new(
  render_to_string("path/to/erb_template", :layout => false),
  syntax:     :scss,
  cache:      false,
  read_cache: false,
  style:      :standard,
  sprockets:  {
    context:     self.view_context,
  }
).render

# respond with the rendered string
respond_to do |format|
  format.css { render plain: css, :content_type => "text/css" }
end   

You can then include the ERB variables in the template. Note that this will be put through the sass engine on every single load so you will want to cache this on production.

If you want to keep all your sass nicely organised into separate files just put your variables in one file to render as ERB and the rest just read in as text files.

rendered_sass = [render_to_string("stylesheets/colours", :layout => false),
  File.read(Rails.root.join("app", "javascript", "stylesheets", "main.scss")),
  File.read(Rails.root.join("app", "javascript", "stylesheets", "base.scss")),
  File.read(Rails.root.join("app", "javascript", "stylesheets", "reset.scss")),
  File.read(Rails.root.join("app", "javascript", "stylesheets", "type.scss")),
  File.read(Rails.root.join("app", "javascript", "stylesheets", "layout.scss")),
  File.read(Rails.root.join("app", "javascript", "stylesheets", "map.scss")),
  File.read(Rails.root.join("app", "javascript", "stylesheets", "audio-player.scss")),
  File.read(Rails.root.join("app", "javascript", "stylesheets", "slider.scss"))].join("\n\r")