6

Prior to posting this question, I consulted the following threads on this topic:

How to include external CDN link into webpack project

Webpack and external libraries

how to use webpack to load CDN or external vendor javascript lib in js file, not in html file How to include jQuery CDN in Webpack?

Webpack externals documentation

Based on all the above, it appears that in order to load a third-party library via a CDN, the standard method would be to use webpack externals, which produces the following script tag in the index.html file (per Webpack docs).

<script
  src="https://code.jquery.com/jquery-3.1.0.js"
  integrity="sha256-slogkvB1K3VOkzAI8QITxV3VzpOnkeNVsKvtkYLMjfk="
  crossorigin="anonymous">
</script>

While this solution works if you have one or two libraries, how are you supposed to load 10 libraries (for arguments sake) via CDNs asynchronously (to maximise pageload performance) using externals in Webpack?

My current solution to this problem is to manually include the following script tags in my index.html file with relevant "async" and "defer" tags; however, I need to update the index.html file in my dist folder every time I include a new library, which leads me to believe I'm doing this completely wrong. Below is what my index.html file currently looks like, which is also replicated in the dist folder.

<!DOCTYPE html>
<html lang="en">
    <head>
        <title>App</title>
        <link rel="stylesheet" href="https://afeld.github.io/emoji-css/emoji.css">
    </head>

    <body>
        <div id="app"></div>
    </body>

    <script src="https://cdn.jsdelivr.net/npm/moment@2.20.1/moment.min.js" async defer></script>
    <script src="https://cdn.jsdelivr.net/npm/lodash@4.17.4/lodash.min.js" async defer></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/mathjs/4.0.0/math.min.js" async defer></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.min.js" async defer></script>
    <script src="https://widget.cloudinary.com/global/all.js" async defer></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.4.0/Chart.min.js" async defer></script>
    <script src="/dist/build.js" async defer></script>
</html>

While I'm sure there's a "hack-ey" way of achieving my goal (which I'm open to seeing), my question is whether I can accomplish the above through an officially supported method (like through externals). If not, how does most of the web development world use libraries given that CDNs are known to almost always improve pageload performance?

EDIT: For some context, I'm using Webpack because I'm using vue-loader to build my VueJS SPA (as a learning project).

EDIT 2: This question was asked using incorrect assumptions about Webpack and how web development works. The conclusion is that you shouldn't be using CDNs as liberally as I have if you're using Webpack. Refer to the comment section for clarification.

ptk
  • 6,835
  • 14
  • 45
  • 91
  • 1
    Did you try using [html-webpack-plugin](https://webpack.js.org/plugins/html-webpack-plugin/) then add a template with all externals you need? Other than that, the links you provided offer great help. And if you're using cdn so much (if not entirely) why do you need webpack? – sduduzo gumede Mar 31 '18 at 04:28
  • Thanks for the link! I'll look into it to see if it fits what I need. The reason I'm using Webpack is because I'm using vue-loader for my Vue SPA. – ptk Mar 31 '18 at 04:32
  • The real question is still why you would do this, since your bundle is supposed to be stable, not "dependent on whatever some CDN decides to give you". If you have dependencies, install those, pegged to a very specific version, and then bundle those so that your bundle is deterministic instead of "dependent on what the internet decides to give you" (including potentially poisoned source code) – Mike 'Pomax' Kamermans Mar 31 '18 at 04:52
  • @Mike'Pomax'Kamermans I see what you're saying here... and because of the reasons you listed above, I'm guessing most serious projects use libraries by bundling them through webpack instead of using CDNs? – ptk Mar 31 '18 at 04:55
  • More "any normal webpack bundle" rather than "serious project". If you use webpack, don't pull in CDN-served libraries, just npm install their equivalents and make your code require those instead. If you absolute want to rely on CDN code for some of your dependencies, then simply tell webpack which names to treat as ["externals"](https://webpack.js.org/configuration/externals/) and load them on whatever page you're loading your bundle on as all. – Mike 'Pomax' Kamermans Mar 31 '18 at 04:59
  • @Mike'Pomax'Kamermans Thank you so much for this clarification. This is precisely what I needed to know. I was almost certain I was asking the question under false assumptions about Webpack and how people build apps given how underserved this topic was. – ptk Mar 31 '18 at 05:01
  • Do note that having both `async` and `defer` tags is redundant; `defer` requires the script to run after the document has been parsed, `async` means that the script can run before the document has been completely parsed *but doesn't block while downloading*. Instead of both, pretty sure you should just use `defer` – CertainPerformance Mar 31 '18 at 05:14
  • @CertainPerformance you're right, thanks for the heads up – ptk Mar 31 '18 at 05:20

1 Answers1

0

My humble solution is to paste all those script tags on a separate file called “cdn-libraries.php”. After the /body, instead of pasting the long list of scripts, just make one call, put:

///...</body>
<?php require ‘cdn-libraries.php‘ ?>
<!--consider the correct path to your cdn-libraries file.-->

Of course the file must be saved as php, not as html.

limakid
  • 71
  • 11