Rails 项目中使用 Rails7 importmap 的体验

lingceng · December 03, 2023 · Last by lingceng replied at December 05, 2023 · 731 hits

前言

最近用 Rails7 + hotwire + importmap 的技术站做了个 AI 站,下图中标黄的都是有较多异步交互的地方,项目中基本没有使用手动 Ajax 与 JSON 交互,仅使用 turbo_frame、turbo_stream 来完成交互。

这里重点说说最新的 importmap 的使用问题,也欢迎大家体验下 kittyai.cn

Importmap 的基本用法

importmap.rb 示例

下面是我的 config/imortmap.rb 部分内容,前面部分是脚手架生成的 hotwire 等库的配置。

这里 controller 目录里的文件是可以动态加载的,例如 HTML 中有某个 data-controller="message",才会加载 message_controller.js 文件。

额外引入了 highlight.js 的高亮配置,注意 importmap 是可以配置目录的。这里也发挥了其按需加载的优势,用到什么语言才加载什么语言的高亮代码。

# Pin npm packages by running ./bin/importmap

pin "application", preload: true
pin "@hotwired/turbo-rails", to: "turbo.min.js", preload: true
pin "@hotwired/stimulus", to: "https://ga.jspm.io/npm:@hotwired/[email protected]/dist/stimulus.js"
pin "@hotwired/stimulus-loading", to: "stimulus-loading.js", preload: true
pin_all_from "app/javascript/controllers", under: "controllers"
pin_all_from "app/javascript/utils", under: "utils"

# For markdown preview
# https://jspm-packages.deno.dev/package/[email protected]
pin "markdown-it", to: "https://ga.jspm.io/npm:[email protected]/dist/markdown-it.js"

# For code syntax highlight
# 这里使用了路径 import https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script/type/importmap
pin "highlight.js/", to: "https://ga.jspm.io/npm:[email protected]/"

开启 HTTPS

另外注意需要开启 HTTP2,能提升多文件加载的效率,例如在 Nginx 要这样配置:

server {
  listen 443 ssl http2
}

逻辑动态 import

除了可以通过静态的 import 来加载依赖,代码中甚至可以动态 import(),例如

import('highlight.js/lib/languages/' + language + ".js").then((module) => {
  hljs.registerLanguage(language, module.default)
  hljs.highlightElement(codeElement)
}).catch(err => {
  console.warn("highlight error", err)
})

遇到的问题

有些库对 ES Module 支持得不好

Javascript 的库一般会说用 npm install 等来安装,会依赖 window.process 里的环境变量,所以直接在 Web 端引入会报错。

例如 tippy.js 这个库,我是在 HTML 中加了下面的代码来 Fix:

<script type="application/javascript">
  // Fix tippy ESM bug. https://github.com/atomiks/tippyjs/issues/990
  window.process = { env: { NODE_ENV: 'production' }}
</script>

Importmap 不会管理 CSS

虽然 JS 可以通过 import 来动态还需加载了,写得很顺滑,但 CSS 并不会。

还是 tippy.js 的例子,需要在 HTML 中额外配置 CSS 依赖

<link rel="stylesheet" href="https://ga.jspm.io/npm:[email protected]/dist/tippy.css">

总结

所以要不要用 importmap 还是需要谨慎。它的优势是细粒度、动态的加载 JS,但其普及度还不是很高,所以容易遇到细节问题。如果要考虑低版本浏览器,importmap 的加载性能和引入的代码的兼容性都可能是问题。

用户第一次进入时,左上区域有一点小错误,Content missing.

Reply to qichunren

收到,我看看

看了一下,GPT 还是 3.0,连 3.5 都不是,答案太落伍了,反应还是可以的

Reply to MarkHoo

有的呀,4.0 Turbo 很强的

You need to Sign in before reply, if you don't have an account, please Sign up first.