Rails:预编译资产缺少节点模块

Rails: Precompiled assets missing node modules

我在 rails 5.1 应用程序中使用纱线(不是 webpacker,只是默认资产管道)。

运行 开发环境中的本地服务器,我的资产没有遇到任何问题。

但是一旦我预编译我的资产(环境无关紧要)或让 Heroku 打包我的资产,我从 application.sass 文件中导入的所有样式表(节点模块)都不起作用没有了。

该行为的原因是 sass 将所有文件编译成一个输出文件,但由于某种原因似乎错过了包含节点模块并单独加载这些文件的 @import 语句。

所以这个:

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

在开发中编译为:

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

并且在生产中:

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

作为资产单独加载node_module/nodemodule.css,但浏览器无法解析。 Javascript 工作正常。

例如,node_modules 需要与 npm install 一起安装,因此它们可能不会安装在 Heroku 上。查看 https://devcenter.heroku.com/articles/using-multiple-buildpacks-for-an-app

很可能,您需要设置一个 Node.js buildpack 来安装您的 npm 依赖项。

链接来自我的项目,您可以作为参考 在您的 asset.rb 中,您需要在默认 load_path.

中包含 /node_modules 路径

如果您打开 rails console 并输入 Rails.application.config.assets.paths,您应该会看到添加的新路径 /yourproject/node_modules

然后你只需写:

@import "nodemodule.css"

在我的例子中 bootstrap 4 在我的 application.scss

@import bootstrap/scss/bootstrap

对应node_modules/bootstrap/scss/bootstrap.scss

中的文件

对于 jquery.jsbootstrap.js 你可以查看我的 application.js

终于找到问题所在了。这是 sass-rails gem 的一个非常讨厌的错误和 Rails.

sprockets 组件的不幸设计

1) sass-rails

@import 似乎无法像与其他资产一样与 node_modules 一起使用。虽然这些其他资产被编译到一个文件中,但 node_modules 仅作为单独的源被浏览器引用和加载,但最终不会被浏览器使用。

2) sprockets

Sprockets 的 require 语句只有在文件开头时才有效。或者正如他们在 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.

但是,在我的例子中,我从一个文件中导入指令,该文件本身是从 application.sass 导入的。

我遇到了同样的问题。受 this comment 从导入中删除文件扩展名的启发最终修复了它。

这没有用:

@import "@shopify/polaris/styles.css";
@import "@uppy/core/dist/style.css";
@import "@uppy/dashboard/dist/style.css";

虽然这样做了:

@import "@shopify/polaris/styles";
@import "@uppy/core/dist/style";
@import "@uppy/dashboard/dist/style";