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 //}