Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to include a CDN to VueJS CLI without NPM or Webpack?

Tags:

I'm new on VueJS ans Webpack. I've created a project with VueJS CLI and trying to work with it. I need to insert an CDN to my code.

When working with standard HTML, CSS & JS solutions, I'd include CDNs like this:

<!DOCTYPE html>  <html>    <head>      <meta charset="utf-8" />      <title>False Merge</title>        <!-- CDN -->      <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">      <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/v/dt/dt-1.10.16/sl-1.2.5/datatables.min.css"/>        <!-- StyleSheets -->      <link rel="stylesheet" href="public/stylesheets/index.css" />  </head>    <body>          <script src="https://code.jquery.com/jquery-3.3.1.js" integrity="sha256-2Kok7MbOyxpgUVvAk/HJ2jigOSYS2auK4Pfzbm7uH60=" crossorigin="anonymous"></script>      <script type="text/javascript" src="https://cdn.datatables.net/v/dt/dt-1.10.16/sl-1.2.5/datatables.min.js"></script>        <script src="public/javascripts/index.js"></script>    </body>    </html>

As you can see, you can add a CDN script with the HTML script tag, and start using it in the JS.

I'm trying to do the same with VueJS in a component. I've got the template and style sections ready.

Unfortunately, I don't know how to add in a simple way a CDN to use inmediately in the script tag within the Vue component. I tried to do this but it is not working.

<template>    <div class="index">      <div class="container">        <table id="table_dataset" class="display">        </table>      </div>    </div>      </template>    <script type="text/javascript" src="https://cdn.datatables.net/v/dt/dt-1.10.16/sl-1.2.5/datatables.min.js"></script>  <script>    export default {      name: 'Index',      data() {        return {         }      }    }  </script>    <!-- Add "scoped" attribute to limit CSS to this component only -->  <style scoped>  </style>

Is there a way to add a CDN (without Webpack or NPM) to a VueJS component?

like image 899
Fabricio Chacon Avatar asked Mar 16 '18 21:03

Fabricio Chacon


2 Answers

Unfortunately, no, you can't add a <script> tag to a specific component via template.

In your case you have some options:

1: Use NPM

Propertly install the dependency using npm

  • Pros: proper usage of NPM and Webpack; scoped definition;
  • Cons: the script must be available as a NPM package.
  • Note: when available this is the recommended approach.
  • Steps:

    • For your case, you can check in datatables official page they do have a NPM package. I could be used like:

      npm install --save datatables.net-dt 
    • And in your .vue file:

      <script>   require( 'datatables.net-dt' )();   export default {     name: 'Index',     data() {       return {        }     }   } </script> 

2: Add <script> tag to index.html

Locate and a dd the <script> tag to your index.html

  • Pros: the <script> tag is clearly (and declaratively) added to the HTML source. The script will only be loaded once.
  • Cons: the script will be globally loaded.
  • Steps:
    • Just add the <script type="text/javascript" src="https://cdn.datatables.net/v/dt/dt-1.10.16/sl-1.2.5/datatables.min.js"></script> to the end of the index.html file, preferably right before </body>.

3: Create the <script> tag programatically

The other alternative is to create the script tag programatically at the component, when the component is lodaded.

  • Pros: the code stays in the component only. Your external script will be loaded only when the component is loaded.
  • Cons: the script still will be globally available once it is loaded.
  • Steps/Code:

    <script>   export default {     name: 'Index',     data() {       return {        }     },     mounted() {       if (document.getElementById('my-datatable')) return; // was already loaded       var scriptTag = document.createElement("script");       scriptTag.src = "https://cdn.datatables.net/v/dt/dt-1.10.16/sl-1.2.5/datatables.min.js";       scriptTag.id = "my-datatable";       document.getElementsByTagName('head')[0].appendChild(scriptTag);     }   } </script> 
like image 160
acdcjunior Avatar answered Jan 20 '23 14:01

acdcjunior


I don't know if this is still a concern, but you could also give vue-meta a look. I'm using it to create a better SEO implementation, but with it, you can include CSS, and/or JS files for specific components. You can even set the individual files to preload if you wanted. Here's a pretty good write-up. https://alligator.io/vuejs/vue-seo-tips/

In there it says that vue-meta isn't stable, but the article was written in February of 2018, and the version as of today, is 2.2.1.

  1. add this line to your package.json file within the dependencies object: "vue-meta": "^2.2.1",

note - omit the trailing comma if it's to be the last line of the dependencies object

  1. open a terminal and cd to the dir which contains above mentioned package.json file. (BTW, this is all super easy if you use the vue ui).
  2. in the terminal run: npm install

Then add the following to your main.js file.

import Meta from "vue-meta"; Vue.use(Meta); 

Now you can freely load static CSS/JS assets. This works for local, or from cdn. Below is my example. Disregard my imports, components and methods... they aren't related to vue-meta and may differ from yours. I just wanted to show you a working version.

<script> import { page } from "vue-analytics"; import Header from "@/components/Header.vue"; import Footer from "@/components/Footer.vue"; export default {   components: {     Header,     Footer   },   data: function() {     return {};   },   methods: {     track() {       page("/");     }   },   metaInfo: {     link: [       {         rel: "preload",         as: "style",         href: "https://cdn.jsdelivr.net/npm/[email protected]/dist/bootstrap-vue.min.css"       },       {         rel: "preload",         as: "style",         href: "https://fonts.googleapis.com/css?family=Cinzel|Great+Vibes|Montserra"       },       {         rel: "preload",         as: "style",         href: "/content/css/site.css"       },       {         rel: "stylesheet",         href:           "https://fonts.googleapis.com/css?family=Cinzel|Great+Vibes|Montserra"       },       {         rel: "stylesheet",         href: "https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css",         integrity:           "sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T",         crossorigin: 'anonymous"'       },       {         rel: "stylesheet",         href: "https://cdn.jsdelivr.net/npm/[email protected]/dist/bootstrap-vue.min.css",         async: true,         defer: true       },       {         rel: "stylesheet",         href: "https://use.fontawesome.com/releases/v5.8.1/css/all.css",         integrity:           "sha384-50oBUHEmvpQ+1lW4y57PTFmhCaXp0ML5d60M1M7uH2+nqUivzIebhndOJK28anvf",         crossorigin: 'anonymous"',         async: true,         defer: true       },       {         rel: "stylesheet",         href: "/content/css/site.css",         async: true,`enter code here`         defer: true       },       { rel: 'favicon', href: 'favicon.ico' }     ],     script: [{ src: "https://unpkg.com/axios/dist/axios.min.js", async: true, defer: true }],   } }; </script> 
like image 31
N8_ Avatar answered Jan 20 '23 14:01

N8_