Rails: Precompiled assets missing node modules

依然范特西╮ 提交于 2019-12-05 21:15:37

问题


I am using yarn with my rails 5.1 app (not webpacker, just the default asset pipeline).

Running a local server in development environment, I experience no issues with my assets.

But as soon as I precompile my assets (the environment doesn't matter) or let Heroku package my assets, all stylesheets (of node modules) I imported from within my application.sass file don't work anymore.

The reason for that behavior is that sass compiles all files into one output file, but because of some reason appears to miss the @import statements which include node modules and load these files separately.

So this:

@import "components/index.sass"
@import "nodemodule/nodemodule.css"

Compiles to this in development:

// content of "components/index.sass"
// content of "nodemodule/nodemodule.css"

and to this in production:

// content of "components/index.sass"
@import "nodemodule/nodemodule.css"

while loading node_module/nodemodule.css separately as an asset, but the browser cannot resolve it. Javascript works fine.


回答1:


The links are from my project that you can use as reference in your asset.rb you need to include the /node_modules path in your default load_path.

If you open the rails console and input Rails.application.config.assets.paths you should see the new path /yourproject/node_modules added.

Then you simply write:

@import "nodemodule.css"

In my case for bootstrap 4 in my application.scss

@import bootstrap/scss/bootstrap

which correspond to the file in node_modules/bootstrap/scss/bootstrap.scss

for jquery.js and bootstrap.js you can check my application.js




回答2:


I have finally found the problem. It is a very nasty bug of the sass-rails gem & an unfortunate design of the sprockets component of Rails.

1) sass-rails

@import does not seem to work with node_modules as it does with other assets. While those other assets get compiled into one file, node_modules only get referenced, loaded by the browser as separate sources, but ultimately not being used by the browser.

2) sprockets

Sprockets' require statement does only work if it is at the beginning of a file. Or as they put it in their documentation:

Note: Directives are only processed if they come before any application code. Once you have a line that does not include a comment or whitespace then Sprockets will stop looking for directives. If you use a directive outside of the "header" of the document it will not do anything, and won't raise any errors.

However, in my case, I was importing directives from a file that itself was imported from application.sass.




回答3:


The node_modules need to be installed with npm install for example, so they're probably not getting installed on Heroku. Check out https://devcenter.heroku.com/articles/using-multiple-buildpacks-for-an-app

Most likely, you need to setup a Node.js buildpack which will install your npm dependencies.



来源:https://stackoverflow.com/questions/47618780/rails-precompiled-assets-missing-node-modules

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!