我正在使用 Importmap for Rails 7 实现 JavaScript 模块模式,并且遇到与在生产环境中加载自定义
helpers
JS 文件相关的错误。
我的应用程序/javascript 的文件系统结构如下:
> javascript
> controllers
> application.js
> index.js
> first_controller.js
> second_controller.js
> ...
> helpers
> index.js
> useMixinOne.js
> useMixinTwo.js
> ...
> application.js
以下是从与问题相关的文件中提取的内容:
# 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"
pin_all_from "app/javascript/helpers", under: "helpers"
# app/javascript/application.js
import "@hotwired/turbo-rails"
import "controllers"
import "helpers"
# app/javascript/controllers/first_controller.js
import { Controller } from "@hotwired/stimulus"
import { useMixinOne, useMixinTwo } from "helpers"
// Connects to data-controller="first"
export default class extends Controller {
connect() {
useMixinOne(this);
...
}
}
# app/javascript/helpers/index.js
export * from "./useMixinOne"
export * from "./useMixinTwo"
...
# app/javascript/helpers/useMixinOne.js
export const useMixinOne = controller => {
Object.assign(controller, {
customFunctionFromOne(event) {
console.log("Hello from One")
}
});
};
# app/javascript/helpers/useMixinTwo.js
export const useMixinTwo = controller => {
Object.assign(controller, {
customFunctionFromTwo(event) {
console.log("Hello from Two")
}
});
};
...
当我在开发中使用上述内容时,它有效。
但是,当我在生产中使用它时,它不起作用:在浏览器控制台中我收到如下错误
GET https://www.mywebsite.com/assets/helpers/useMixinOne net::ERR_ABORTED 404 (Not Found)
index-1ee3e17fa548653761aab66bd7ab6d677cc5dc8be43616b1c86e694aee4c4b27.js:1
GET https://www.mywebsite.com/assets/helpers/useMixinTwo net::ERR_ABORTED 404 (Not Found)
index-1ee3e17fa548653761aab66bd7ab6d677cc5dc8be43616b1c86e694aee4c4b27.js:1
...
怎么了?如何使用 Importmap 解决与
helpers
JS 资源相关的错误?
适用于
export
的规则与 import
相同。不要使用相对名称:
export * from "./useMixinOne"
// ^^^^^^^^^^^^^
// this is a module name, just like for imports
如果导入映射中没有匹配的名称,它将不会映射到相应的摘要资产 URL,该 URL 仅在开发中有效。您的导入/导出需要与导入映射中的某些内容匹配:
$ bin/importmap json
{
"imports": {
...
"helpers": "/assets/helpers/index-ab104765b4187e301d3391fb535a15e3754cb6b938bcfecd7984a44a0f1d0628.js",
"helpers/useMixinOne": "/assets/helpers/useMixinOne-4e3c8cd641eae1b19feb43fb775e422c931fd9b40d74ba295881069447d1af59.js",
// ^^^^^^^^^^^^^^^^^^^^^
}
// app/javascritp/helpers/index.js
export * from "helpers/useMixinOne"
从技术上讲,如果您愿意,您可以使相对名称起作用:
# config/importmap.rb
pin_all_from "app/javascript/helpers", under: "/assets/helpers", to: "helpers"
这会给你这个导入地图:
$ bin/importmap json
{
"imports": {
...
"/assets/helpers": "/assets/helpers/index-6f4938f0e494428e95c0211ec9aa57b42a0021726bcf0de91f1eb7c128a971c3.js",
"/assets/helpers/useMixinOne": "/assets/helpers/useMixinOne-4e3c8cd641eae1b19feb43fb775e422c931fd9b40d74ba295881069447d1af59.js"
}
让你的亲戚名字发挥作用:
// app/javascritp/helpers/index.js
export * from "./useMixinOne"
// app/javascript/controllers/first_controller.js
import { useMixinOne } from "../helpers"