Webpack中publicPath详解
最近自己在搭建一个基于webpack的react项目,遇到关于
output.publicPath
和webpack-dev-server中publicPath
的问题,而官方文档对它们的描述也不是很清楚,所以自己研究了下并写下本文记录。
output
output选项指定webpack输出的位置,其中比较重要的也是经常用到的有path
和publicPath
output.path
- 默认值:
process.cwd()
output.path
只是指示输出的目录,对应一个绝对路径,例如在项目中通常会做如下配置:
|
|
output.publicPath
- 默认值:空字符串
webpack 提供一个非常有用的配置,该配置能帮助你为项目中的所有资源指定一个基础路径,它被称为公共路径(publicPath)。
而关于如何应用该路径并没有说清楚…
其实这里说的所有资源的基础路径是指项目中引用css,js,img等资源时候的一个基础路径,这个基础路径要配合具体资源中指定的路径使用,所以其实打包后资源的访问路径可以用如下公式表示:
|
|
例如
|
|
这个最终静态资源访问路径在使用html-webpack-plugin打包后得到的html中可以看到。所以publicPath
设置成相对路径后,相对路径是相对于build之后的index.html的,例如,如果设置publicPath: './dist/'
,则打包后js的引用路径为./dist/main.js
,但是这里有一个问题,相对路径在访问本地时可以,但是如果将静态资源托管到CDN上则访问路径显然不能使用相对路径,但是如果将publicPath
设置成/
,则打包后访问路径为localhost:8080/dist/main.js
,本地无法访问
所以这里需要在上线时候手动更改publicPath
,感觉不是很方便,但是不知道该如何解决…
一般情况下publicPath应该以’/‘结尾,而其他loader或插件的配置不要以’/‘开头
webpack-dev-server中的publicPath
点击查看官方文档中关于devServer.publicPath的介绍
在开发阶段,我们借用devServer启动一个开发服务器进行开发,这里也会配置一个publicPath
,这里的publicPath
路径下的打包文件可以在浏览器中访问。而静态资源仍然使用output.publicPath
。
webpack-dev-server打包的内容是放在内存中的,这些打包后的资源对外的的根目录就是publicPath
,换句话说,这里我们设置的是打包后资源存放的位置
例如:
|
|
以上可以直接通过http://lcoalhost:8080/dist/main.js
访问到。
通过访问 http://localhost:8080/webpack-dev-server
可以得到devServer启动后的资源访问路径,如图所示,点击静态资源可以看到静态资源的访问路径为 http://localhost:8080${publicPath}index.html
html-webpack-plugin
这个插件用于将css和js添加到html模版中,其中template
和filename
会受到路径的影响,从源码中可以看出
template
作用:用于定义模版文件的路径
源码:
|
|
因此template
只有定义在webpack的context
下才会被识别,webpack context的默认值为process.cwd()
,既运行 node 命令时所在的文件夹的绝对路径
filename
作用:输出的HTML文件名,默认为index.html,可以直接配置带有子目录
源码:
|
|
所以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
保持一致。
最后
关于webpack中的path
就总结这么多,在研究关于webpack路径的过程中看查到的一些关于路径的零碎的知识如下:
斜杠/
的含义
配置中/
代表url根路径,例如http://localhost:8080/dist/js/test.js
中的http://localhost:8080/
devServer.publicPath & devServer.contentBase
- devServer.contentBase 告诉服务器从哪里提供内容。只有在你想要提供静态文件时才需要。
- devServer.publicPath 将用于确定应该从哪里提供 bundle,并且此选项优先。
node中的路径
__dirname
: 总是返回被执行的 js 所在文件夹的绝对路径__filename
: 总是返回被执行的 js 的绝对路径process.cwd()
: 总是返回运行 node 命令时所在的文件夹的绝对路径