最新版本的 Ruby on Rails 重点关注框架不同方面的简单性,并承诺回归“单人框架”(单个开发人员可以有效地构建和维护整个应用程序)。
Importmap Rails 库基于现代 Web 浏览器已经赶上 ECMAScript 规范并可以解释 ES 模块(ESM)的原理。作为一项 Web 标准,Importmap 允许您控制 JavaScript 模块在浏览器中的解析方式并管理依赖项和版本,而无需转译或捆绑发送到浏览器的代码。
这一切都始于应用程序主布局或网页中定义的 importmap 类型的脚本标签。在此标签内,一个 JSON 对象定义了别名及其对应的源代码路径。
<script type="importmap"> { "imports": { "application": "/assets/application.js", "local-time": "https://cdn.jsdelivr.net/npm/local-time@3.0.2/app/assets/javascripts/local-time.es2017-esm.min.js", "utils": "/assets/utils.js" } } </script>
在同一个地图中,您可以混合指向 CDN 或使用本地资源的库路径。要使用此地图中的库,请引用别名。
<!-- Below the importmap script --> <script type="module">import "application"</script>
并在您的application.js中,导入所需的依赖项:
// application.js import LocalTime from "local-time"; LocalTime.start(); import "utils";
浏览器 Chrome 89 、 Safari 16.4 、 Firefox 108 和 Edge 89 均支持导入地图。对于较旧的浏览器,请包含一个polyfill:
<script async src="https://ga.jspm.io/npm:es-module-shims@1.10.1/dist/es-module-shims.js" ></script>
Ruby on Rails 中的导入映射功能遵循上述相同标准,并提供了一种创建映射和版本文件的简单方法。使用名为 heroImage 的 Web 应用程序作为示例(源代码可在 Github 上获取),让我们探索一下实现。
当您创建新的 Rails 8 应用程序时,默认情况下会添加并安装 importmap-rails gem。将创建一个文件config/importmap.rb,您可以在其中固定应用程序中所需的JavaScript代码。
pin "application" pin "@hotwired/turbo-rails", to: "turbo.min.js" pin "@hotwired/stimulus", to: "stimulus.min.js" pin "@hotwired/stimulus-loading", to: "stimulus-loading.js" pin_all_from "app/javascript/controllers", under: "controllers", preload: false
pin 关键字最多需要三个参数。第一个是必需的,因为它是 JavaScript 代码的别名。 pin“application”是文件 application.js 的快捷方式,别名为 application:
pin "application", to: "application.js"
当别名和文件名不同时,使用关键字::
pin "@hotwired/turbo-rails", to: "turbo.min.js"
pin_all_from 关键字有助于一次引用多个文件。第一个参数是 JavaScript 文件所在的路径,under: 参数是每个文件的别名的前缀。生成的别名使用下的前缀和文件名,例如alert_controller.js文件的controllers/alert-controller。
要可视化 Importmap JSON 文件,请执行:
<script type="importmap"> { "imports": { "application": "/assets/application.js", "local-time": "https://cdn.jsdelivr.net/npm/local-time@3.0.2/app/assets/javascripts/local-time.es2017-esm.min.js", "utils": "/assets/utils.js" } } </script>
Rails 通过 Propshaft gem 解析所有 JavaScript,它解析 JavaScript 代码的物理路径,映射到 /assets Web 路径,并将摘要添加到每个文件中,以实现更好的缓存和失效。
Propshaft 从资产配置中发现物理路径:
<!-- Below the importmap script --> <script type="module">import "application"</script>
确保您的文件存在于任何已注册的路径中,或添加您自己的路径以供 Propshaft 和 Importmap 发现。
Rails 中的 Importmap 允许您指定浏览器应如何加载 JavaScript 文件。有两个选项:预加载(默认)和无预加载。预加载告诉浏览器尽快下载文件。 Importmap 生成一个带有 rel="modulepreload":
的链接标签
// application.js import LocalTime from "local-time"; LocalTime.start(); import "utils";
如果将 preload 参数设置为 false,则不会生成链接标签,浏览器会在需要时下载文件。
使用 Rails 的 Importmap,您还可以使用 URL 的 to: 参数固定 CDN 中的 JavaScript 代码:
<script async src="https://ga.jspm.io/npm:es-module-shims@1.10.1/dist/es-module-shims.js" ></script>
Importmap 包含一个 CLI,用于将固定 或取消固定 JavaScript 代码到config/importmap.rb 文件中。它还包括更新、审核和检查版本的命令:
pin "application" pin "@hotwired/turbo-rails", to: "turbo.min.js" pin "@hotwired/stimulus", to: "stimulus.min.js" pin "@hotwired/stimulus-loading", to: "stimulus-loading.js" pin_all_from "app/javascript/controllers", under: "controllers", preload: false
当对 JavaScript 包使用 pin 命令时,Importmap 不会将 to: 参数设置为 CDN,而是解析包依赖项并将包和依赖项下载到 vendor/javascript ,允许 Rails 应用程序提供这些文件:
pin "application", to: "application.js"
当您的包在 JavaScript 包中具有简单的依赖项或定义良好的依赖项时,此方法效果很好。如果情况并非如此,则使用 Importmap 在 vendor/javascript 供应代码会变得具有挑战性。它可能与 URL 和手动依赖项添加一起使用,或者您可以调整供应商的代码以使其工作。
有两种方法可以创建与 Importmap 兼容的 Ruby on Rails gem。第一种方法允许您的 gem 提供 JavaScript 代码,您可以选择将其固定在 Importmap 配置中。这就是 turbo-rails 和 stimulus-rails gem 的实现方式。
将 JavaScript 代码放入 gem 的 app/assets/javascripts 文件夹中。您可能需要一个额外的过程来缩小 JavaScript 文件并生成 JavaScript 映射文件。然后,在 Engine 类中,定义一个初始化器钩子以使用 Propshaft 声明 JavaScript 代码:
<script type="importmap"> { "imports": { "application": "/assets/application.js", "local-time": "https://cdn.jsdelivr.net/npm/local-time@3.0.2/app/assets/javascripts/local-time.es2017-esm.min.js", "utils": "/assets/utils.js" } } </script>
第二个选项使用 Importmap 配置文件。如果您的引擎有其布局模板,并且视图与主机应用程序隔离,并且引擎不需要与主机应用程序共享 JavaScript 代码,您可以在 config/importmap.rb 创建一个 Importmap 配置文件,设置引脚,将 JavaScript 代码放置在 app/javascript,并使用初始值设定项配置引擎。
打开您的engine.rb Ruby 文件并添加Importmap 配置文件和扫描器:
<!-- Below the importmap script --> <script type="module">import "application"</script>
指定要在引擎布局模板中使用的导入映射:
// application.js import LocalTime from "local-time"; LocalTime.start(); import "utils";
要与主机应用程序共享 JavaScript 代码(例如 Stimulus 控制器),请创建部分 Importmap 配置文件并将引擎设置为将其与主机应用程序中的主文件合并。
在 config/importmap.rb 创建一个 Importmap 配置文件,并添加 JavaScript 引脚以与主机应用程序共享。如果您有外部包的依赖项,请通过生成器或安装程序将它们添加到主机应用程序:
<script async src="https://ga.jspm.io/npm:es-module-shims@1.10.1/dist/es-module-shims.js" ></script>
打开你的engine.rb 文件并添加一个初始化器:
pin "application" pin "@hotwired/turbo-rails", to: "turbo.min.js" pin "@hotwired/stimulus", to: "stimulus.min.js" pin "@hotwired/stimulus-loading", to: "stimulus-loading.js" pin_all_from "app/javascript/controllers", under: "controllers", preload: false
从 Ruby on Rails 开发人员的角度来看,使用 Importmap 的主要优点是不需要类似 JavaScript 运行时的节点,并且不受 node_modules 依赖关系。
此外,您不需要在开发模式下进行额外的过程来转译和缩小 JavaScript 代码。您依靠 Web 标准将代码提供给浏览器。在反向代理后面部署 Rails 应用程序有几个好处。首先,如果您启用 HTTP/2 协议,您的浏览器可以通过单个 HTTP 连接获取多个文件,并且下载许多小 JavaScript 文件不会影响性能。
启用代理使用 gzip 或 brotli 压缩可确保您发送非常小的文件,同时在使用浏览器开发人员工具时保持可读性。如果更改一个文件,只需使浏览器下载的该特定文件失效即可。由于 Propshaft 添加到所有文件的指纹,浏览器知道文件已被修改。
使用像 Thruster 这样的反向代理以及 Puma 可以卸载 Rails 应用程序提供的资源。 Thruster 可以缓存资源并在客户端请求文件时提供它们。
在某些情况下,您应该避免在 Rails 应用程序中使用 Importmap。如果您正在使用 React、Vue 或任何其他类似工具构建 SPA 应用程序,那么您很可能正在使用 TypeScript 编写代码。在这种情况下,您应该坚持捆绑策略。
此外,如果您需要支持较旧的浏览器,与代码转译捆绑在一起是更好的选择。
以上是Nobuild 与 Rails 和 Importmap的详细内容。更多信息请关注PHP中文网其他相关文章!