理解 importmap-rails

发布: (2026年2月27日 GMT+8 01:15)
5 分钟阅读
原文: Dev.to

It looks like only the source link was provided, but the article’s content to translate isn’t included. Could you please paste the text you’d like translated (excluding any code blocks or URLs you want to keep unchanged)? Once I have the content, I’ll translate it into Simplified Chinese while preserving the original formatting.

介绍

如果你使用过现代 JavaScript,你一定熟悉 ES 模块和 import 语句。Rails 应用可以使用 esbuild(或 vite 或 bun)来实现,但默认(Rails 方式)是 importmap‑rails。它让你可以直接编写

import { Controller } from "@hotwired/stimulus"

而无需任何构建步骤。

什么是 import maps?

Import maps 是一种 Web 标准,用于告诉浏览器如何解析 裸模块标识符(例如 import React from "react")。浏览器需要绝对路径、相对路径或 HTTP URL 来加载模块。

Import map 提供了这种映射,例如:

{
  "imports": {
    "application": "/assets/application-abc123.js",
    "@hotwired/stimulus": "/assets/stimulus.min-def456.js",
    "controllers/application": "/assets/controllers/application-ghi789.js"
  }
}

当你的 JavaScript 写下 import { Controller } from "@hotwired/stimulus" 时,浏览器会在此映射中查找 "@hotwired/stimulus",并加载 /assets/stimulus.min-def456.js

使用 importmap‑rails

importmap-rails gem 为您生成 “ 标签。 在布局中包含它:

此助手读取 config/importmap.rb,输出导入映射,添加 modulepreload 链接(使浏览器立即开始下载您的 JavaScript 文件),并插入您的应用程序入口点。

Source:

配置 pin

config/importmap.rb 中定义映射内容:

pin "application"
pin "@hotwired/turbo-rails", to: "turbo.min.js"
pin "@hotwired/stimulus",   to: "stimulus.min.js"
pin "@rails/request.js",    to: "@rails--request.js.js"

每个 pin 会在 import map 中创建一个映射(条目):

  • 第一个参数 – 你将在 import 语句中使用的裸模块标识符。
  • to: 属性 – 应该从资产管线加载的文件(通常位于 app/javascriptvendor/javascript 下)。

从 npm pin 包

要添加来自 npm 的包,运行:

./bin/importmap pin package-name

该命令会把包文件下载到 vendor/javascript,并在 config/importmap.rb 中添加对应的 pin。默认使用 JSPM.org 作为 CDN,但你可以指定其他来源:

./bin/importmap pin react --from unpkg
./bin/importmap pin react --from jsdelivr

下载的文件会被提交到源码控制,并通过应用的资产管线提供。

Pin 整个目录

你也可以一次性映射整个目录,而不是单独 pin 文件:

pin_all_from "app/javascript/controllers",          under: "controllers"
pin_all_from "app/javascript/turbo_stream_actions", under: "turbo_stream_actions"

under: 属性会创建一个命名空间前缀。目录中的每个文件都可以使用该前缀进行导入。

  • app/javascript/controllers/reposition_controller.js

    import RepositionController from "controllers/reposition_controller"
  • app/javascript/turbo_stream_actions/set_data_attribute.js

    import set_data_attribute from "turbo_stream_actions/set_data_attribute"

Source:

自定义 Turbo Stream 操作

  1. config/importmap.rb映射目录

    pin_all_from "app/javascript/turbo_stream_actions", under: "turbo_stream_actions"
  2. 当 Rails 生成导入映射(“)时,它会扫描该目录并创建类似以下的条目:

    {
      "imports": {
        "turbo_stream_actions": "/assets/turbo_stream_actions/index-abc.js",
        "turbo_stream_actions/set_data_attribute": "/assets/turbo_stream_actions/set_data_attribute-xyz.js"
      }
    }
  3. 创建自定义动作app/javascript/turbo_stream_actions/set_data_attribute.js):

    export default function() {
      // your custom logic
    }
  4. app/javascript/turbo_stream_actions/index.js注册它

    import set_data_attribute from "turbo_stream_actions/set_data_attribute"
    
    Turbo.StreamActions.set_data_attribute = set_data_attribute
  5. 在主入口文件(app/javascript/application.js)中 加载这些动作

    import "turbo_stream_actions"

浏览器通过导入映射解析 "turbo_stream_actions/set_data_attribute",获取编译后的资源,随后该动作即可使用。

Stimulus 集成

  1. 固定 controllers 目录:

    pin_all_from "app/javascript/controllers", under: "controllers"
  2. app/javascript/controllers/index.js 中引导 Stimulus:

    import { application } from "controllers/application"
    import { eagerLoadControllersFrom } from "@hotwired/stimulus-loading"
    
    eagerLoadControllersFrom("controllers", application)
  3. 定义应用程序 (app/javascript/controllers/application.js):

    import { Application } from "@hotwired/stimulus"
    
    const application = Application.start()
    application.debug = false
    window.Stimulus = application
    
    export { application }

eagerLoadControllersFrom 函数会扫描 import map 中以 "controllers/" 开头的条目,并自动导入和注册它们。在 app/javascript/controllers 下添加新的控制器文件后,它会立即可用——无需额外配置。

摘要

  • Import maps 让浏览器在没有打包工具的情况下解析裸模块标识符。
  • importmap‑rails 为 Rails 应用生成 import map 和 modulepreload 链接。
  • 使用 pin 为单个文件固定,使用 pin_all_from 为整个目录固定,使用 ./bin/importmap pin 从 npm 拉取包。
  • under: 命名空间创建一个干净的导入前缀,映射你的目录结构,简化 Turbo Stream 动作、Stimulus 控制器以及其他 JavaScript 模块的集成。
0 浏览
Back to Blog

相关文章

阅读更多 »