geektime-webpack-course icon indicating copy to clipboard operation
geektime-webpack-course copied to clipboard

关于publicPath和contentBase的问题

Open zhangbocodes opened this issue 5 years ago • 5 comments

请教老师一个问题,关于output中的publicPath,还有devServer中的publicPath和contentBase作用总是有点分不清,能否帮忙讲解一下~

zhangbocodes avatar Nov 21 '19 16:11 zhangbocodes

发现一个奇怪的现象

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>

看起来就正常 取的是内存中的文件了

请问这是什么原因呢

zhangbocodes avatar Nov 21 '19 16:11 zhangbocodes

首先说一下 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 情况进行设置。

cpselvis avatar Nov 22 '19 00:11 cpselvis

嗯嗯 THX~明白了~ 那contentBase是不是在开发环境devServer的情况下也可以不用关注,因为静态资源都在内存中呢

zhangbocodes avatar Nov 22 '19 07:11 zhangbocodes

@zhangbocodes contentBase是指当前项目开发环境服务器的托管目录,你可以根据自己的场景需求设置不同的值,不设置的话默认就是当前工作的目录

konglingwen94 avatar Apr 15 '20 10:04 konglingwen94

publicPath & contentBase

  1. publicPath === build bundle root path

  2. contentBase === dev server root path

xgqfrms avatar Aug 12 '20 05:08 xgqfrms