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 相关文章推荐
JS Array对象入门分析
Oct 30 Javascript
JavaScript 学习笔记(九)call和apply方法
Jan 11 Javascript
[原创]js获取数组任意个不重复的随机数组元素
Mar 15 Javascript
基于jQuery实现的水平和垂直居中的div窗口
Aug 08 Javascript
js+xml生成级联下拉框代码
Jul 24 Javascript
jquery简单的拖动效果实现原理及示例
Jul 26 Javascript
jQuery+AJAX实现遮罩层登录验证界面(附源码)
Sep 13 Javascript
轻松掌握JavaScript状态模式
Sep 07 Javascript
详解webpack的proxyTable无效的解决方案
Jun 15 Javascript
基于vue中keep-alive缓存问题的解决方法
Sep 21 Javascript
vue 左滑删除功能的示例代码
Jan 28 Javascript
小程序识别身份证,银行卡,营业执照,驾照的实现
Nov 05 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获取当前网址url并替换参数或网址的方法
2010/06/06 PHP
php 使用ActiveMQ发送消息,与处理消息操作示例
2020/02/23 PHP
使用jQuery全局事件ajaxStart为特定请求实现提示效果的代码
2010/12/30 Javascript
js不能跳转到上一页面的问题解决方法
2013/03/01 Javascript
JS常用字符串处理方法应用总结
2014/05/22 Javascript
js 中将多个逗号替换为一个逗号的代码
2014/06/07 Javascript
javascript中undefined与null的区别
2015/08/16 Javascript
JavaScript面向对象编写购物车功能
2016/08/19 Javascript
JS组件系列之使用HTML标签的data属性初始化JS组件
2016/09/14 Javascript
原生js实现简单的模态框示例
2017/09/08 Javascript
快速将Vue项目升级到webpack3的方法步骤
2017/09/14 Javascript
swiper 解决动态加载数据滑动失效的问题
2018/02/26 Javascript
解决vue多个路由共用一个页面的问题
2018/03/12 Javascript
jQuery实现的点击按钮改变样式功能示例
2018/07/21 jQuery
配置eslint规范项目代码风格
2019/03/11 Javascript
基于AngularJS拖拽插件ngDraggable.js实现拖拽排序功能
2019/04/02 Javascript
使用cx_freeze把python打包exe示例
2014/01/24 Python
python中map、any、all函数用法分析
2015/04/21 Python
简单谈谈Python中函数的可变参数
2016/09/02 Python
详解python实现读取邮件数据并下载附件的实例
2017/08/03 Python
Python2和Python3中print的用法示例总结
2017/10/25 Python
基于python3 OpenCV3实现静态图片人脸识别
2018/05/25 Python
opencv python 基于KNN的手写体识别的实例
2018/08/03 Python
PyCharm 设置SciView工具窗口的方法
2019/01/15 Python
html5中为audio标签增加停止按钮动作实现方法
2013/01/04 HTML / CSS
阿里健康大药房:阿里自营网上药店
2017/08/01 全球购物
如何在.net Winform里面显示PDF文档
2012/09/11 面试题
开工庆典邀请函范文
2014/01/16 职场文书
置业顾问岗位职责
2014/03/02 职场文书
年终考核实施方案
2014/05/26 职场文书
会员活动策划方案
2014/08/19 职场文书
竞选班干部演讲稿600字
2014/08/20 职场文书
行政专员岗位职责说明书
2014/09/01 职场文书
2015年万圣节活动总结
2015/03/24 职场文书
使用Spring处理x-www-form-urlencoded方式
2021/11/02 Java/Android
CSS中calc(100%-100px)不加空格不生效
2023/05/07 HTML / CSS