webpack4系列教程,如何修改publicPath使用cdn资源?
发布于 作者:苏南大叔 来源:程序如此灵动~
基于webpack的前端项目发展到后期,就是要各种折腾了。这么,折腾的新需求来了,就是静态资源都放到cdn上面。更变态的需求是:根据文件的不同类型,放到不同的cdn上面。好吧,要继续修改项目的webpack配置文件了。

本文测试环境:win10、node@14.2.0、npm@6.14.4、webpack@4.43.0。主要内容就是:各种花样设置publicPath。
情况一:单独的资源服务器cdn修改
因为静态资源涉及到了图片、视频、字体、css、js等。一般来说,就设置一个cdn就够了。把上述这些文件按着目录结构放到cdn上面就可以了。
这种情况下,就修改output的publicPath即可。例如:
module.exports = {
mode: 'production', // 环境
entry: {
//...
},
output: {
//...
publicPath: "//cdn/", //重点
},
module: {
rules: [
{
test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
//...
},
{
test: /\.(eot|woff|woff2?|ttf|svg)$/,
//...
},
{
test: /\.(css|scss|less)$/,
use: [{ loader: MiniCssExtractPlugin.loader,
options: {
publicPath: '../',
},
},
//...
],
},
{
test: /\.(png|jpg|gif|jpeg|svg)$/,
//...
},
]
}
}
对于图片、视频、字体等,保持相对路径不变。css中的publicPath是用来控制,css内部的图片及字体引用地址的。内部图片及字体的相对路径,可以定义在name里面,也可以单独定义name和outputPath。css相关路径,都是相对路径。对于
html里面的图片及视频地址,因为是使用require来处理的,其处理机制和css中的图片不一样。最终将会加载output.publicPath,就是说cdn静态资源地址。
最终的效果来看的话:html里面的资源全部加载了cdn地址,而css内部,还是使用相对地址。


情况二:不同资源使用不同的cdn
在情况一中,就涉及到一个cdn服务器地址,那么,如果需求比较变态,图片、视频、字体、css+js,都要放置到不同的cdn服务器上面呢?
继续看一下苏南大叔的webpack配置,在这种情况下,所有的地址都不是相对地址了,都是带cdn地址的绝对地址。配置如下:
module.exports = {
mode: 'production', // 环境
entry: {
//...
},
output: {
//...
publicPath: "//cdn/", //重点
},
module: {
rules: [
{
test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
loader: 'url-loader',
query: {
limit: 1024000, //1000kb
name: 'video/[name].[ext]',
publicPath: "//video.cdn/",
esModule: false
}
},
{
test: /\.(eot|woff|woff2?|ttf|svg)$/,
use: [{
loader: "url-loader",
options: {
name: "fonts/[name]-[hash:5].[ext]",
// outputPath: "fonts/",
publicPath: "//font.cdn/",
//...
}
}]
},
{
test: /\.(css|scss|less)$/,
use: [{ loader: MiniCssExtractPlugin.loader,
options: {
//publicPath: '../',
},
},
//...
],
},
{
test: /\.(png|jpg|gif|jpeg|svg)$/,
use: [{
loader: "url-loader",
options: {
name: "[name].[contenthash:5].[ext]",
outputPath: "img",
publicPath: "//img.cdn/",
esModule: false
}
}]
},
]
}
}
- 这里需要注意的是:
css的MiniCssExtractPlugin的publicPath,不是给自己使用的,而是给css中的图片及字体使用的。而这两者又单独设置了,所以css相关的MiniCssExtractPlugin的publicPath注释掉,然后在图片、视频、字体中,单独设置url-loader的publicPath。

特殊说明:url-loader中的outputPath
另外,对于url-loader中的outputPath,单独配置或者写在name里面,对于真实的目录结构来说,效果是一样的。但是在生成这个cdn路径上来说,效果是有区别的。最终的访问路径都是:publicPath+name。跟outputPath没有关系,所以,请注意路径配置。
例如,下面的这个配置,生成的路径是://img.cdn/[name].[contenthash:5].[ext]。
name: "[name].[contenthash:5].[ext]",
outputPath: "img",
publicPath: "//img.cdn/",下面的这个配置,生成的路径是://font.cdn/fonts/[name]-[hash:5].[ext]。
name: "fonts/[name]-[hash:5].[ext]",
publicPath: "//font.cdn/",
需要额外提示的是:使用cdn之后,本地调试就会发生一系列的困难了。所以,请妥善处理cdn域名的解析和部署问题。
相关链接:
- https://newsn.net/say/webpack-start.html
- https://newsn.net/say/webpack-css.html
- https://newsn.net/say/webpack-font.html
- https://newsn.net/say/webpack-html-loader-ok.html
- https://newsn.net/say/webpack-video.html
总结
本文中,总结了设置cdn地址的几种情况,在情况二中,css和js的publicPath地址,其实是没有分开。如何解决这个问题,将在后续文章中讲述。更多webpack经验文字,请点击苏南大叔的博客: