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 相关文章推荐
javascript replace方法与正则表达式
Feb 19 Javascript
Javascript学习笔记6 prototype的提出
Jan 11 Javascript
jQuery选择器的工作原理和优化分析
Jul 25 Javascript
瀑布流布局代码一例
Apr 11 Javascript
郁闷!ionic中获取ng-model绑定的值为undefined如何解决
Aug 27 Javascript
使用PBFunc在Powerbuilder中支付宝当面付款功能
Oct 01 Javascript
微信小程序-图片、录音、音频播放、音乐播放、视频、文件代码实例
Nov 22 Javascript
JS基于递归算法实现1,2,3,4,5,6,7,8,9倒序放入数组中的方法
Jan 03 Javascript
Node.js+Express+MySql实现用户登录注册功能
Jul 10 Javascript
vue.js实现的幻灯片功能示例
Jan 18 Javascript
微信小程序实现form表单本地储存数据
Jun 27 Javascript
vue3自定义dialog、modal组件的方法
Jan 04 Vue.js
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
让whoops帮我们告别ThinkPHP6的异常页面
2020/03/02 PHP
js的逻辑运算符 ||
2010/05/31 Javascript
jquery ajax return没有返回值的解决方法
2011/10/20 Javascript
javascript 进阶篇3 Ajax 、JSON、 Prototype介绍
2012/03/14 Javascript
JavaScript 函数replace深入了解
2013/03/14 Javascript
JS cookie中文乱码解决方法
2014/01/28 Javascript
JS将数字转换成三位逗号分隔的样式(示例代码)
2014/02/19 Javascript
基于NodeJS的前后端分离的思考与实践(三)轻量级的接口配置建模框架
2014/09/26 NodeJs
对比分析json及XML
2014/11/28 Javascript
js中this的用法实例分析
2015/01/10 Javascript
微信小程序之小豆瓣图书实例
2016/11/30 Javascript
JS利用cookies设置每隔24小时弹出框
2017/04/20 Javascript
JS禁止浏览器右键查看元素或按F12审查元素自动关闭页面示例代码
2017/09/07 Javascript
webpack 插件html-webpack-plugin的具体使用
2018/04/09 Javascript
JS实现的文件拖拽上传功能示例
2018/05/21 Javascript
react脚手架如何配置less和ant按需加载的方法步骤
2018/11/28 Javascript
js实现超级玛丽小游戏
2020/03/18 Javascript
JavaScript使用prototype属性实现继承操作示例
2020/05/22 Javascript
Vue Router中应用中间件的方法
2020/08/06 Javascript
[02:50]2014DOTA2 TI预选赛预选赛 大神专访第一弹!
2014/05/21 DOTA
Windows中使用wxPython和py2exe开发Python的GUI程序的实例教程
2016/07/11 Python
python使用筛选法计算小于给定数字的所有素数
2018/03/19 Python
Python中collections模块的基本使用教程
2018/12/07 Python
python代码 FTP备份交换机配置脚本实例解析
2019/08/01 Python
python实现的多任务版udp聊天器功能案例
2019/11/13 Python
如何基于Python实现自动扫雷
2020/01/06 Python
python3发送request请求及查看返回结果实例
2020/04/30 Python
HTML5混合开发二维码扫描以及调用本地摄像头
2017/12/27 HTML / CSS
Carter’s OshKosh加拿大:购买婴幼儿服装和童装
2018/11/27 全球购物
EJB包括(SessionBean,EntityBean)说出他们的生命周期,及如何管理事务的
2015/07/24 面试题
修理厂厂长岗位职责
2014/01/30 职场文书
电大毕业自我鉴定
2014/02/03 职场文书
十八届三中全会宣传方案
2014/02/21 职场文书
反四风个人对照检查材料
2014/09/26 职场文书
Kubernetes部署实例并配置Deployment、网络映射、副本集
2022/04/01 Servers
Android开发之WECHAT微信小程序路由跳转的两种形式
2022/04/12 Java/Android