Webpack-publicPath

2017-12-27  本文已影响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

    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是以配置文件所在目录为根目录。
上一篇下一篇

猜你喜欢

热点阅读