cdn网站

国际上是unpkg、jsdelivr、cdnjs,国内是bootcdn

  1. https://cdn.jsdelivr.net

部署cdn需要html-webpack-plugin 的配合,和 externals属性的刨除将cdn的文件排除在打包文件之外

新建

dependencies-cdn.js

  1. module.exports = [
  2. { name: 'vue', library: 'Vue', js: 'https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.min.js', css: '' },
  3. { name: 'vue-i18n', library: 'VueI18n', js: 'https://cdn.jsdelivr.net/npm/vue-i18n@8.15.1/dist/vue-i18n.min.js', css: '' },
  4. { name: 'vue-router', library: 'VueRouter', js: 'https://cdn.jsdelivr.net/npm/vue-router@3.1.3/dist/vue-router.min.js', css: '' },
  5. { name: 'vuex', library: 'Vuex', js: 'https://cdn.jsdelivr.net/npm/vuex@3.1.2/dist/vuex.min.js', css: '' },
  6. { name: 'axios', library: 'axios', js: 'https://cdn.jsdelivr.net/npm/axios@0.19.0/dist/axios.min.js', css: '' },
  7. { name: 'better-scroll', library: 'BScroll', js: 'https://cdn.jsdelivr.net/npm/better-scroll@1.15.2/dist/bscroll.min.js', css: '' },
  8. { name: 'axios-mock-adapter', library: 'AxiosMockAdapter', js: 'https://cdn.jsdelivr.net/npm/axios-mock-adapter@1.18.1/dist/axios-mock-adapter.min.js', css: '' },
  9. { name: 'element-ui', library: 'ELEMENT', js: 'https://cdn.jsdelivr.net/npm/element-ui@2.13.1/lib/index.js', css: 'https://cdn.jsdelivr.net/npm/element-ui@2.13.0/lib/theme-chalk/index.css' },
  10. { name: 'lodash', library: '_', js: 'https://cdn.jsdelivr.net/npm/lodash@4.17.15/lodash.min.js', css: '' },
  11. { name: 'ua-parser-js', library: 'UAParser', js: 'https://cdn.jsdelivr.net/npm/ua-parser-js@0.7.20/dist/ua-parser.min.js', css: '' },
  12. { name: 'js-cookie', library: 'Cookies', js: 'https://cdn.jsdelivr.net/npm/js-cookie@2.2.1/src/js.cookie.min.js', css: '' },
  13. { name: 'nprogress', library: 'NProgress', js: 'https://cdn.jsdelivr.net/npm/nprogress@0.2.0/nprogress.min.js', css: 'https://cdn.jsdelivr.net/npm/nprogress@0.2.0/nprogress.css' },
  14. { name: 'dayjs', library: 'dayjs', js: 'https://cdn.jsdelivr.net/npm/dayjs@1.8.17/dayjs.min.js', css: '' },
  15. { name: 'fuse.js', library: 'Fuse', js: 'https://cdn.jsdelivr.net/npm/fuse.js@5.2.3/dist/fuse.min.js', css: '' },
  16. { name: 'hotkeys-js', library: 'hotkeys', js: 'https://cdn.jsdelivr.net/npm/hotkeys-js@3.7.3/dist/hotkeys.min.js', css: '' },
  17. { name: 'qs', library: 'Qs', js: 'https://cdn.jsdelivr.net/npm/qs@6.9.1/dist/qs.js', css: '' },
  18. { name: 'lowdb', library: 'low', js: 'https://cdn.jsdelivr.net/npm/lowdb@1.0.0/dist/low.min.js', css: '' },
  19. { name: 'lowdb/adapters/LocalStorage', library: 'LocalStorage', js: 'https://cdn.jsdelivr.net/npm/lowdb@1.0.0/dist/LocalStorage.min.js', css: '' },
  20. { name: 'screenfull', library: 'screenfull', js: 'https://cdn.jsdelivr.net/npm/screenfull@5.0.2/dist/screenfull.min.js', css: '' },
  21. { name: 'sortablejs', library: 'Sortable', js: 'https://cdn.jsdelivr.net/npm/sortablejs@1.10.1/Sortable.min.js', css: '' }
  22. ]

webpack-config.js

  1. const cdnDependencies = require("./dependencies-cdn");
  2. const cdn = {
  3. css: cdnDependencies.map((e) => e.css).filter((e) => e),
  4. js: cdnDependencies.map((e) => e.js).filter((e) => e),
  5. };
  6. modules.exports = {
  7. externals: cdnDependencies.reduce((acc, pkg) => {
  8. acc[pkg.name] = pkg.library;
  9. return acc;
  10. }, {}),
  11. new HtmlWebpackPlugin({
  12. template: path.resolve(__dirname, 'public/index.html'),
  13. title: 'devServe测试',
  14. cdn,
  15. }),
  16. }

index.html

  1. <!--
  2. * @Description:
  3. * @Author: wsy
  4. * @Date: 2021-12-04 16:16:27
  5. * @LastEditTime: 2021-12-04 16:48:17
  6. * @LastEditors: wsy
  7. -->
  8. <!DOCTYPE html>
  9. <html lang="en">
  10. <head>
  11. <meta charset="UTF-8">
  12. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  13. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  14. <% for (var i in htmlWebpackPlugin.options.cdn&&htmlWebpackPlugin.options.cdn.css) { %>
  15. <link href="<%= htmlWebpackPlugin.options.cdn.css[i] %>" rel="preload" as="style">
  16. <link href="<%= htmlWebpackPlugin.options.cdn.css[i] %>" rel="stylesheet">
  17. <% } %>
  18. <!-- 使用 CDN 加速的 JS 文件,配置在 vue.config.js -->
  19. <% for (var i in htmlWebpackPlugin.options.cdn&&htmlWebpackPlugin.options.cdn.js) { %>
  20. <link href="<%= htmlWebpackPlugin.options.cdn.js[i] %>" rel="preload" as="script">
  21. <% } %>
  22. <title>
  23. <%= htmlWebpackPlugin.options.title %>
  24. </title>
  25. </head>
  26. <body>
  27. <!-- 使用 CDN 加速的 JS 文件,配置在 vue.config.js -->
  28. <% for (var i in htmlWebpackPlugin.options.cdn&&htmlWebpackPlugin.options.cdn.js) { %>
  29. <script src="<%= htmlWebpackPlugin.options.cdn.js[i] %>"></script>
  30. <% } %>
  31. </body>
  32. </html>

在html内你会看到

  1. <link rel="stylesheet" href="styles/main.css">
  2. <link href="<%= htmlWebpackPlugin.options.cdn.js[i] %>" rel="preload" as="script">

rel=’preload’

元素的 rel 属性的属性值preload能够让你在你的HTML页面中 元素内部书写一些声明式的资源获取请求,可以指明哪些资源是在页面加载完成后即刻需要的。对于这种即刻需要的资源,你可能希望在页面加载的生命周期的早期阶段就开始获取,在浏览器的主渲染机制介入前就进行预加载。这一机制使得资源可以更早的得到加载并可用,且更不易阻塞页面的初步渲染,进而提升性能。

  1. <!-- 使用 link 标签静态标记需要预加载的资源 -->
  2. <link rel="preload" href="/path/to/style.css" as="style" />
  3. <!-- 或使用脚本动态创建一个 link 标签后插入到 head 头部 -->
  4. <script>
  5. const link = document.createElement("link");
  6. link.rel = "preload";
  7. link.as = "style";
  8. link.href = "/path/to/style.css";
  9. document.head.appendChild(link);
  10. </script>