Leverage the power of Webpack to make Vue available globally

Currently, I am dealing with a situation in a legacy Rails application that has undergone some migration to integrate Webpacker and Vue. Additionally, we are utilizing a legacy script loaded through a CDN that also requires Vue. However, instead of bundling Vue into the script, we are aiming to utilize the existing Vue instance within the Rails app.

After referencing this question on Stack Overflow How to expose Vue as global object, I have managed to expose the Vue object at Vue.default using expose-loader. Essentially, the exposed "Vue" object is a Module where the actual Vue object is nested within Vue.default.

My progress has been guided by extensive research on relevant documentation and articles. The following were the most helpful resources:

While my current approach works, I am skeptical about its efficiency. I am now exploring a potentially "more correct" method of exposing Vue directly, without nesting it within the Module default.

My Experiment

To test a new approach, I created a new Rails 6 application from scratch. After adding the necessary JS dependencies using the following commands:

yarn install
yarn add vue
yarn add -D expose-loader
yarn add -D webpack-dev-serer
rails webpacker:install

I went ahead to configure the expose-loader in config/webpack/development.js

environment.loaders.append('expose', {
  test: require.resolve('vue'),
  use: [{
      loader: 'expose-loader',
      options: 'Vue'
  }]
})

Subsequently, I created a basic page and set it as the root route. Then, I created an entry JavaScript file at

app/javascript/packs/application.js

import Vue from 'expose-loader?Vue!vue'
console.log({ pack: Vue })

Within the application layout, under

javascript_pack_tag 'application'
, I included:

<script>
  try {
    console.log({ layout: Vue })
  } catch (error) {
    console.warn('Global Vue not found')
  }
</script>

Upon inspecting the browser console, I observed

{ pack: ƒ Vue(options) }
{ layout: Module
    default: ƒ Vue(options) }

I further experimented with various configurations for the expose-loader in config/webpack/development.js, but the results varied.

  test: require.resolve('vue/dist/vue.esm.js')
// or
  test: require.resolve('vue/dist/vue.esm.js').default
// or
  test: require.resolve('expose-loader?Vue!vue')
// and different permutations of that.

Additionally, I attempted a different approach by directly assigning Vue to the window object from my application.js pack file. Although it functions, it doesn't seem like the optimal solution. Is there a more appropriate method?

The Question

What is the recommended way to expose the Vue object managed by Webpacker so that any non-Webpacker managed script can access it? In other words, how can it be made available on the window object?

Answer №1

After hours of trial and error, I finally found a solution by adding the following configuration rule to webpack

{
  test: require.resolve("vue/dist/vue.esm.js"),
  loader: "expose-loader",
  options: {
    exposes: [{
      globalName: "Vue",
      moduleLocalName: "default",
    }]
  },
},

The moduleLocalName parameter specifically targets the Vue object within the default property and exposes it under the globalName. This allows for easy access to Vue via window.Vue

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

One important rule to remember when using React Hooks is that they must be called consistently and in the correct order in each render of the component. It

Encountering an issue while trying to use the ternary operator to determine which React Hook to utilize. The error message states: "React Hook "useIsolationDynamicPhase" is called conditionally. React Hooks must be invoked in the same order during every co ...

I am finding the event naming conventions in Vue 3 to be quite perplex

In the parent component, there is a child component: <upsetting-moment-step :this-step-number="1" :current-step-number="currentStepNumber" @showNextStep="showNextStep" ></upsetting-moment-step> The par ...

Rearrange elements in an array

Currently, I have an array of sphere meshes and I am looking for a way to position them in a level. The meshes are currently set in a specific position (in the shape of a skeleton), but I would like to move the entire array and place it in a different loca ...

What is the process for choosing every child (regardless of level) of a parent using jQuery?

Is there a way to unbind all elements from a parent node using jQuery? How can I effectively select all children, regardless of their nesting level, from a parent node? I attempted the following: $('#google_translate_element *').unbind('c ...

REGEX: All characters that appear between two specified words

Is it possible to use Regex to select all characters within the designated words "Word1 :" and "Word2 :"? I am looking to extract any character located between these two specific phrases. Word1 : Lorem ipsum dolor sit amet consectetur adipiscing elit ...

What is the best way to manage a multi-select dropdown with checkboxes in Selenium Webdriver?

Below is a snapshot of the drop-down I am working with. In order to handle multiple selections, I currently have code that clicks on the arrow in the drop-down and then selects the corresponding checkbox. However, I would like a more efficient solution fo ...

The CE button on the calculator seems to be malfunctioning

My calculator's CE button isn't working as expected – instead of deleting the last entered number, it clears all numbers. I want the CE button to only delete the last number entered. Additionally, I want the calculator to display a default valu ...

prioritizing the loading of the header in an Angular application before proceeding to load the main content

My website has a basic layout shown below: |-------------------| | HEADER | |___________________| |------||-----------| | side || Main | | bar || Content | | || | |------||------------ For routing and states, I am using ...

How can you correctly make an Ajax request using computed properties sourced from VueX Store?

Is there a way to make an AJAX call where one of the parameters is a computed State in VueX? For instance, if I use this.$axios.get('someUrl/' + accID ), with accID being a computed property from VueX (using MapState), sometimes it returns ' ...

Disregard the views folder when using Express

I've configured a settings file to store important information like the application path and cookie secret for my express app. However, I'm facing an issue where it seems to be disregarding my specified view path directory. config.js: ... expor ...

Change the size of a particular div upon hovering over another element

I'm trying to figure out how to scale my div with text when a user hovers over a button, but I've tried various operators like >, ~, +, - with no success. section { background: #000; color:#fff; height: 1000px; padding: 150px 0; font-family ...

Using jQuery to retrieve the TD value

I'm attempting to retrieve the TD value using the Value attribute.... Let's say I have the following HTML markup: <td nowrap="nowrap" value="FO2180TL" class="colPadding" id="salesOrderNumber1">bla bla </td> So, I tried this- v ...

Blank Screen with Three JS Animation

I'm relatively new to three js and webgl. Currently, I'm working on a complex solar system project and everything seems to be functioning well until I attempt to animate anything. Below is a simplified version showcasing the issue (with a low res ...

Share an image using a subdomain in Express.js

Suppose I have the following code for testing on a local environment. sendImage: async function(req, res) { console.log(req.hostname); var filepath = path.join(__dirname, '../../img/uploads/' + req.params.year + '/' + req.para ...

Struggling to access subroutes of a Vue app without any success

Having some issues with accessing subroutes of my Vue app directly in production when hosted on Heroku. While I can navigate to www.example.com and access subroutes from the index page, typing www.example.com/subpage directly results in errors. For additi ...

Developing a notification system using a combination of ajax, jquery, and Iframe

I am in the process of setting up a messaging system on my website. Currently, I have a table with three columns - two integer fields (from and to) and a timestamp for the date of sending. On one section of the page, I want to display a list of messages ...

Prevent the ability to drag and drop within specific div elements

Having trouble disabling the sortable function when the ui ID is set to "comp". Can't figure out what's going wrong, hoping for some assistance here. $(".sort").sortable({ // start sortable connectWith: ".sort", receive: function ...

Retrieve information from a MongoDB document based on the specific month

If I have a user document with a createdAt field, how can I retrieve data by month in the condition? The format of the createdAt value is as follows: 2016-10-08T16:21:40.935Z Account.find({'what should be passed here?'}, function(err,response){ ...

How can we show a div element when hovering over another element using css-in-js?

Is there a way to use material ui withStyles component in order to show information only on hover for a specific div? ...

What are the steps to ensure my MERN application refreshes properly when deployed on Heroku?

After successfully deploying my MERN app to Heroku, I encountered an issue where pages would come up blank when refreshed. Despite being able to navigate between pages using the nav bar without any errors, a page refresh renders them empty. This troublin ...