Webpack中publicPath路径问题详解


Posted in Javascript onMay 03, 2018

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

output

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

output.path

默认值: process.cwd()

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

output: {
 path: path.resolve(__dirname, '../dist'),
}

output.publicPath

默认值:空字符串

官方文档中对publicPath的解释 是

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

而关于如何应用该路径并没有说清楚...

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

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

例如

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 ,本地无法访问

所以这里需要在上线时候手动更改 publicPath ,感觉不是很方便,但是不知道该如何解决...

一般情况下 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

Webpack中publicPath路径问题详解

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 保持一致。

最后

关于webpack中的 path 就总结这么多,在研究关于webpack路径的过程中看查到的一些关于路径的零碎的知识如下:

斜杠/的含义

配置中/代表url根路径,例如http://localhost:8080/dist/js/test.js中的http://localhost:8080/

devServer.publicPath & devServer.contentBase

  1. devServer.contentBase 告诉服务器从哪里提供内容。只有在你想要提供静态文件时才需要。
  2. devServer.publicPath 将用于确定应该从哪里提供 bundle,并且此选项优先。

node中的路径

  1. __dirname: 总是返回被执行的 js 所在文件夹的绝对路径
  2. __filename: 总是返回被执行的 js 的绝对路径
  3. process.cwd(): 总是返回运行 node 命令时所在的文件夹的绝对路径

参考

详解Webpack2的那些路径
webpack 公共路径(Public Path)
devServer.publicPath
浅析 NodeJs 的几种文件路径

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
jquery select下拉框操作的一些说明
Apr 02 Javascript
js 实现 input type="file" 文件上传示例代码
Aug 07 Javascript
jQuery 获取/设置/删除DOM元素的属性以a元素为例
May 23 Javascript
jQuery实现的Div窗口震动特效
Jun 09 Javascript
浅析Bootstrap验证控件的使用
Jun 23 Javascript
AnjularJS中$scope和$rootScope的区别小结
Sep 18 Javascript
20个最常见的jQuery面试问题及答案
May 23 jQuery
Vuex 在Vue 组件中获得Vuex 状态state的方法
Aug 27 Javascript
webpack4实现不同的导出类型
Apr 09 Javascript
jQuery实现高级检索功能
May 28 jQuery
AntV F2和vue-cli构建移动端可视化视图过程详解
Oct 08 Javascript
vue-property-decorator用法详解
Dec 12 Javascript
Angular Renderer (渲染器)的具体使用
May 03 #Javascript
react router4+redux实现路由权限控制的方法
May 03 #Javascript
vue.js学习笔记之v-bind和v-on解析
May 03 #Javascript
jQuery实现每隔一段时间自动更换样式的方法分析
May 03 #jQuery
详解VueJs中的V-bind指令
May 03 #Javascript
基于vue,vue-router, vuex及addRoutes进行权限控制问题
May 02 #Javascript
用ES6写全屏滚动插件的示例代码
May 02 #Javascript
You might like
用PHP连接Oracle数据库
2006/10/09 PHP
PHP 第二节 数据类型之转换
2012/04/28 PHP
php操作mysql数据库的基本类代码
2014/02/25 PHP
Laravel 4 初级教程之视图、命名空间、路由
2014/10/30 PHP
PHP面相对象中的重载与重写
2017/02/13 PHP
PHP生成各种随机验证码的方法总结【附demo源码】
2017/06/05 PHP
laravel 查询数据库获取结果实现判断是否为空
2019/10/24 PHP
每天一篇javascript学习小结(Date对象)
2015/11/13 Javascript
javascript轻量级库createjs使用Easel实现拖拽效果
2016/02/19 Javascript
图文详解Heap Sort堆排序算法及JavaScript的代码实现
2016/05/04 Javascript
详解JavaScript节流函数中的Throttle
2016/07/16 Javascript
js实现添加可信站点、修改activex安全设置,禁用弹出窗口阻止程序
2016/08/17 Javascript
Vue实现购物车功能
2017/04/27 Javascript
在Vue组件上动态添加和删除属性方法
2018/02/23 Javascript
解决Vue 通过下表修改数组,页面不渲染的问题
2018/03/08 Javascript
使用vue-router在Vue页面之间传递数据的方法
2019/07/15 Javascript
基于postman获取动态数据过程详解
2020/09/08 Javascript
vue实现列表拖拽排序的功能
2020/11/02 Javascript
element-ui中el-upload多文件一次性上传的实现
2020/12/02 Javascript
Python Mysql数据库操作 Perl操作Mysql数据库
2009/01/12 Python
python中二维阵列的变换实例
2014/10/09 Python
Python编程之序列操作实例详解
2017/07/22 Python
Python3.6简单操作Mysql数据库
2017/09/12 Python
python3.6利用pyinstall打包py为exe的操作实例
2018/10/31 Python
Django之编辑时根据条件跳转回原页面的方法
2019/08/21 Python
Python中内建模块collections如何使用
2020/05/27 Python
国际性能运动服装品牌:Dare 2b
2018/07/27 全球购物
学前班学生评语
2014/12/29 职场文书
银行稽核岗位职责
2015/04/13 职场文书
2015年安全生产管理工作总结
2015/05/25 职场文书
子女赡养老人协议书
2016/03/23 职场文书
导游词之长城八达岭
2019/09/24 职场文书
iPhone13 Pro外观确定,升级4800万镜头,4月20日发新品
2021/04/15 数码科技
Python趣味爬虫之用Python实现智慧校园一键评教
2021/05/28 Python
Python+Matplotlib图像上指定坐标的位置添加文本标签与注释
2022/04/11 Python
IIS服务器中设置HTTP重定向访问HTTPS
2022/04/29 Servers