7
votes

I created a new rails application using:

rails new blah --webpack -T

I then added primer

yarn add primer

My import works if I do this in /assets/stylesheets/application.scss

@import "~primer/index.scss";

Primer has lots of modules, so the primer/index.scss then references the files from other modules. So even if I put the tilda in my first import, it doesn't solve the problem because in other files it has no tilda.

But the problem is that once the index.scss file loads, there are other files that stop working because they are also referencing files like:

// Core modules
@import "primer-base/index.scss";
@import "primer-box/index.scss";
@import "primer-breadcrumb/index.scss";
@import "primer-buttons/index.scss";
@import "primer-table-object/index.scss";
@import "primer-forms/index.scss";
@import "primer-layout/index.scss";
@import "primer-navigation/index.scss";
@import "primer-pagination/index.scss";
@import "primer-tooltips/index.scss";
@import "primer-truncate/index.scss";

So these imports have to be changed also. I need to solve this so I don't have to prefix with the tilda sign. My assets.rb is already including node_modules so I'm not sure what else I can do?

My /initializers/assets.rb has this:

Rails.application.config.assets.paths << Rails.root.join('node_modules')

Yet in my application.scss file I have to include the tilda sign to reference a scss file:

@import "primer/index.scss";
html {
  font-size: 30px;
}

application.js file:

import "./application.scss";

console.log('Hello World from Webpacker2d');

My layout file:

<!DOCTYPE html>
<html>
  <head>
    <title>Blah</title>
    <%= csrf_meta_tags %>
    <%= csp_meta_tag %>

    <%= stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track': 'reload' %>
    <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>

    <%= javascript_pack_tag    'application' %>
    <%= stylesheet_pack_tag    'application' %>
  </head>

  <body>
    <%= yield %>
  </body>
</html>
3
What's your sass-loader version? - Raviteja
@Raviteja its a brand new rails application, I can't find the word 'loader' in my gemfile.lock. What would it be called? - Blankman
@Raviteja my yarn.lock file has ``` sass-loader "^6.0.7"``` - Blankman
@Blankman Can you show me the part where you say stops working, in what action exactly? I think, I had this issue previously and fixed it different way. - 7urkm3n
@7urkm3n I'm not sure what happened but things are working now. Maybe some dep gem was updated shrugs. - Blankman

3 Answers

1
votes

Would it be an acceptable solution to preprocess all of these files to add the tilde? If so you can do that for a single file like so if in a *nix machine:

cat some_file.scss | ruby -ne 'print $_.sub(/(@import\s*\")([^~])/) { "#{$1}~#{$2}" }' > some_file.scss.tilde
mv some_file.scss.tilde some_file.scss

For multiple files:

for file in $(ls *.scss); do
    cat "$file" | ruby -ne 'print $_.sub(/(@import\s*\")([^~])/) { "#{$1}~#{$2}" }' > "$file.tilde"
    mv "$file".tilde "$file"
done

This will replace your scss files with a version that adds a tilde to any @import declaration that does not already have it. More specifically, it matches @import followed by any whitespace followed by a double quote followed by something that isn't a tilde, and puts a tilde right before that something that wasn't a tilde.

You may want to skip the mv line to test the output first.

If you had to do this multiple times, you could write it into a rake task or script.

0
votes

Not sure why do you want to import node module files seperately.

The best way to use is the following:

npm link my-react-lib

Now, we can create a file and import this library:

vim app/javascript/packs/my-react-component.jsx

import React from 'react' 
import ReactDOM from 'react-dom' 
import MyReactLib from 'my-react-lib'

document.addEventListener('DOMContentLoaded', () => {   ReactDOM.render(
        <MyReactLib />,
        document.body.appendChild(document.createElement('div')),   ) })

Now we can just change the pack tag to use our my-react-component. And refresh our webpack dev server.

<h1>Pages#index</h1> 
<p>Find me in app/views/pages/index.html.erb</p>

<p>Here we will import our React Component using javascript_pack_tag: </p> <%= javascript_pack_tag 'my-react-component' %>

And it works!

0
votes

I just past my simple solution. Since Webpack already installed.

Need to install Foreman for this. Basically rest of the part is the same, except I do not use turbolinks with webpack.

foreman start -f ./Procfile.dev

# Procfile.dev
web: bundle exec puma -p 3000 -e ${RACK_ENV:-development}
webpacker: ./bin/webpack-dev-server
log: tail -f ./log/development.log