Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

vite_legacy_javascript_tag execution order inconsistent with vite_javascript_tag #104

Closed
duprasa opened this issue Jul 16, 2021 · 2 comments
Labels
enhancement New feature or request

Comments

@duprasa
Copy link

duprasa commented Jul 16, 2021

Description 📖

When using multiple endpoints on one page with vite_legacy_javascript_tag doesn't preserve execution order. I think this is because under the hood it just runs System.import(document.getElementById('#{ id }') behind the scenes which doesn't guarantee any execution order between vite_legacy_javascript_tag since they are handled async and will just run in completion order.

vite_javascript_tag does however behave as expected this is because <script type="module"> will execute the endpoints in the order that they are defined in the html.

I know that ideally we would only have 1 endpoint per page, but thats not a viable option for us since we have a lot of legacy code 😅

Reproduction 🐞

<head>
  <%= vite_javascript_tag "first_to_run" %>
  <%= vite_legacy_javascript_tag "first_to_run" %>
  <%= vite_javascript_tag "second_to_run" %>
  <%= vite_legacy_javascript_tag "second_to_run" %>
</head>

expected execution order: first_to_run, second_to_run
expected execution order for non-legacy browsers : first_to_run, second_to_run
expected execution order for legacy browsers : first_to_run, second_to_run or second_to_run, first_to_run

Run bin/rake vite:info and provide the output:

bin/vite present?: true
vite_ruby: 1.2.12
vite_rails_legacy: 2.0.12
rails: 4.2.11.1
node: v15.6.0
npm: 7.4.0
yarn: 1.22.4
bin/rake: No such file or directory - pnpm
pnpm: 
ruby: ruby 2.6.5p114 (2019-10-01 revision 67812) [x86_64-linux]

installed packages:
rtings@ /home/sam/Workspace/rtings
├─┬ @vitejs/plugin-legacy@1.4.3
│ └── vite@2.4.2 deduped
├─┬ vite-plugin-ruby@2.0.4
│ └── vite@2.4.2 deduped
├─┬ vite-plugin-vue2@1.7.2
│ └── vite@2.4.2 deduped
└── vite@2.4.2

Appreciation

Other than this issue, this gem has been awesome! It's really gonna help us out! Thanks 😄 👍

@duprasa duprasa added the bug: pending triage Something doesn't seem to be working, but hasn't been verified label Jul 16, 2021
@ElMassimo ElMassimo added enhancement New feature or request and removed bug: pending triage Something doesn't seem to be working, but hasn't been verified labels Jul 16, 2021
@ElMassimo
Copy link
Owner

ElMassimo commented Jul 16, 2021

Hi @duprasa!

As you mentioned, ideally you would only have one legacy entrypoint per page.

In order to control the order, you could change the helper contract from:

def vite_legacy_javascript_tag(name, asset_type: :javascript)

to

def vite_legacy_javascript_tag(*names, asset_type: :javascript)

and chain System.import promises:

import_tag = content_tag(:script, nomodule: true) {
  <<-JS
    var srcs = #{vite_asset_paths.to_json.html_safe}
    var i = 0
    var promise = Promise.resolve()
    do {
      promise = promise.then(System.import(srcs[i]))
    } while (i++ < srcs.length)
  JS
}

This introduces additional complexity to the helper, so I'd like to hear from other users that share this requirement before updating the gem.

Please do try it out by overriding or creating a new helper based on this and let me know how it goes 😃

@ElMassimo
Copy link
Owner

After some investigation, it seems that import order does not guarantee execution order (at least when using the module polyfill).

A way to enforce execution order is to leverage the module system.

For example, in your case, create another entrypoint combined_first_and_second.js:

import '~/entrypoints/first_to_run'
import '~/entrypoints/second_to_run'

and then reference this entrypoint in your pages:

<%= vite_javascript_tag "combined_first_and_second" %>
<%= vite_legacy_javascript_tag "combined_first_and_second" %>

If you are rendering the tags in different views or partials, then there's really no guarantee to the execution order given the async nature of ES modules.

Repository owner locked and limited conversation to collaborators Jul 19, 2021

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants