Rails 5/6: Как включить функции JS в веб-упаковщик?

Я пытаюсь обновить приложение Rails 3 до Rails 6, и у меня возникают проблемы с теперь используемым по умолчанию веб-пакетом, так как мои функции Javascript недоступны.

Я получил: ReferenceError: Can't find variable: functionName для всех триггеров функции js.

Что я сделал, это:

  • создайте каталог app_directory в /app/javascript
  • скопировал мой файл javascript для разработки в каталог app_directory и переименовал его в index.js
  • добавленной console.log('Hello World from Webpacker'); к index.js
  • добавленной import "app_directory"; в /app/javascript/packs/application.js
  • добавлено в /config/initializers/content_security_policy.rb:

    Rails.application.config.content_security_policy do |policy|
      policy.connect_src :self, :https, "http://localhost:3035", "ws://localhost:3035" if Rails.env.development?
    end
    

Я получаю сообщение "Hello World from Webpacker" на консоли, но при попытке получить доступ к простой функции JS через <div id="x" onclick="functionX()"></div> в браузере я получаю ошибку ссылки.

Я понимаю, что конвейер ресурсов был заменен веб-упаковщиком, который отлично подходит для включения модулей, но как мне включить простые функции JS? Что мне не хватает?

Заранее спасибо?

1 ответ

Решение

Из официального руководства приложения рельсы:

Где вставить свой JavaScript

Независимо от того, используете ли вы конвейер ресурсов Rails или добавляете тег непосредственно в представление, вы должны выбрать, куда поместить любой локальный файл JavaScript.

У нас есть выбор из трех мест для локального файла JavaScript:

Папка app/assets/javascripts, папка lib /assets/javascripts и папка vendor /assets/javascripts

Вот рекомендации по выбору места для ваших скриптов:

Используйте app/assets/javascripts для JavaScript, который вы создаете для своего приложения.

Используйте lib /assets/javascripts для сценариев, которые используются многими приложениями (но используйте драгоценный камень, если можете).

Используйте vendor /assets/javascripts для копий плагинов jQuery и т. Д. От других разработчиков. В простейшем случае, когда все ваши файлы JavaScript находятся в папке app/assets/javascripts, вам больше ничего не нужно делать.

Добавьте файлы JavaScript в любое другое место, и вам нужно будет понять, как изменить файл манифеста.

Больше чтения: http://railsapps.github.io/rails-javascript-include-external.html

Инструкции по переходу от старого конвейера активов к новому способу работы с веб-пакетами вы можете увидеть здесь:

https://www.calleerlandsson.com/replacing-sprockets-with-webpacker-for-javascript-in-rails-5-2/

Это способ перехода от конвейера ресурсов к веб-упаковщику в Rails 5.2, и он дает вам представление о том, как обстоят дела в Rails 6 теперь, когда веб-упаковщик используется по умолчанию для javascript. В частности:

Теперь пришло время переместить весь код JavaScript вашего приложения из app / assets / javascripts / в app / javascript /.

Чтобы включить их в пакет JavaScript, обязательно укажите их в app/javascript/pack/application.js:

require('your_js_file')

Итак, создайте файл в app/javascript/hello.js нравится:

console.log("Hello from hello.js");

Затем в app/javascript/packs/application.js, добавьте эту строку:

require("hello")

(обратите внимание, что расширение не требуется)

Теперь вы можете загрузить страницу с открытой консолью браузера и увидеть "Привет!" сообщение в консоли. Просто добавьте все, что вам нужно в app/javascript каталог, или, что еще лучше, создайте подкаталоги, чтобы сохранить ваш код организованным.

Посмотрим, как webpacker "упаковывает" js-файлы и функции:

/***/ "./app/javascript/dashboard/project.js":
/*! no static exports found */
/***/ (function(module, exports) {

  function myFunction() {...}

Таким образом, webpacker хранит эти функции в другой функции, делая их недоступными. Не уверен, почему это так, или как обойти это правильно.

Хотя есть и обходной путь. Вы можете:

1) изменить сигнатуры функций из:

function myFunction() { ... }

чтобы:

window.myFunction = function() { ... }

2) сохранить сигнатуры функций как есть, но вам все равно нужно добавить ссылку на них, как показано здесь:window.myFunction = myFunction

Это сделает ваши функции глобально доступными из объекта "window".

Замените код в пользовательском файле сценария Javaиз

function function_name() {// body //}

к

window.function_name = function() {// body //}
Другие вопросы по тегам