javascript - 让 Rails Webpacker 仅在特定 View 中应用 JavaScript( yarn 管理的和非 yarn 管理的)

标签 javascript ruby-on-rails webpack

将旧版 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/

相关文章:

javascript - 尝试在 React 中迭代 JSON 对象

ruby-on-rails - Rspec Controller 测试在 #create 与关联后失败

javascript - Webpack/Angular - Materialise 未加载

Angular 2。异常 : No Directive annotation found on Alert

javascript - 无法将对象转换为原始值

javascript - parseInt 最后一个数字并保存为变量

ruby-on-rails - 如何为集合设置 Rails 表单选择

ruby-on-rails - 如何在 Ruby on Rails 中使用带有邮件程序的实例变量?

javascript - 在 Wordpress 上使用 Webpack 从网站 js 脚本中拆分 vendor 第三方库 js

javascript - 使用 JavaScript 的 if/else 的innerHTML 在 if 语句之前关闭表格标签