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 部分遇到的问题:
- 图片无法引入。之前的 css 是通过 js 直接 import 的,现在需要分开处理,所以简单的把 import css 的代码移除即可。
- stimulus 引入的代码报错。之前 webpack 有个用法,已经无法使用,我用了一个 js 包帮忙处理:esbuild-plugin-stimulus。跟着文档写就行,这样就不需要一个个 controller 手动引入方便许多。
js
const context = require.context("./controllers", true, /\.js$/);
application.load(definitionsFromContext(context));
- js_compressor 我们换成了 terser
css 部分遇到的问题:
- 编译报错,我们把之前写的 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。
- 因为我们之前写的 tailwind 相关的 css 没办法给 assets pipeline 编译,所以是 tailwindcss cli 输出 scss -> 给 assets pipline 再来一次,虽然有点脱裤子放屁,但至少能编译了。
- css compressor 我们换成了 sassc-rails
- 尽管如此,@tailwindcss/typography 还是不能用,必须用的最好等等
最后遇到的大坑:
放到服务器上,发现 esbuild 的 js 文件没有得到正确的输出到 public/assets 中,我认为有用的解决办法:
- 升级到 ruby 最新版,如 2.6.2 最算无法升级到 2.7,也请至少升级到 2.6.8(写文时最新的 2.6 版本)
- 确保 app/assets/builds 正确 push 到了 git 服务器,因为这个目录在 gem 的安装过程中默认会加入.gitignore,所以导致就算目录下有.gitkeep 文件也无法被提交。先把.gitignore 的代码去掉,commit push 后再加回来。
至此,我们选择了 tailwind 输出的代码给 assets pipeline 再压一次,虽然很丑,但是可以用。js 则直接使用 esbuild 的。不得不说,esbuild 的速度是真的很快。这是一次简单的尝鲜,希望能抛砖引玉。