Utilize Content Delivery Network Components in Conjunction with a Command Line Interface Build

As we progress in building our Vue applications, we have been using the standard script tag include method for Vue. However, as we transition from jQuery/Knockout-heavy apps to more complex ones, the maintenance issues that may arise if we don't switch to the CLI build sooner rather than later are becoming apparent.

Although not a problem for many of our apps, due to our early adoption of an "internal CDN" approach in our Vue apps, bundling everything in Webpack seems like a step back in terms of versatility. Currently, we serve four files, with each route within our MVC app having its own associated Vue instance (e.g., about.js), controlling the UI and logic. The CDN serves: 1. polyfills.js (for browser compatibility), 2. vendor.js (axios, moment.js, and others), 3. vue.js (vue + vee-validate), and 4. components.js (our custom UI component library).

I'm particularly concerned about #4. Serving this over the CDN has allowed us to instantly push updates to all our apps without running a new build. With the intention of eventually converting all 80+ internal applications, plus existing and new external applications to Vue, updating shared components required by 30 apps means rebuilding and pushing them all, which is far from ideal.

Is there a way to continue using the CDN build solely for our components while bundling the rest as a SPA with Webpack?

Note: This differs from referencing an external JS library like jQuery; I am focusing on adding Vue Components. If you load a library externally and then try to import the component, Vue will throw a console error. Simply adding it won't work either because there's no import, but importing it also fails because it's external to the app.

Answer №1

Yes, it is possible to utilize http-vue-loader for loading .vue components through the HTTP protocol. However, there are certain restrictions associated with its usage, and it is advised against using it in a production environment.

Answer №2

If you want to efficiently manage your applications using a Vue webpack CLI build while still maintaining the freedom of working with independent Vue components, which are served as separate files shared among multiple apps/projects, you might be interested in what can be described as an "internal CDN" architecture.

An insightful suggestion by @RandyCasburn on achieving this goal is to globally expose the Vue object (typically loaded from a CDN via a <script> tag) and then load your individual files that utilize Vue.component to register your components globally.

For further guidance, refer to: How to 'import' Vuejs component into index.html?

However, if your preference is to develop these independent Vue Components as Single File Components (SFC), here are two key solutions for consideration:

  1. Create a small build step tool that converts your SFC into a plain JS file, allowing it to be loaded through a script tag and registered globally using Vue.component.
  2. Rather than generating a JS file that registers with Vue.component, have it expose the Vue Component configuration/options object so it can be locally registered and asynchronously loaded. This approach requires configuring each consumer app's webpack setup to handle loading non-bundled chunks.

Incorporating Vue SFC as a single JS file with Vue.component

A recent template project that facilitates this process is available at: https://github.com/RonnieSan/vue-browser-sfc

The advantage of this method lies in its simplicity - requiring only HTML refactoring to load Vue followed by common components JS files. The components should be globally accessible even during development, eliminating complaints from the Vue runtime about "Unknown custom element". However, all components must be loaded upfront regardless of usage status.

Converting Vue SFC to a single JS file with "async" options object

This alternative presents a more complex yet intriguing solution. By utilizing a build step to convert the SFC .vue file without the need for additional wrapper code with Vue.component declarations, webpack or Rollup can encapsulate the component options object in an IIFE or UMD format that registers the object globally.

To implement this approach successfully, your webpack configuration should be adjusted to facilitate asynchronous loading of components from the network rather than bundling them within the app.

Consider leveraging tools like dynamic-cdn-webpack-plugin along with customized resolver functions to list components in the plugin settings and define their versions/specifications accordingly.

While this method may entail a more intricate webpack setup for consumer apps, it streamlines the async loading process without necessitating modifications to the HTML files. CDN components are fetched on-demand when required, offering potential advantages over traditional loading approaches.

Answer №3

Have you considered configuring multiple entry points in your webpack.config.js? By doing so, you can have one entry point specifically for loading components and another for other files. The sample code snippet below, sourced from the webpack website, illustrates how to achieve this.

{
  entry: {
    app: './src/app.js', //Exports to /dist/app.js
    search: './src/components.js' //Exports to /dist/components.js
  },
  output: {
    filename: '[name].js',  //[name] is replaced with the 
                            //key names in the entry option(app & search) 
    path: __dirname + '/dist'
  }
}

You would then create a file /src/app.js that imports items 1-3, and a /src/components.js that imports your .vue files.

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

When utilizing Vue.js, I aim to eliminate a <td></td> element as the colspan data increases

After playing around with vuejs for a few weeks, I am facing an issue. I want to dynamically remove a td tag every time the colspan value exceeds the default one. For example, if the initial colspan is 3 and it changes to 4, I need to remove one td tag. So ...

Sending data from the server to the client in MVC using C#

I sent a token from a View to a function in my HomeController, and now I need to process the token and send back the information to the frontend. I assumed that the resultData returned by the ajax call would be the output of GetMyData, but it turns out it& ...

What could be causing NVM (for Windows) to malfunction and consistently display error messages every time it is executed?

After attempting to install nvm on my Windows system using https://github.com/coreybutler/nvm-windows, I encountered an error message when running the nvm-setup. Despite reinstalling nvm, resetting the PATH environment variable, and trying to install vers ...

Ways to change the URL post saving a cookie with express?

I have written this code for user login in my Express router: if (password === realpassword) { res.cookie('thecookie', 'somethingliketoken'); res.redirect(302, '/somepages'); } else { res.status(403).end(); } The ...

Simple chart with four sections in DimpleJS (D3)

Recently I decided to give DimpleJS a try for the first time with hopes of creating something like this: However, I seem to have run into some trouble. No matter what I do, nothing appears on the screen. http://jsbin.com/xosehedejo/1/edit window.onloa ...

Remove dynamically created elements from an AngularJS div

Is there a way to remove an item from the criteria list when clicking the delete button? Currently, only the filter is being refreshed and not the tables. Any suggestions on how to resolve this issue? HTML <ul class="list-unstyled"> <l ...

`Get the height of a specific element within a FlatList using the index property in React Native`

I'm currently exploring a workaround for the initialScrollIndex issue in FlatList that is not functioning correctly. I attempted to use getItemLayout to address this, but encountered a new problem - my elements inside the FlatList have varying heights ...

Storing past entries in a local storage using JavaScript

Currently, I am developing a JavaScript program that involves 3 input boxes. The program is designed to display whatever is typed into each input box on the page. To store and re-display previous submissions, I have implemented local storage. However, I en ...

Removing an element in Vue.js

Can someone help me with a Vue.js issue I'm having? I'm working on a quiz and I want to add a button that deletes a question when clicked. Here's what I've tried so far: deleteQuestion(index) { this.questions.splice(index, ...

What is the best way to upgrade to a specific version of a child dependency within a module?

npm version: 7.24.2 Looking for assistance on updating a child dependency. The dependency in question is: vue-tel-input This dependency relies on libphonenumber-js with version ^1.9.6 I am aiming to update libphonenumber-js to version ^1.10.12. I have ...

Ways to confirm non-null values and bypass the row if it is

I have been attempting to compare 2 dates in order to appropriately display data in a table. I have tried the following approach: ${this.dateToCompare.getTime()} > ${row.CreateDate.getTime()} However, there is an issue where CreateDate has a null value ...

Transform an array of objects into a nested tree structure with Javascript

I am currently facing a challenge with handling a complex json file using javascript to structure it hierarchically. My goal is to convert an array of objects into a deeply nested array, where there can be multiple divNames with varying categories and subc ...

Error message encountered: ReferenceError - The subcommand specified in Discord.js Slash Command function is undefined

I have been experimenting with subcommands in a slash command for a discord bot. I plan to have several similar subcommands, so I wanted to create a function that can be called within .addSubCommand, but it seems like it's not functioning correctly. ...

Assign the DatePicker Object to an HTML Element

I am currently using a SyncFusion date picker in my project and the implementation looks like this: var datepicker = null; $("#datepicker").hide(); $("#click").click(function(){ $("#datepicker").show(); datepicker = new ej.calendars.DatePi ...

Guide to rendering a div class conditionally in a Razor page depending on a variable?

How can I dynamically render a div with different classes in Angular based on a condition? <div class="@(myArray.length>0 ? "col-md-8" : "col-md-12" )"> I'm trying to achieve that if the length of myArray is greater than 0, then it should h ...

Managing browser navigation within a web application

I am currently developing a web-based application for internal use in the company I work for. The application is quite intricate, featuring numerous forms that will enable users to both view and input data, which will then be stored in a database upon savi ...

Discover the steps to execute a continuous loop of animations on a singular component using framer-motion

I'm currently working on a website that incorporates framer-motion for animations One key component of the site is an image displayed as follows: <motion.img ref={scope} initial={{ x: -200 }} alt="pa ...

What is the best way to segregate Express routes from server.js?

I've been closely following a Vue SSR guide on GitHub and noticed that the author has organized their Express routes within a file named server.js. For better organization, I prefer to keep my Express routes in a file called router.express.js located ...

Enable JavaScript in Webdriver Selenium to enhance the functionality of your web

I am facing an issue with my Java program and Selenium WebDriver. The script I have does not detect the button "Open device access" because its style is set to "display: none". Usually, clicking on "Device Access" triggers JavaScript to display the "Open ...

Tips for maintaining selected text while a modal window is active

So I'm currently working on a document writer and I'm utilizing document.execCommand to insert links. What I aim for is the ability for a user to select/highlight text, click a button to add a link to that specific text (via a modal), and then ha ...