Rails 尝鲜 Rails 7 的 esbuild,谈谈遇到的坑

bluecoda · 2021年09月13日 · 最后由 zhongsheng 回复于 2021年09月14日 · 1734 次阅读

DHH 最近很高产,新出了 2 个 gem: jsbundling-rails 和 cssbundling-rails,虽然才 0.1.x(本文用的 0.1.1),肯定还有很多 bug,但是我已经迫不及待想试试看 esbuild 的速度了。手头上有个项目,用了 tailwind,stimulus,用 webpack 编译速度并不快,感觉这个项目正好合适,马上开干。

这两个 gem 理解起来很简单,jsbundling 可以通过 esbuild 把 js 编译到 app/assets/builds,cssbundling 也类似,我用的 tailwind,默认会使用 tailwindcss cli 编译 css 到 app/assets/builds,然后通过 app/assets/config/manifest.js 引入对应文件,从而在 layout 中直接引用编译好的文件。开始之前,记得先把 webpacker 从 gemfile 里去掉。

js 部分遇到的问题:

  1. 图片无法引入。之前的 css 是通过 js 直接 import 的,现在需要分开处理,所以简单的把 import css 的代码移除即可。
  2. stimulus 引入的代码报错。之前 webpack 有个用法,已经无法使用,我用了一个 js 包帮忙处理:esbuild-plugin-stimulus。跟着文档写就行,这样就不需要一个个 controller 手动引入方便许多。 js const context = require.context("./controllers", true, /\.js$/); application.load(definitionsFromContext(context));
  3. js_compressor 我们换成了 terser

css 部分遇到的问题:

  1. 编译报错,我们把之前写的 tailwind 相关的 css 代码都放到 applcation.tailwind.css 中,有些 tailwind 代码还是没有展开,所以研究之后,用 postcss 的方式进行编译后问题得到解决:tailwindcss --postcss -i ./app/assets/stylesheets/tailwind/application.tailwind.scss -o ./app/assets/builds/_application.scss。此处因为我们在这个 css 上套了一层 assets pipeline,所以用这个输出 scss 的方式,不要照搬。postcss 的配置就用 webpack 之前写好的,也可以继续 purge。
  2. 因为我们之前写的 tailwind 相关的 css 没办法给 assets pipeline 编译,所以是 tailwindcss cli 输出 scss -> 给 assets pipline 再来一次,虽然有点脱裤子放屁,但至少能编译了。
  3. css compressor 我们换成了 sassc-rails
  4. 尽管如此,@tailwindcss/typography 还是不能用,必须用的最好等等

最后遇到的大坑:

放到服务器上,发现 esbuild 的 js 文件没有得到正确的输出到 public/assets 中,我认为有用的解决办法:

  1. 升级到 ruby 最新版,如 2.6.2 最算无法升级到 2.7,也请至少升级到 2.6.8(写文时最新的 2.6 版本)
  2. 确保 app/assets/builds 正确 push 到了 git 服务器,因为这个目录在 gem 的安装过程中默认会加入.gitignore,所以导致就算目录下有.gitkeep 文件也无法被提交。先把.gitignore 的代码去掉,commit push 后再加回来。

至此,我们选择了 tailwind 输出的代码给 assets pipeline 再压一次,虽然很丑,但是可以用。js 则直接使用 esbuild 的。不得不说,esbuild 的速度是真的很快。这是一次简单的尝鲜,希望能抛砖引玉。

builds 内容应该设置 gitignore,在 assets:precompile 之前编译。

Rei 回复

用命令行 install 这些 gem 的时候默认就加入 gitignore 了

在 assets:precompile 之前编译这个功能也是两个 gem 本身都设置好的,不需要手动

但是要确保 app/assets/builds目录在git上存在,否则会有上面说的public/assets下没有builds/下输出的文件的问题(尽管manifest.json中已经设置//= link_tree ../builds .js 也会输出不到)。可能是 gem 不够成熟,也可能是我自己的个别问题,还没有深入研究。

3 楼 已删除

哎哟,发现 install 脚本的 gitignore 规则写错了,导致 .keep 文件被忽略了。晚上没人提我就去提个 pr。

错误:

/app/assets/builds
!/app/assets/builds/.keep

正确:

/app/assets/builds/*
!/app/assets/builds/.keep

为了避坑我直接用的 github 上未发布的 rails7

需要 登录 后方可回复, 如果你还没有账号请 注册新账号