美文网首页
Webpack-publicPath

Webpack-publicPath

作者: 九丘建木 | 来源:发表于2017-12-27 16:06 被阅读2571次
    你真的知道publicPath的用处吗?无论是官方文档,还是水友的解释都很难让豁然开朗,比如:

    对于按需加载(on-demand-load)或加载外部资源(external resources)(如图片、文件等)来说,output.publicPath 是很重要的选项。如果指定了一个错误的值,则在加载这些资源时会收到 404 错误。
    此选项指定在浏览器中所引用的「此输出目录对应的公开 URL」。相对 URL(relative URL) 会被相对于 HTML 页面(或 <base> 标签)解析。相对于服务的 URL(Server-relative URL),相对于协议的 URL(protocol-relative URL) 或绝对 URL(absolute URL) 也可是可能用到的,或者有时必须用到,例如:当将资源托管到 CDN 时。

    实验是检验用法的最好途径,于是设置目录结构如下:
    src
    |---index.html
    |---index.js
    |---asssets
        |----1.jpg

    • index.html使用<script src="./dist/bundle.js"/>的方式引入打包后的脚本。
    • index.js使用require('./assets/1.jpg')的方式引入了图片
    • webpack.config.js的配置如下:
        entry:"./index.js",
        output:{
            filename:"bundle.js",
            path:path.resolve(__dirname,"dist"),
        },
        devServer:{
        },
    

    目的是将脚本打包到一个统一的dist文件夹下。

    使用webpack-dev-server重新打包并打开index.html时,报错如下:

    http://localhost:8080/dist/bundle.js net::ERR_ABORTED
    

    为什么找不到呢?

    1. webpack-dev-server使用的是内存中的打包文件,并不是webpack命令打包后的路径。(上面我没有使用webpack命令打包哦。)
    2. webpack-dev-server在不设置publicPath的情况下,将默认输出bundle.js到根目录。不信,你输入localhost:8080/bundle.js就能看到这个Js。
    3. 报错是因为,输出的bundle.js在根目录,而html却要去加载dist目录下的,所以找不到(上文:index.html使用<script src="./dist/bundle.js"/>的方式引入打包后的脚本)。

    这时你需要在devServer中添加publicPath属性:

    publicPath: "/dist/"

    重新使用webpack-dev-server打包,并打开index.html你会发现,找到了bundle.js。但是仍旧提示找不到图片

    http://localhost:8080/c3bbc15b8d6be7ec744c8a32670d7f6c.png 404 (Not Found)
    

    所以,此时devServer.pulicPath属性的含义可以这么理解:

    1. 将你的打包文件输出到哪个路径下,该路径是在内存里(你看不到但存在),相对于加载bundle.js的index.html页面或web服务根目录的哪个路径下。(本示例就相对web服务根目录,因为是以"/"开头)
    2. 此时webpack.config.js中,output.path是可以删除的。因为这个路径是输出到硬盘上的物理路径。与webpack-dev-server完全无关。

    可为什么找不到图片呢?先回味一下官方原文

    对于按需加载(on-demand-load)或加载外部资源(external resources)(如图片、文件等)来说,output.publicPath 是很重要的选项。如果指定了一个错误的值,则在加载这些资源时会收到 404 错误。

    也就是说:如果你require了一些资源或直接引用了网络上的资源,这些资源里包含uri属性(如css中设置img:url('./1.jpg')),就要使用就这个属性,否则会找不到文件。(如果没有使用uri资源,那么这个属性没什么用)。
    说人话---这个属性就是让webpack在打包时才能根据配置动态修改uri中的相对值的;你不配置,webpack打包后的bundle.js中引用的url不对。

    于是再去配置output下的publicPath,将其修改为

        output:{
            filename:"bundle.js",
            path:path.resolve(__dirname,"dist"),
            publicPath: "/dist/"
        },
    

    重新执行webpack-dev-server,打开index.html发现一切正常!

    后来尝试,不配置webserver.publicPath,而只配置output中的publicPath且修改为:

    publicPath: "/dist/"
    

    重新执行webpack-dev-server,打开index.html发现一切正常!
    难道我对webserver.publicPath的理解有错?
    比较了加与不加时,控制台打印出的日志才明白:

    1. 当你不配置devServer下的publicPath时,其会默认将包打到output.publicPath的路径下。
    2. 当你配置了devServer下的publicPath时,才其会将包打开你指定的路径下。

    个人理解:

    1. output.path:硬盘上的路径,也就是你打算把文件打包到你的哪个目录,也就是各个牛人说的绝对路径!与发布时的路径完全无关。
    2. output.publicPath:主要用来转换url中的相对路径的。如果你引用到包含url的资源,一定要配置output.publicPath。配置了此项,webpack在打包时才能根据配置动态修改uri中的相对值。
    3. devserver.publicPath:可以理解为服务或模块的发布路径!注意:该值后面都要有"/"!本示例的index.html用了dist目录下的bundle.js,所以我们需要将模块发布到dist目录下就正确了。
      4.output.path对应的是硬盘上路径,output.publicPath对应的是你这打好的包将来放在web服务器上后,使用www.xxx.xx/xxx/xx形式访问时对应的url.本示例中因为我引用的是域名下/dist目录中的js。所以其对应的publicPath就应该为/dist/
    4. 如果你使用webstorm,千万不要在webpack打包后,使用其自带的端口为63342的默认web服务器打开index.html。这个默认的web服务器会以你的工程目录为根目录,而不像webpack-dev-server是以配置文件所在目录为根目录。

    相关文章

      网友评论

          本文标题:Webpack-publicPath

          本文链接:https://www.haomeiwen.com/subject/aioygxtx.html