Javascript функций не работают должным образом - PullRequest
1 голос
/ 29 мая 2020

Я использую Ruby в Rails 6.0.3. Если я сохраню код javascript в app/assets/javascript/packs/file.js, а затем включу его с javascript_pack_tag(), функции в коде не будут работать должным образом.


Например, у меня есть BlogApp с контроллером блога.

app/assets/javascript/packs/file.js

function notifySend(arg) {
    console.log(arg)
}

function notify(arg) {
    notifySend(arg)
}

app/views/layouts/blog.html.erb

<!DOCTYPE html>
<html>
    <head>
        <title><%= @page_title %></title>
        <meta charset="utf-8">

        <%= csrf_meta_tags %>
        <%= csp_meta_tag %>

        <%= javascript_pack_tag 'file', %s(data-turbolinks-track) => 'reload' %>
    </head>

    <body>
        <script>notify('hello!')</script>
    </body>
</html>

При открытии localhost:3000/blogs я получаю :

ReferenceError: notify is not defined

В консоли браузера.


Но если я немного изменю file.js, например:

function notifySend(arg) {
    console.log(arg)
}

notify = function(arg) {
    notifySend(arg)
}

javascript работает нормально, и я получаю "привет!" в консоль браузера!


Итак, есть хлопоты переписать функции.

Но для больших JS файлов или уменьшенных файлов это может занять много времени. Каждую функцию, которая вызывается из тега script в теле, необходимо переписать.

Как сохранить неповрежденный код js (как в примере 1) и заставить его работать с рельсами?

1 Ответ

2 голосов
/ 29 мая 2020

Это связано с тем, что webpacker оборачивает ваш импорт в функции, чтобы они не помещались в глобальную область видимости.

Во втором примере, опуская ключевое слово var, вы создаете неявный глобальный:

function notifySend(arg) {
    console.log(arg)
}

notify = function(arg) {
    notifySend(arg)
}

Это считается действительно плохой практикой, и если вы используете строгий режим или линтер, он бы вам об этом сказал. Если вы действительно хотите объявить глобальный, сделайте это явно:

function notifySend(arg) {
    console.log(arg)
}

window.notify = notifySend;

Но реальное решение здесь состоит в том, чтобы не использовать встроенные теги сценария или встроенные обработчики и написать реальный поддерживаемый minified javascript вместо того, чтобы создавать беспорядок. Javascript не принадлежит вашим взглядам. Если ваш код полагается на кучу глобальных переменных, вы делаете это неправильно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...