将旧版 Rails 应用程序迁移到 Rails 6
3 个 JavaScript 库仅在两个页面上使用,并且考虑到一个页面的大小,目标是仅在这些页面上调用它们。
yarn add grapheme-splitter
运行正常,但是其他两个库没有通过yarn列出。因此 application.js
包含:
require("grapheme-splitter")
import("../src/segments_calculator")
import("../src/segments_viewer")
但是当调用这些脚本时
<%= javascript_pack_tag 'grapheme_splitter' %>
[...]
<%= javascript_pack_tag 'segments_calculator' %>
Webpacker can't find grapheme_splitter in /Volumes/sjt/r/fidel/public/packs/manifest.json. Possible causes: [...]
Webpacker can't find segments_calculator in /Volumes/sjt/r/fidel/public/packs/manifest.json. Possible causes: [...]
在所有最初的原因中,webpacker被配置为编译(并且我已经看到它这样做)并且没有迹象表明该文件曾经被修改过(相同的创建和修改日期)
development:
<<: *default
compile: true
为什么第四个解释是有效的你的 webpack 配置没有创建 list 。
?我确实看到 list 中缺少它,但仅在特定页面(和运行)上使用的其他库也是如此。
如何让页面运行,只加载特定的 javascript(无论是 yarn 管理的还是非 yarn 管理的)?
更新
{
"application.js": "/packs/js/application-3eebddca0d1bd59ab625.js",
"application.js.map": "/packs/js/application-3eebddca0d1bd59ab625.js.map",
"entrypoints": {
"application": {
"js": [
"/packs/js/application-3eebddca0d1bd59ab625.js"
],
"js.map": [
"/packs/js/application-3eebddca0d1bd59ab625.js.map"
]
},
"foundation-datepicker": {
"js": [
"/packs/js/foundation-datepicker-a70417b8f24614757c48.js"
],
"js.map": [
"/packs/js/foundation-datepicker-a70417b8f24614757c48.js.map"
]
},
"municipals": {
"js": [
"/packs/js/municipals-ba2af3f728fdf4b1104e.js"
],
"js.map": [
"/packs/js/municipals-ba2af3f728fdf4b1104e.js.map"
]
},
"what-input": {
"js": [
"/packs/js/what-input-f10be0b1923799dfc64d.js"
],
"js.map": [
"/packs/js/what-input-f10be0b1923799dfc64d.js.map"
]
}
},
"foundation-datepicker.js": "/packs/js/foundation-datepicker-a70417b8f24614757c48.js",
"foundation-datepicker.js.map": "/packs/js/foundation-datepicker-a70417b8f24614757c48.js.map",
"municipals.js": "/packs/js/municipals-ba2af3f728fdf4b1104e.js",
"municipals.js.map": "/packs/js/municipals-ba2af3f728fdf4b1104e.js.map",
"what-input.js": "/packs/js/what-input-f10be0b1923799dfc64d.js",
"what-input.js.map": "/packs/js/what-input-f10be0b1923799dfc64d.js.map"
}
最佳答案
背景
“grapheme-splitter”和“segments_calculator”模块的内容包含在“application.js”捆绑文件中。
当 webpack 编译时,它会创建一个或多个依赖图。根据 Webpack-er 约定,依赖关系图的“入口点”是 app/javascript/packs/目录中包含的文件。这些“pack”文件中的每一个都会作为输出编译到 public/packs/目录中(假设您尚未将 webpack 配置为跨包共享模块)。
快速修复
因此,将这些行放入“application.js”包文件中:
require("grapheme-splitter")
import("../src/segments_calculator")
import("../src/segments_viewer")
你的意思是:将这些模块包含在“application.js”文件中,该文件将输出输出到 public/packs/目录中。要在给定页面上呈现这些模块,您需要使用 <%= javascript_pack_tag 'application' %>
。否则,您可以将这些模块放入不同的包文件中并进行渲染。这应该足以帮助您入门。
更好的修复
但是,您在特定 View 中询问了 JavaScript。对于“特定于页面”的 JavaScript 和现代 JavaScript bundler (如 webpack)的推荐方法是使用 dynamic imports以及单个(或很少)的包文件。目前,您似乎已经有四个包 - “application”、“foundation-datepicker”、“municipals”、“what-input” - 对于小型应用程序来说(在我看来,一般来说)这太多了。您正面临着重复模块并造成性能瓶颈的风险,as described in this post .
通过动态导入,您可以推迟依赖图的渲染部分,并使用事件监听器或函数调用一次下载和执行小块。示例可能如下所示:
window.addEventListener('DOMContentLoaded', () => {
if (document.getElementById("graphene-page")) {
import('../src/graphene-page') // <-- dynamic import
}
});
关于javascript - 让 Rails Webpacker 仅在特定 View 中应用 JavaScript( yarn 管理的和非 yarn 管理的),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65735721/