cdn 指的是通过相互连接的网络系统,使用最靠近用户的服务器将音乐、图片等资源以高效率和低成本的方式将内容传递给用户。

在 webpack 中,我们可能会将引入的第三方资源会编译成单独的文件,作为静态资源放到服务器上,但有些库它本身就有 cdn 链接,通过 cdn 直接加载会使各地资源获取速度更快。

编译成单独文件

在 src/index.js 文件中写一段简单代码,通过 axios 发送 get 请求

import axios from 'axios';
axios.get('https://httpbin.org/get').then((res) => {
  console.log('res', res);
});

在 webpack.config.js 中定义 splitChunks 属性,将公共资源单独编译

module.exports = {
  // 其余配置省略
  optimization: {
    splitChunks: {
      chunks: 'all',
    },
  },
};

执行 npm run build 后,axios 被编译到 559.js 文件中。

559 这个文件名是通过 optimization.chunkIds 定义的,默认属性 deterministic,即根据内容生成的一个不变的短数字

再将编译后的 html 文件在浏览器中打开,获取到了 get 请求的响应数据

引入cdn链接

在这种情况下, 我们是将第三方资源编译成单独的文件,如果通过 cdn 引入的方式呢?

首先在官网上找到 axios 的 cdn 地址。

然后在 public 文件夹的 html 模板文件里引入 cdn 链接。

<body>
<!--   其余配置省略 -->
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</body>

再通过 html-webpack-plugin 编译的时候复制一份到打包后的 dist 文件夹中。

module.exports = {
  // 其余配置省略
  plugins: [
    new HtmlWebpackPlugin({
      title: 'hello webpack',
      template: './public/index.html',
    }),
  ],
};

html-webpack-plugin 不熟悉的可以参考这篇文章

再通过 npm run build 发现,还是将 axios 编译成了单独的文件,并且 index.html 中也引入了 cdn 的链接。

这是因为,我们只告诉了 webpack 要将 cdn 引入 html 页面中,没有告诉它不需要再帮我们打包 axios 的第三方资源。

不打包第三方资源

那通过什么告诉 webpack 不需要打包第三方资源了呢,答案是 externals 属性

module.exports = {
  // 其余配置省略
  externals: {
    axios: 'axios',
  },
};

因为只用到了 axios 这一个库,所以剔除打包后,之前生成包含 axios 的 559.js 文件就不会生成,也不会被引入到 html 页面中,axios也能够正常使用。

区分开发和生产模式

当我们通过 devServer 和 HMR 进行本地开发时,不会在项目里生成文件,而是存储于内存当中,这个时候通过内存获取数据会比从网络中获取 cdn 资源更快。

所以此时可以对引入的 cdn 链接做区分,当生产环境下使用 cdn 链接,本地就通过 node_modules 中的资源编译就好。

只需要在 public 下模板 html 文件引入 cdn 链接的时候做以下判断。

<% if (process.env.NODE_ENV === 'production') { %>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<% } %>

能在 html 页面获取到 NODE_ENV 属性是因为在 webpack.config.js 中我们将 mode 定义为 "production" 后,webpack 会有一些默认操作,其中之一就是使用 DefinePlugin 将 process.env.NODE_ENV 的值设置为 production。

DefinePlugin 不熟悉的可以参考这篇文章

所以此时通过 npm run serve 进行本地开发时,不会加载 cdn 资源。

总结

使用 cdn 链接分为以下几个步骤

  • 去官网 / cdn 网站上找到需要使用库的 cdn 地址
  • 通过 externals 属性排除掉通过 cdn 引入链接的库,不让它再打包
  • 在模板 html 文件中引入 cdn 地址,可通过区分开发和生产环境来判断是否使用 cdn 链接(process.env.NODE_ENV 属性)
  • 使用 html-webpack-plugin 复制模板 html 文件到打包后的 dist 文件中

以上就是 webpack 中 cdn 资源与 externals 属性, 更多有关 webpack 的内容可以参考我其它的博文,持续更新中~

cdn 引入的资源需要通过 externals 排除打包哦~的更多相关文章

  1. https中引入http资源资源所导致的问题

    问题描述 因为公司要求所有生产环境为了安全性需求,全部都走https, 并且在Nginx里面加入了Content-Security-Policy "upgrade-insecure-requ ...

  2. https 页面中引入 http 资源的解决方式

    相对协议 应用场景 浏览器默认是不允许在 https 里面引用 http 资源的,一般都会弹出提示框. 用户确认后才会继续加载,用户体验非常差. 而且如果在一个 https 页面里动态的引入 http ...

  3. springMVC 引入静态资源Js的方式

    前两天项目出现了Js无法引入的情况,本篇博客先总结分析+批判自己犯的低级错,再说说几种访问静态资源的方式! 首先,由于在web.xml里面的servlet拦截匹配为<url-pattern> ...

  4. Spirit带你了解如何安全引入第三方资源

    Spirit带你了解如何安全的引入第三方资源 本文介绍一下如何安全的引入第三方资源 同源策略(SOP) 首先我们来了解一下什么是同源策略,下面的是wiki百科的定义 同源策略是指Web浏览器中,允许某 ...

  5. SpringMVC不能引入静态资源

    SpringMVC不能引入静态资源 问题:部署项目后程序加载或用浏览器访问时出现类似的警告, 2011-01-19 10:52:51,646 WARN [org.springframework.web ...

  6. WPF中引入外部资源

    有时候需要在WPF中引入外部资源,比如图片.音频.视频等,所以这个常见的技能还是需要GET到. 第一步:在VS中创建一个WPF窗口程序 第二步:从外部引入资源,这里以引入图片资源为例 1)新建Reso ...

  7. 关于在vue-cli脚手架中使用CDN引入element-ui不成功的坑

    在前端开发过程中,为了减少最后打包出来的体积,我们会用到cdn引入一些比较大的库来解决. 常见我们引入的element-ui库,在最近使用cdn引入时,无论如何都引入不成功,其他的如Vue.vue-r ...

  8. https http 混合访问_https 页面中引入 http 资源的解决方式

    解决android 5.0 webview不能加载http与https混合内容的问题 在使用WebView加载https资源文件时,如果认证证书不被Android认可,那么会出现无法成功加载对应资源问 ...

  9. html单页面通过cdn引入element-ui组件样式不显示问题

    html单页面通过cdn引入element-ui组件样式不显示问题 必须先引入vue,再通过cdn引入element,否则element-ui组件与样式无效. <!DOCTYPE html> ...

  10. vue-cli3使用cdn引入

    1. index.html引入: <script src="https://cdn.bootcss.com/moment.js/2.20.1/moment.min.js"&g ...

随机推荐

  1. #PowerBi 1分钟学会,powerbi中行列值拼接(COMBINEVALUES与CONCATENATEX)

    在日常的工作中,我们往往需要对表格数据的拼接,用来生成一些复合数据列,如下图类似场景. 其实,在powerbi中,我们同样也可以对表格文本进行拼接.今天我们就介绍两个DAX函数,COMBINEVALU ...

  2. 2023-03-09:用golang调用ffmpeg,将流媒体数据(以RTMP为例)保存成本地文件(以flv为例)。

    2023-03-09:用golang调用ffmpeg,将流媒体数据(以RTMP为例)保存成本地文件(以flv为例). 答案2023-03-09: 这是最简单的收流器.本文记录一个最简单的基于FFmpe ...

  3. 2022-10-22:以下go语言代码输出什么?A:moonfdd1;B:编译错误;C:运行时 panic。 package main import “fmt“ func main() {

    2022-10-22:以下go语言代码输出什么?A:moonfdd1:B:编译错误:C:运行时 panic. package main import "fmt" func main ...

  4. 2022-10-20:以下go语言代码输出什么?A:7;B:7.0;C:0;D:编译错误。 package main import ( “fmt“ ) func main() { const

    2022-10-20:以下go语言代码输出什么?A:7:B:7.0:C:0:D:编译错误. package main import ( "fmt" ) func main() { ...

  5. 2022-05-14:语法补全功能,比如“as soon as possible“, 当我们识别到“as soon as“时, 基本即可判定用户需要键入“possible“。 设计一个统计词频的模型,

    2022-05-14:语法补全功能,比如"as soon as possible", 当我们识别到"as soon as"时, 基本即可判定用户需要键入&quo ...

  6. 2021-08-18:扰乱字符串。使用下面描述的算法可以扰乱字符串 s 得到字符串 t :1.如果字符串的长度为 1 ,算法停止。2.如果字符串的长度 > 1 ,执行下述步骤:在一个随机下标处将字符串

    2021-08-18:扰乱字符串.使用下面描述的算法可以扰乱字符串 s 得到字符串 t :1.如果字符串的长度为 1 ,算法停止.2.如果字符串的长度 > 1 ,执行下述步骤:在一个随机下标处将 ...

  7. 2021-09-27:Pow(x, n)。实现 pow(x, n) ,即计算 x 的 n 次幂函数(即,x**n)。力扣50。

    2021-09-27:Pow(x, n).实现 pow(x, n) ,即计算 x 的 n 次幂函数(即,x**n).力扣50. 福大大 答案2021-09-27: 遍历n的二进制位. 时间复杂度:O( ...

  8. Kubernetes 架构原则和对象设计

    Kubernet¶ Kubernetes 架构原则和对象设计¶ 什么是云计算¶ 云计算平台的分类¶ 以Openstack为典型的虚拟化平台 虚拟机构建和业务代码部署分离. 可变的基础架构使后续维护风险 ...

  9. Springcloud 开始来了解

    为什么要学习springcloud? "微服务 "一词源于Martin Fowler 的名为 Microservices 的博文,简单地说, 微服务是系统架构上的一种设计风格, 它 ...

  10. CentOS 8 已是绝版?还有后续么?

    文章由 Linux爱好者( ID: LinuxHub)整理自开源中国 + 红帽官方.本文章经原作者同意后授权转载. 2020年12月8日,CentOS 项目宣布,CentOS 8 将于 2021 年底 ...