pa3*_*a3k 37 javascript ruby-on-rails import-maps ruby-on-rails-7
我创建了新的 Rails 7 项目rails new my_project
,但在包含要由 Rails 处理的自定义 JS 文件时遇到问题。
我的“javascript/application.js”
import "@hotwired/turbo-rails"
import "controllers"
import "chartkick"
import "Chart.bundle"
import "custom/uni_toggle"
Run Code Online (Sandbox Code Playgroud)
我的自定义 JS 文件:“javascript/custom/uni_toggle.js”
function uniToggleShow() {
document.querySelectorAll(".uni-toggle").forEach(e => e.classList.remove("hidden"))
}
function uniToggleHide() {
console.log("uni toggle hide")
document.querySelectorAll(".uni-toggle").forEach(e => e.classList.add("hidden"))
}
window.uniToggleShow = uniToggleShow
window.uniToggleHide = uniToggleHide
Run Code Online (Sandbox Code Playgroud)
我在我的布局中使用<%= javascript_importmap_tags %>
和我的“config/importmap.rb”
pin "application", preload: true
pin "@hotwired/turbo-rails", to: "turbo.min.js", preload: true
pin "@hotwired/stimulus", to: "stimulus.min.js", preload: true
pin "@hotwired/stimulus-loading", to: "stimulus-loading.js", preload: true
pin_all_from "app/javascript/controllers", under: "controllers"
Run Code Online (Sandbox Code Playgroud)
Ale*_*lex 87
1. Quickstart - quick things you should know\n2. `pin_all_from` - a few details\n3. `pin` ...\n4. Run in a console - when you need to figure stuff out\n5. Relative imports - don\'t do it, unless you want to\n6. Examples - to make it extra clear\n
Run Code Online (Sandbox Code Playgroud)\n如果您不使用,实际上importmap-rails
,您不应该遇到任何问题。然后添加一个文件import "./path/to/file"
。如果您正在bin/dev
使用jsbundling-rails
.
如果您使用importmap-rails
,则无需编译,每个文件都必须在开发和生产中单独提供,并且每个导入都必须映射到浏览器要获取的 URL。
pin
是pin_all_from
一种构建importmap
. 导入通过资产 URL 映射到本地文件。因此请记住,import "something"
可以映射到 url /assets/file-123.js
,该 url 可以映射到文件app/some_asset_path/file.js
或在生产中public/assets/file-123.js
:
<script type="importmap" data-turbo-track="reload">{\n "imports": {\n "application": "/assets/application-da9b182f12cdd2de0b86de67fc7fde8d1887a7d9ffbde46937f8cd8553cb748d.js",\n "@hotwired/turbo-rails": "/assets/turbo.min-49f8a244b039107fa6d058adce740847d31bdf3832c043b860ebcda099c0688c.js",\n "@hotwired/stimulus": "/assets/stimulus-a1299f07b3a1d1083084767c6e16a178a910487c81874b80623f7f2e48f99a86.js",\n "@hotwired/stimulus-loading": "/assets/stimulus-loading-6024ee603e0509bba59098881b54a52936debca30ff797835b5ec6a4ef77ba37.js",\n "controllers/application": "/assets/controllers/application-44e5edd38372876617b8ba873a82d48737d4c089e5180f706bdea0bb7b6370be.js",\n "controllers/hello_controller": "/assets/controllers/hello_controller-29468750494634340c5c12678fe2cdc3bee371e74ac4e9de625cdb7a89faf11b.js",\n "controllers": "/assets/controllers/index-e70bed6fafbd4e4aae72f8c6fce4381d19507272ff2ff0febb3f775447accb4b.js",\n }# ^ ^\n # | |\n # names you use to import urls browser uses to get it\n # | ^ \n # | |\n # `------> mapped to ---------\'\n}</script>\n
Run Code Online (Sandbox Code Playgroud)\n一旦你有了导入图,你就可以得到import
你需要的东西了。Importmap 不加载任何内容,它只是一个配置。
假设我们添加了一个插件目录:
\napp/\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 javascript/\n \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 application.js # <= imports go here and other js files\n \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 plugin/\n \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 app.js\n \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 index.js\nconfig/\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 importmap.rb # <= pins go here\n
Run Code Online (Sandbox Code Playgroud)\n固定单个文件:
\n# config/importmap.rb\npin "plugin/app"\npin "plugin/index"\n\n# app/javascript/application.js\nimport "plugin/app" # which maps to a url which maps to a file\nimport "plugin/index"\n
Run Code Online (Sandbox Code Playgroud)\n或者固定插件目录和子目录中的所有文件:
\n# config/importmap.rb\npin_all_from "app/javascript/plugin", under: "plugin"\n\n# app/javascript/application.js\nimport "plugin/app"\nimport "plugin"\n
Run Code Online (Sandbox Code Playgroud)\n不要使用相对导入,例如import "./plugin/app"
,它可能在开发中有效,但在生产中会崩溃。
\n查看输出bin/importmap json
以了解可以导入哪些内容并验证importmap.rb配置。
不要在开发中预编译,它将提供预编译的资源,public/assets
当您进行更改时,这些资源不会更新。
\n运行bin/rails assets:clobber
以删除预编译资源。
如果出现问题,app/javascript目录必须位于:
\n Rails.application.config.assets.paths
\ napp/assets/config/manifest.js
并且为//= link_tree ../../javascript .js
固定文件并不会使它们加载。它们必须导入application.js
:
// app/javascript/application.js\nimport "plugin"\n
Run Code Online (Sandbox Code Playgroud)\n或者,如果您想拆分捆绑包,可以在布局中使用单独的模块标签:
\n<%= javascript_import_module_tag "plugin" %>\n
Run Code Online (Sandbox Code Playgroud)\n或模板:
\n<% content_for :head do %>\n <%= javascript_import_module_tag "plugin" %>\n<% end %>\n\n# add this to the end of the <head> tag:\n# <%= yield :head %>\n
Run Code Online (Sandbox Code Playgroud)\n除了 之外,您还可以添加另一个入口点application.js
,假设您已经添加了app/javascript/admin.js
。您可以使用所有引脚导入它:
# this doesn\'t `import` application.js anymore\n<%= javascript_importmap_tags "admin" %>\n
Run Code Online (Sandbox Code Playgroud)\n因为application
pinpreload: true
默认设置了选项,所以它会发出加载application.js
文件的请求,即使您application
使用admin
. 预加载和导入是两件独立的事情,一件事不会导致另一件事。删除preload
选项以避免不必要的请求。
固定目录和子目录中的所有文件。
\nhttps://github.com/rails/importmap-rails/blob/v1.1.2/lib/importmap/map.rb#L33
\ndef pin_all_from(dir, under: nil, to: nil, preload: false)\n clear_cache\n @directories[dir] = MappedDir.new(dir: dir, under: under, path: to, preload: preload)\nend\n
Run Code Online (Sandbox Code Playgroud)\ndir
- 相对于Rails.root的路径或绝对路径。
选项:
\n:under
- 可选的[1]引脚前缀。如果您有index.js
文件,则需要。
:to
- 可选的[1]资产路径。返回到: under选项。如果省略:under则为必需。\n此路径相对于Rails.application.config.assets.paths。
:preload
- 添加模块预加载链接(如果设置为true
:)
<link rel="modulepreload" href="/assets/turbo-5605bff731621f9ca32b71f5270be7faa9ccb0c7c810187880b97e74175d85e2.js">\n
Run Code Online (Sandbox Code Playgroud)\n:under
是:to
必需的要将所有文件固定在插件目录中:
\n<link rel="modulepreload" href="/assets/turbo-5605bff731621f9ca32b71f5270be7faa9ccb0c7c810187880b97e74175d85e2.js">\n
Run Code Online (Sandbox Code Playgroud)\n以下是它们的组合方式:
\n (如果某些功能不起作用,请选择您的选项并按照箭头操作,尤其是该path_to_asset
部分,您可以在控制台中尝试,请参见下文)
pin_all_from "app/javascript/plugin", under: "plugin"\n\n# NOTE: `index.js` file gets a special treatment, instead\n# of pinning `plugin/index` it is just `plugin`.\n{\n "imports": {\n "plugin/app": "/assets/plugin/app-04024382391bb910584145d8113cf35ef376b55d125bb4516cebeb14ce788597.js",\n "plugin": "/assets/plugin/index-04024382391bb910584145d8113cf35ef376b55d125bb4516cebeb14ce788597.js"\n }\n}\n
Run Code Online (Sandbox Code Playgroud)\n:to
这里的选项可能并不明显。如果更改:underpath_to_asset
选项,这将很有用,这将导致找不到app.js。
例如,:under选项可以是您想要的任何内容,但:to选项必须是资产管道Sprockets可以找到的路径(请参阅Rails.application.config.assets.paths)并且还可以预编译(请参阅app/assets/配置/manifest.js)。
\n "plugin/app": "/assets/plugin/app-04024382391bb...4145d8113cf788597.js"\n# ^ ^ ^\n# | | | \n# :under | `-path_to_asset("plugin/app.js")\n# | ^ ^\n# | | |\n# |.. (:to||:under)-\' |\n# "#{dir}/app.js" |\n# \'\'\'\'\'`-------------------------\' \n
Run Code Online (Sandbox Code Playgroud)\n指定绝对路径将绕过资产管道:
\npin_all_from "app/javascript/plugin", under: "@plug", to: "plugin"\n\n# Outputs these pins\n#\n# "@plug/app": "/assets/plugin/app-04024382391b1...16beb14ce788597.js"\n# "@plug": "/assets/plugin/index-04024382391bb91...4ebeb14ce788597.js"\n#\n# and can be used like this\n#\n# import "@plug";\n# import "@plug/app";\n
Run Code Online (Sandbox Code Playgroud)\n固定单个文件。
\nhttps://github.com/rails/importmap-rails/blob/v1.1.2/lib/importmap/map.rb#L28
\npin_all_from("app/javascript/plugin", under: "plugin", to: "/plugin")\n\n# "plugin/app": "/plugin/app.js"\n# "plugin": "/plugin/index.js"\n#\n# NOTE: It is up to you to set up `/plugin/*` route and serve these files.\n
Run Code Online (Sandbox Code Playgroud)\nname
- 引脚名称。
选项:
\n:to
- 资产的可选路径。跌回到{name}.js
. 此路径相对于Rails.application.config.assets.paths。
:preload
- 添加模块预加载链接(如果设置为)true
固定本地文件时,指定相对于app/javascript目录(或供应商或任何其他资产目录)的名称。
\ndef pin(name, to: nil, preload: false)\n clear_cache\n @packages[name] = MappedFile.new(name: name, path: to || "#{name}.js", preload: preload)\nend\n
Run Code Online (Sandbox Code Playgroud)\n以下是它的组合方式:
\npin "plugin/app"\npin "plugin/index"\n\n{\n "imports": {\n "plugin/app": "/assets/plugin/app-04024382391bb910584145d8113cf35ef376b55d125bb4516cebeb14ce788597.js",\n "plugin/index": "/assets/plugin/index-04024382391bb910584145d8113cf35ef376b55d125bb4516cebeb14ce788597.js"\n }\n}\n
Run Code Online (Sandbox Code Playgroud)\n如果您想更改引脚名称:to
,则需要选项为path_to_asset提供有效的文件位置。
例如,要为index.js文件获取与我们从pin_all_from获取的引脚相同的引脚:
\n "plugin/app": "/assets/plugin/app-04024382391bb...16cebeb14ce788597.js"\n# ^ ^\n# | | \n# name `-path_to_asset("plugin/app.js")\n# ^\n# |\n# (:to||"#{name}.js")-\'\n
Run Code Online (Sandbox Code Playgroud)\n您可以在控制台中乱搞Importmap
,调试和了解哪些有效、哪些无效的速度更快:
pin "plugin", to: "plugin/index"\n\n{\n "imports": {\n "plugin": "/assets/plugin/index-04024382391bb910584145d8113cf35ef376b55d125bb4516cebeb14ce788597.js"\n }\n} \n
Run Code Online (Sandbox Code Playgroud)\n如果您进行正确的映射,相对/绝对导入可以工作:
\n>> helper.path_to_asset("plugin/app.js")\n=> "/assets/plugin/app-04024382391bb910584145d8113cf35ef376b55d125bb4516cebeb14ce788597.js"\n\n>> map = Importmap::Map.new\n>> map.pin_all_from("app/javascript/plugin", under: "plugin")\n>> puts map.to_json(resolver: helper)\n{\n "imports": {\n "plugin/app": "/assets/plugin/app-04024382391bb910584145d8113cf35ef376b55d125bb4516cebeb14ce788597.js",\n "plugin": "/assets/plugin/index-04024382391bb910584145d8113cf35ef376b55d125bb4516cebeb14ce788597.js"\n }\n}\n\n>> map.pin("application")\n>> puts map.to_json(resolver: helper)\n{\n "imports": {\n "application": "/assets/application-8cab2d9024ef6f21fd55792af40001fd4ee1b72b8b7e14743452fab1348b4f5a.js"\n }\n}\n\n# Importmap from config/importmap.rb\n>> Rails.application.importmap\n
Run Code Online (Sandbox Code Playgroud)\n// app/javascript/application.js\nimport "./plugin/app"\n
Run Code Online (Sandbox Code Playgroud)\napplication.js映射到消化后的/assets/application-123.js,因为./plugin/app
相对于/assets/application-123.js,它应该正确解析为/assets/plugin/app
具有我们用 pin 制作的导入映射:
"/assets/plugin/app": "/assets/plugin/app-04024382391bb910584145d8113cf35ef376b55d125bb4516cebeb14ce788597.js",\n
Run Code Online (Sandbox Code Playgroud)\n这也应该有效:
\n// app/javascript/plugin/index.js\nimport "./app"\n
Run Code Online (Sandbox Code Playgroud)\n然而,虽然import-maps
支持所有相对和绝对导入,但这似乎不是importmap-rails
.
这应该涵盖几乎所有内容:
\n# config/importmap.rb\npin "/assets/plugin/app", to: "plugin/app.js"\n
Run Code Online (Sandbox Code Playgroud)\n输出来自运行bin/importmap json
:
// app/javascript/application.js\nimport "./plugin/app"\n
Run Code Online (Sandbox Code Playgroud)\n注意区别:
\n"/assets/plugin/app": "/assets/plugin/app-04024382391bb910584145d8113cf35ef376b55d125bb4516cebeb14ce788597.js",\n
Run Code Online (Sandbox Code Playgroud)\n注意模式:
\n// app/javascript/plugin/index.js\nimport "./app"\n
Run Code Online (Sandbox Code Playgroud)\n.\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 app/\n\xe2\x94\x82 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 javascript/\n\xe2\x94\x82 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 admin.js\n\xe2\x94\x82 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 application.js\n\xe2\x94\x82 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 extra/\n\xe2\x94\x82 \xe2\x94\x82 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 nested/\n\xe2\x94\x82 \xe2\x94\x82 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 directory/\n\xe2\x94\x82 \xe2\x94\x82 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 special.js\n\xe2\x94\x82 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 plugin/\n\xe2\x94\x82 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 app.js\n\xe2\x94\x82 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 index.js\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 vendor/\n \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 javascript/\n \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 downloaded.js\n \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 package/\n \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 vendored.js\n
Run Code Online (Sandbox Code Playgroud)\n# this is the only time when both `to` and `under` options can be omitted\n# you don\'t really want to do this, at least not for `app/javascript`\npin_all_from "app/javascript"\npin_all_from "vendor/javascript"\n\n"admin": "/assets/admin-761ee3050e9046942e5918c64dbfee795eeade86bf3fec34ec126c0d43c931b0.js",\n"application": "/assets/application-d0d262731ff4f756b418662f3149e17b608d2aab7898bb983abeb669cc73bf2e.js",\n"extra/nested/directory/special": "/assets/extra/nested/directory/special-04024382391bb910584145d8113cf35ef376b55d125bb4516cebeb14ce788597.js",\n"plugin/app": "/assets/plugin/app-04024382391bb910584145d8113cf35ef376b55d125bb4516cebeb14ce788597.js",\n"plugin": "/assets/plugin/index-04024382391bb910584145d8113cf35ef376b55d125bb4516cebeb14ce788597.js",\n"downloaded": "/assets/downloaded-04024382391bb910584145d8113cf35ef376b55d125bb4516cebeb14ce788597.js",\n"package/vendored": "/assets/package/vendored-04024382391bb910584145d8113cf35ef376b55d125bb4516cebeb14ce788597.js"\n
Run Code Online (Sandbox Code Playgroud)\n同样的事情也适用于供应商:
\npin_all_from "app/javascript/extra", under: "extra" # `to: "extra"` is implied\n"extra/nested/directory/special": "/assets/extra/nested/directory/special-04024382391bb910584145d8113cf35ef376b55d125bb4516cebeb14ce788597.js"\n ^\n\npin_all_from "app/javascript/extra", to: "extra"\n"nested/directory/special": "/assets/extra/nested/directory/special-04024382391bb910584145d8113cf35ef376b55d125bb4516cebeb14ce788597.js"\n ^\n\npin_all_from "app/javascript/extra", under: "@name", to: "extra"\n"@name/nested/directory/special": "/assets/extra/nested/directory/special-04024382391bb910584145d8113cf35ef376b55d125bb4516cebeb14ce788597.js"\n ^\n
Run Code Online (Sandbox Code Playgroud)\n单个文件很简单:
\npin_all_from "app/javascript"\npin_all_from "app/javascript/extra", under: "extra"\npin_all_from "app/javascript/extra/nested", under: "extra/nested"\npin_all_from "app/javascript/extra/nested/directory", under: "extra/nested/directory"\n
Run Code Online (Sandbox Code Playgroud)\n当pin_all_from失败时:
\npin_all_from "app/javascript/extra", to: "extra"\npin_all_from "app/javascript/extra/nested", to: "extra/nested"\npin_all_from "app/javascript/extra/nested/directory", to: "extra/nested/directory"\n
Run Code Online (Sandbox Code Playgroud)\n
小智 27
在我的 Rails 7 应用程序中添加自定义 JS 文件时也遇到问题。我什至关注了 DHH 视频 --> https://www.youtube.com/watch?v=PtxZvFnL2i0但仍然面临困难。以下步骤对我有用:
\n转到config/importmap.rb并添加以下内容:
\npin_all_from "app/javascript/custom", under: "custom"
转到 app/javascript/application.js 文件并添加以下内容:
\nimport "custom/main"
在“app/javascript”目录中,添加“custom”文件夹。
\n在“app/javascript/custom”目录中添加自定义 js 文件“main.js”。
\n在您的终端中运行:
\nRails 资产:预编译
\n启动 Rails 服务器。\nVoil\xc3\xa0
\npa3*_*a3k 22
看完 DHH视频后,我找到了最后一块拼图。
为了使我的自定义 JS 代码正常工作,我刚刚将此行添加到“confing/importmap.rb”中
pin_all_from "app/javascript/custom", under: "custom"
Run Code Online (Sandbox Code Playgroud)