ViteJS如何取代默认的Rails前端资产管理

194 阅读6分钟

0.动机

我们正在上一个Rails版本的基础上构建[BootrAils]。当Rails 7问世时,看到Webpacker的替代品,我(有点)松了一口气。虽然新的资产管道看起来更好,但似乎还有更好的空间存在。

目前Ruby-on-Rails的前端资产管理对许多开发者来说可能会感觉很笨拙。

  • HTML页面的[实时/自动/热]重载仍然不能原生工作。
  • Rails的资产服务已经发生了多次变化,从无到有(Sprokets出现在Rails 3.1),到不完全可用的importmaps。目前,Rails支持jsbundling,将esbuild(也可以选择其他工具......)包裹起来,然后再注入到Sprockets中。而css捆绑则以另一种方式工作......

如果你想从一开始就有一个合适的、统一的、优雅的、高性能的资产前端管理,那该怎么办?

有一个宝石可以做到这一点

1.前提条件

检查你是否已经安装了ruby 3。检查你是否已经安装了bundler,以及版本7以上的npm。

$> ruby -v  
ruby 3.1.0p0 // you need at least version 3 here  
$> bundle -v  
Bundler version 2.2.10
$> foreman -v 
0.87.2
$> npm -v
7.1.0 // you need at least version 7.1 here 

任何更高的版本都可以使用。

2.创建一个新的简约的Rails应用程序

mkdir railsvite && cd railsvite  
echo "source 'https://rubygems.org'" > Gemfile  
echo "gem 'rails', '7.0.1'" >> Gemfile  
bundle install  
bundle exec rails new . --force --css=bootstrap --minimal
bin/rails db:create
bin/rails db:migrate

3.安装vite_rails

打开Gemfile,并添加

gem 'vite_rails'

然后在你的终端中

bundle install
bundle exec vite install

4.vite_rails安装到你的Rails应用中的内容

.gitignore被改变

# Vite Ruby
/public/vite
/public/vite-dev
/public/vite-test
node_modules
*.local
.DS_Store

好了,这里没有什么惊喜。Vite.js是用来处理npm资产的,所以node_modules被安全地忽略了。public/里面的内容在技术上是vite_rails所需要的,到目前为止,我们不需要知道它是什么。

.Procfile.dev

从Rails 7开始,你需要foreman来启动你的本地服务器,./bin/dev 。这个命令实际上是在后台调用foreman,寻找本地的.Procfile.dev

vite_rails 覆盖默认的,如下所示。

vite: bin/vite dev
web: bin/rails s

好的,前端部分与服务器分开运行。

app/frontend/entrypoints/application.js

哇!这下可好了。神奇的事情现在开始发生了。现在所有的东西都由app/frontend来管理,而不是为javascript和其他类型的资产建立一个单独的目录。这让事情变得更清晰了。这个文件的内容主要是文档,以及来自控制台的 "hello world",所以我们现在不会去研究它(但为了好奇,你可以这样做)。

app/views/layouts/application.html.erb

有趣的部分在这里。

<%= vite_client_tag %>
<%= vite_javascript_tag 'application' %>

vite_client_tag :根据文档,渲染Vite客户端以启用热模块重新加载。

vite_javascript_tag 'application' : 嗯,乍一看,这个标签应该包括vite生成的javascript。

因此,不再有不明确的javascript和样式表包含:现在Vite为我们保留了一切。

package.json

{
  "devDependencies": {
    "vite": "^2.7.3",
    "vite-plugin-ruby": "^3.0.4"
  }
}

vite.config.ts

import { defineConfig } from 'vite'
import RubyPlugin from 'vite-plugin-ruby'

export default defineConfig({
  plugins: [
    RubyPlugin(),
  ],
})

我们可以从vite.config.js中了解到的是,我们将从vite.js本身获得收益。所以所有来自Vite.js的文档对我们的项目都是有利可图的。看看RubyPlugin被包含得多好。它没有给我们的配置带来麻烦,而且所有的

Vite本身也包括在内。没有什么可隐藏的,Vite-ruby-plugin在这里为Vite和Rails应用程序之间架起了桥梁(标签助手...)。

其他更改的文件

不太有趣,但值得一提的是:修改了package-lock.json(很明显),为了安全起见,也修改了config/initializers/content_security_policy.rb ,并增加了bin/vite ,以便在启动本地服务器时启动vite本身。

4.上半场结束⚽

就这样了 !仅仅是偷看了一下代码,一切从一开始就显得优雅而直观。非常完美!👌

5.创建最小的文件

好了,让我们来测试一下每个人的期望。首先,我们需要最基本的文件。

# inside app/controllers/home_controller.rb  
class HomeController < ApplicationController  
end  
# inside config/routes.rb  
Rails.application.routes.draw do  
  get "home/index"  
  root to: "home#index"  
end  
<!-- inside app/views/home/index.html.erb -->
<h1>This is h1 title</h1>  
  
<button>
   This is a button
</button>  

这3个文件足以触发一个默认视图。让我们来试试。

$/myapp> foreman start -f Procfile.dev

并打开你的浏览器

Title and button

标题和按钮

很好!

6.使用Vite和Rails的CSS

创建文件app/frontend/entrypoints/application.css

// inside app/frontend/entrypoints/application.css
h1 {
  text-decoration: underline;
} 

修改app/views/layouts/application.html.erb

<-- inside app/views/layouts/application.html.erb -->
<html>
  <head>
    <title>Myapp</title>
    <%= vite_client_tag %>
    <%= vite_javascript_tag 'application' %>
    <!-- add line below, remove old stylesheet_link_tag -->
    <%= vite_stylesheet_tag 'application' %>
  </head>
  <body>
    <%= yield %>
  </body>
</html>

现在停止你的本地服务器

重新启动它。

$/myapp> foreman start -f Procfile.dev

并在本地主机上打开你的浏览器

Underlined

下划线

我们刚刚看到了Vite是如何处理样式表的:只需在名字很好的app/frontend/entrypoints文件夹中添加一个入口,并在你的布局中用vite_stylesheet_tag帮助器引用它。

7.用Rails和Vite进行热重载

"热重载 "是指,每次你在代码编辑器中改变/保存任何东西时,浏览器都会自动刷新。

对于那些已经使用过React/Vue/whateverJSframework的人来说,这听起来已经很明显了,因为当你每天都要写几十行代码的时候,每次按 "f5 "进入浏览器是很乏味的。

但信不信由你,它仍然不适用于默认的Rails应用,即使是最近的Rails 7版本。

让我们试试吧,当Vite被安装后。

热重载CSS

你的localserver应该已经启动。评论并保存整个app/frontend/entrypoints/application.css文件,然后打开你的浏览器。标题的样式应该已经消失了。现在取消注释并保存整个app/frontend/entrypoints/application.css文件。标题的样式应该在你的浏览器中自动加下划线。

热重载就可以了。🎉🎉🎉

热重载JS

app/frontend/entrypoints/application.js中尝试同样的体验。你应该看到在你的浏览器中立即发生变化。

热重载HTML

如果你尝试改变并保存app/views/home/index.html.erb。你的浏览器中发生了什么? 什么都没有。呃--哦。

是时候看看如何给ViteJS添加一个插件了。

8.使用Rails为ViteJS添加一个插件

希望对于我们的HTML来说,ViteJS有一个专门的插件来完成这个任务。

$/myapp> yarn add -D vite-plugin-full-reload

在package.json中快速检查该插件是否安装,然后打开vite.config.ts

// inside vite.config.ts
 import { defineConfig } from 'vite'
 import RubyPlugin from 'vite-plugin-ruby'
 import FullReload from 'vite-plugin-full-reload'
 
 export default defineConfig({
   plugins: [
     RubyPlugin(),
     FullReload(['config/routes.rb', 'app/views/**/*'], { delay: 200 })
   ],
 })

重新启动你的本地服务器。尝试改变并保存app/views/home/index.html.erb,现在任何对视图的改变都会自动出现在你的浏览器中 !

9.好一个gem !

这已经是一个很长的教程了,所以今天就到此为止,但以后还会有更多关于强大的Vite的文章。

我们已经看到ViteJS如何以一种直观的方式完全取代了默认的Rails前端资产管理。

然后我们看到了热重载是如何工作的,以及如何在我们的应用程序中添加Vite插件来实现一个漂亮的开发工作流程。