geektime-webpack-course
geektime-webpack-course copied to clipboard
关于publicPath和contentBase的问题
请教老师一个问题,关于output中的publicPath,还有devServer中的publicPath和contentBase作用总是有点分不清,能否帮忙讲解一下~
发现一个奇怪的现象
dev.config这样配置的时候:
entry: {
index: './src/index.js',
search: './src/search.js'
},
output: {
path: path.join(__dirname, 'dist'),
filename: '[name].js',
publicPath: '/hehe/'
},
mode: 'development',
plugins: [
new webpack.HotModuleReplacementPlugin(),
new HtmlWebpackPlugin({
filename: 'index.html',
template: path.resolve(__dirname, './src/index.html'),
chunks: ['search']
})
],
devServer: {
contentBase: './dist',
hot: true
}
};
如果dist目录下已经有之前build好的文件,那么html结构是这样的:
<body>
<div id="root">
<div class="search-cls">
hello search!<img src="/hehe/a93b9e8555750ddc12adeb4e28fca4ca.jpg">
</div>
</div>
<script src="./search_5901ee35.js" type="text/javascript"></script>
</body>
可以看到search.js并没有前缀/hehe/;
但是如果我把dist目录下之前编译出来的文件删掉,那么html就变成:
<body>
<div id="root">
<div class="search-cls">
hello search!!<img src="/hehe/a93b9e8555750ddc12adeb4e28fca4ca.jpg">
</div>
</div>
<script src="/hehe/search.js"></script>
</body>
看起来就正常 取的是内存中的文件了
请问这是什么原因呢
首先说一下 output中的publicPath。
outpub 里面有一个 path,path 的配置是指定构建出来的静态资源存放的绝对路径,放在磁盘的哪个位置,比如我们通常放到当前的这个项目根目录的 build 或者 dist 下,因此我们会将 path 设置成 path.join(__dirname, 'dist').
在来看一下 publicPath,这个通常是和生产环境的构建相关,mode = development 阶段是不用关注这个值的。以腾讯直播这个业务为例,now.qq.com 首页查看源代码会发现 js 静态资源路径是https://11.url.cn/now//index_51727db.js?_bid=152 。可以看到它有个前缀 11.url.cn/now(这个需要重点关注下)。 假设在生产环境我们不设置这个 publicPath,那么这个 js 的路径会变成 /index_51727db.js?_bid=152,它会直接访问到 now.qq.com 这个域名下,也就是 now.qq.com/index_51727db.js?_bid=152,会走不到 cdn。到这里,我们不难理解 publicPath 的含义,它的作用是给我们的静态资源增加前缀,构建时如果设置了 publicPath,会重写静态资源路径(相当于给静态的访问资源路径增加一个前缀)。
假设我们设置 publicPath 为 11.url.cn/now,比如:
src="img.png" -> 变成 src="11.url.cn/now/img.png"
src="a_xxx.js" -> 变成 src="11.url.cn/now/a_xxx.js"
结论:publicPath 的效果体现在静态资源的uri中,通常开发环境和生产环境设置也不一样,生产环境会根据 CDN 情况进行设置。
嗯嗯 THX~明白了~ 那contentBase是不是在开发环境devServer的情况下也可以不用关注,因为静态资源都在内存中呢
@zhangbocodes contentBase是指当前项目开发环境服务器的托管目录,你可以根据自己的场景需求设置不同的值,不设置的话默认就是当前工作的目录
publicPath & contentBase
-
publicPath === build bundle root path
-
contentBase === dev server root path