Webpack中publicPath详解

最近本身在搭建一个基于webpack的react项目,遇到关于output.publicPath和webpack-dev-server中publicPath的问题,而官方文档对它们的描述也不是很清楚,因此本身研究了下并写下本文记录。javascript

output

output选项指定webpack输出的位置,其中比较重要的也是常常用到的有pathpublicPathcss

output.path

  • 默认值:process.cwd()

output.path只是指示输出的目录,对应一个绝对路径,例如在项目中一般会作以下配置:html

output: {
	path: path.resolve(__dirname, '../dist'),
}
复制代码

output.publicPath

  • 默认值:空字符串

官方文档中对publicPath的解释java

webpack 提供一个很是有用的配置,该配置能帮助你为项目中的全部资源指定一个基础路径,它被称为公共路径(publicPath)。node

而关于如何应用该路径并无说清楚...react

其实这里说的全部资源的基础路径是指项目中引用css,js,img等资源时候的一个基础路径,这个基础路径要配合具体资源中指定的路径使用,因此其实打包后资源的访问路径能够用以下公式表示:webpack

静态资源最终访问路径 = output.publicPath + 资源loader或插件等配置路径
复制代码

例如git

output.publicPath = '/dist/'

// image
options: {
 	name: 'img/[name].[ext]?[hash]'
}

// 最终图片的访问路径为
output.publicPath + 'img/[name].[ext]?[hash]' = '/dist/img/[name].[ext]?[hash]'

// js output.filename
output: {
	filename: '[name].js'
}
// 最终js的访问路径为
output.publicPath + '[name].js' = '/dist/[name].js'

// extract-text-webpack-plugin css
new ExtractTextPlugin({
	filename: 'style.[chunkhash].css'
})
// 最终css的访问路径为
output.publicPath + 'style.[chunkhash].css' = '/dist/style.[chunkhash].css'
复制代码

这个最终静态资源访问路径在使用html-webpack-plugin打包后获得的html中能够看到。因此publicPath设置成相对路径后,相对路径是相对于build以后的index.html的,例如,若是设置publicPath: './dist/',则打包后js的引用路径为./dist/main.js,可是这里有一个问题,相对路径在访问本地时能够,可是若是将静态资源托管到CDN上则访问路径显然不能使用相对路径,可是若是将publicPath设置成/,则打包后访问路径为localhost:8080/dist/main.js,本地没法访问github

因此这里须要在上线时候手动更改publicPath,感受不是很方便,可是不知道该如何解决...web

通常状况下publicPath应该以'/'结尾,而其余loader或插件的配置不要以'/'开头

webpack-dev-server中的publicPath

点击查看官方文档中关于devServer.publicPath的介绍

在开发阶段,咱们借用devServer启动一个开发服务器进行开发,这里也会配置一个publicPath,这里的publicPath路径下的打包文件能够在浏览器中访问。而静态资源仍然使用output.publicPath

webpack-dev-server打包的内容是放在内存中的,这些打包后的资源对外的的根目录就是publicPath,换句话说,这里咱们设置的是打包后资源存放的位置

例如:

// 假设devServer的publicPath为
const publicPath = '/dist/'
// 则启动devServer后index.html的位置为
const htmlPath = `${pablicPath}index.html`
// 包的位置
cosnt mainJsPath = `${pablicPath}main.js`
复制代码

以上能够直接经过http://lcoalhost:8080/dist/main.js访问到。

经过访问 http://localhost:8080/webpack-dev-server 能够获得devServer启动后的资源访问路径,如图所示,点击静态资源能够看到静态资源的访问路径为 http://localhost:8080${publicPath}index.html

图1-1

html-webpack-plugin

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

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

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

因此通常状况下都要保证devServer中的publicPathoutput.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 命令时所在的文件夹的绝对路径

参考

相关文章
相关标签/搜索