webpack中的path、publicPath、contentBase的区分


output.publicPath & devServer.publicPath

  • output里面的publicPath表示的是打包生成的index.html文件里面引用资源的前缀;javascript

  • devServer里面的publicPath表示的是打包生成的静态文件所在的位置(如果devServer里面的publicPath没有设置,则会认为是output里面设置的publicPath的值);css

两个publicPath能够看做是devServer对生成目录dist设置的虚拟目录,devServer首先从devServer.publicPath中取值,若是它没有设置,就取output.publicPath的值做为虚拟目录,若是它也没有设置,就取默认值 "/"。html

output.publicPath,不只能够影响虚拟目录的取值,也影响利用html-webpack-plugin插件生成的index.html中引用的js、css、img等资源的引用路径。会自动在资源路径前面追加设置的output.publicPath。前端

示例

基本目录

在这里插入图片描述

配置

var path = require("path");
var HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
    entry: {
        app'./src/app.js'
    },
    output: {
        path: path.join(__dirname, "dist"),
        filename"[name].js",
        libraryTarget"umd",
        publicPath'/asset/'
    },
    resolve: {
        extensions: ['.js''.vue''.json']
    },
    externals: {
        tools"tools"
    },
    module: {
        rules: [
            {
                test/\.vue$/,
                loader'vue-loader',

            }
        ]
    },
    plugins: [
        new HtmlWebpackPlugin({
            title'hello world',
            template'./src/index.html',
            filename'index.html'
        })
    ],
    devServer: {
        host'test.m.iqiyi.com',
        port'9393'
    }
};

经过访问 http://test.m.iqiyi.com:9393/, 咱们发现没法访问到页面,只是显示出了目录
vue

在这里插入图片描述

若是咱们访问http://test.m.iqiyi.com:9393/asset/, 能够正常访问到页面
java

在这里插入图片描述

经过上面两个图片的对比,能得出output.publicPath影响着devServer的虚拟目录的设置。同时内部引用的js路径也被修改成output.publicPathnode

若是咱们修改配置:webpack

devServer {
    publicPath"test"
}

访问 http://test.m.iqiyi.com:9393/test/, 以下图所示:
web

在这里插入图片描述

咱们会发现,虚拟目录优先取devServer中的publicPath,index.html中的js路径仍然取的output.publicPath,可是因为二者值不同,因此server找不到 /asset/的虚拟目录。json

contentBase

devServer里面的contentBase表示的是告诉服务器从哪里提供内容。(也就是服务器启动的根目录,默认为当前执行目录,通常不须要设置)

path

output里面的path表示的是output目录对应的一个绝对路径

html-webpack-plugin

这个插件用于将css和js添加到html模版中,其中template和filename会受到路径的影响,从源码中能够看出
template做用:用于定义模版文件的路径
源码:

this.options.template = this.getFullTemplatePath(this.options.template, compiler.context);

复制代码所以template只有定义在webpack的context下才会被识别,webpack context的默认值为process.cwd(),既运行 node 命令时所在的文件夹的绝对路径

filename做用:输出的HTML文件名,默认为index.html,能够直接配置带有子目录
源码:

this.options.filename = path.relative(compiler.options.output.path, filename);

复制代码因此filename的路径是相对于output.path的,而在webpack-dev-server中,则是相对于webpack-dev-server配置的publicPath。

若是webpack-dev-server的publicPath和output.publicPath不一致,在使用html-webpack-plugin可能会致使引用静态资源失败,由于在devServer中仍然以output.publicPath引用静态资源,和webpack-dev-server的提供的资源访问路径不一致,从而没法正常访问。

有一种状况除外,就是output.publicPath是相对路径,这时候能够访问本地资源

因此通常状况下都要保证devServer中的publicPath与output.publicPath保持一致。

参考文章:
https://juejin.im/post/5bb085dd6fb9a05cd24da5cf
https://juejin.im/post/5ae9ae5e518825672f19b094

推荐阅读

  1. 【第22题】理解 JS 模块化

  2. 【深刻vue】为何Vue3.0再也不使用defineProperty实现数据监听?

  3. 抛弃jenkins,如何用node从零搭建自动化部署管理平台

  4. 前端部署演化史

  5. 深刻理解 ES6 Iterator

  6. 解读HTTP/2与HTTP/3 的新特性(推荐)

关注我

扫一扫 关注个人公众号【前端名狮】,更多精彩内容陪伴你!

本文分享自微信公众号 - 壹前端(yiqianduan)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。

相关文章
相关标签/搜索