填坑:在 SegmentFault 开发单页应用之图片引用的问题探索
前言
前段时间,SegmentFault 低调上线了 技术号 模块,方便用户对数据进行集中管理。在开发过程中,第一次引入了 MV* 框架。

SF 的基本架构还是后端路由,这也使得页面频繁地整体请求,体验非常不好。而技术号这个模块,不依赖 SEO,侧边导航又具有非常强烈的可切换性,所以适当地引入一个 MV* 框架是非常合适的。基于此考虑,决定在这个模块的开发中引入 Vue.js。
SF 目前的前端架构是非常传统的,jQuery+BootStrap+Requirejs+Gulp 的开发组合,r.js 做上线前的打包。如何将 Vue.js 应用进入目前的架构?其实非常简单,遵循一个原则即可,r.js 最后打包成一个 js 文件,而 webpack 最后也是打包成一个 js 文件。
我们用 webpack-dev-server 起前端 server 后,在内存中生成的 js 的路径类似 localhost:8080/xxx.js,然后在后端模版中引用这个 js 即可。值得注意的是,必须写死绝对路径,所以只能指定端口,目前我还没有找到更好的办法解决这个问题。
图片引用
其他部分的开发,比如 js 和 css 都没有什么大的问题,图片的引用成了问题。在第一次上线时我用了线上的绝对路径,这显然是不合理的。
之前的图片引用,其实是依赖后端的。前端上线时,会有一个文件夹包含所有的 js、css 以及图片文件,然后将这个文件夹重命名(重命名成一个哈希版本号),再上传到 CDN。所以如果独立打开 js、css 或者图片文件,其实路径上是会有一个版本号的。
那么目前线上是如何解决的?目前应用图片的地方主要是后端模版文件以及 css。如果是后端模版文件,引用图片时会先调用一个后端函数,这个函数会返回图片路径,很显然开发环境和线上环境这个路径的结果是不同的。同样,js 和 css 的引入,都会被这个函数先调用才返回引用路径。而在 css 中引用图片就没啥问题了,只是个相对路径的事。
而将图片引用放入前端了呢?图片的路径和 js 的路径具有某种联系,本质是需要获取这个哈希版本号。问题在于,如何获取正在执行的 js 文件的路径?其实这很像是一道脑筋急转弯,如果习惯了 Node 的方式,可能会从 __dirname 和 process.cwd() 去入手,但是很遗憾虽然客户端也能引入 process 、path 等包,但是获取不到类似的值。答案也很简单,直接获取 script 的 dom 节点,然后取 src 即可,就是完美的绝对路径。另外还有个方法,可以用 document.currentScript.getAttribute('src'),但是 src 赋值的字符串是什么,它就是什么,而且在实际开发中莫名报错,所以我用了前者。
cdn: src => {
let jsPath = document.getElementById('indexScript').src.replace(/script.*/, 'img/')
src = jsPath + src
return src
}
这样就粗暴地解决了线上图片引用的问题。
开发 VS 线上
但是本地开发引用图片的问题还没有解决。
综上所述,本地开发起的前端 server,其实是用了绝对地址 localhost:8080/xxx.js,如果用以上规则获取图片,很显然获取的还是 localhost:8080 域名下的图片,我们需要将其切换到后端路由的测试域名下。
也就是规则类似 localhost:8080/build/xxx/img/xxx.png 的请求都需要转到另外一个域名下(实际开发中是 sf.testapp.org),chrome 下有个神器 ReRes 可以轻易做到。
配置如下:
// If URL match
http://localhost:8080/build/(.*)/img/
// Response
http://sf.testapp.org/build/$1/img/
这样就粗暴解决了开发环境引用不到图片的问题。
待续
这并不是终点。其实目前的图片是放在最终上线的静态文件文件夹中,和 Vue.js 整个开发项目剥离,这并不是一个好的方式。最好的方式肯定是放在 Vue.js 项目中,比如 assets 或者 static 文件夹下。这就需要在前端引用图片的时候判断是开发还是线上环境,分别引用不同地址,开发完后,打包前需要将项目中的图片同步到需要上线的静态文件文件夹中。还有另一种方案,开发和线上引用一个地址,但是开发环境引用时再做一次映射,跳到 Vue.js 项目内。
目前还没考虑这点,因为这只是 MV* 的第一次尝试,文件目录的结构还没最终确定。
思考
这个功能的开发其实不具有典型的参考意义,我称之为 "走 SF 特色的一次开发尝试"。毕竟需要前后端路由混杂,而且还和最终线上打包方式有关,只能因地制宜,走自己的路。
这让我想到了之前一位前辈对我说的话:
前端的主要竞争力还是学习能力,程序员的竞争力是解决问题的能力。
共勉之
填坑:在 SegmentFault 开发单页应用之图片引用的问题探索的更多相关文章
- Laravel 5.5 + Vue 开发单页应用
上次我用 laravel5.3 + Vue 开发了一个简单的单页应用,这次我打算将其升级到 laravel5.5,在升级的过程中,做一下记录,其源码放在 github 上面,源码地址 开发环境 软 ...
- 使用Vue快速开发单页应用
本文所涉及代码全在vue-cnode 单页应用,即在一个页面集成系统中所有功能,整个应用只有一个页面.因为路由的控制在前端,单页面应用在页面切换时比传统页面更快,从而在前端体验更好. 将逻辑从后端转移 ...
- 【前端vue开发架构】vue开发单页项目架构总结
为营销活动设计的前端架构 主要的技术栈为 Vuejs,Webpack,请自行阅读如下技术或者框架的文档: 一.基础说明: node (https://nodejs.org/en/) npm (http ...
- 基于环信SDK的IM即时通讯填坑之路(vue)
公司最近使用第三方环信SDK的进行通信聊天,基本已完成.记录下填坑之路 1.可以通过以下方式引用 WebSDK 1.安装 npm install easemob-websdk --save 2. 先 ...
- Android Tips – 填坑手册
出于: androidChina http://www.androidchina.net/3595.html 学习 Android 至今,大大小小的坑没少踩,庆幸的是,在强大的搜索引擎与无私奉献的 ...
- webapp填坑记录[更新中]
网上也有许多的 webapp 填坑记录了,这几个月,我在公司正好也做了2个,碰到了一些问题,所以我在这里记录一下我所碰到的问题: meta 头部声明在开发的时候,刚刚创建 HTML 文件,再使用浏览器 ...
- webapp填坑记录
网上也有许多的 webapp 填坑记录了,这几个月,我在公司正好也做了2个,碰到了一些问题,所以我在这里记录一下我所碰到的问题: meta 头部声明在开发的时候,刚刚创建 HTML 文件,再使用浏览器 ...
- 微信公众号支付备忘及填坑之路-java
一.背景 最近公司给第三方开发了一个公众号,其中最重要的功能是支付,由于是第一次开发,遇到的坑特别的多,截止我写博客时,支付已经完成,在这里我把遇到的坑记录一下(不涉及退款).不得不吐槽一下,腾讯这么 ...
- css 填坑常用代码分享
以下是常用的代码收集,没有任何技术含量,只是填坑的积累.转载请注明出处,谢谢. 因为提交比较麻烦,后来转置github:https://github.com/jsfront/src/blob/mast ...
随机推荐
- deeplearning.ai 人工智能行业大师访谈 Ian Goodfellow 听课笔记
1. Ian Goodfellow之前是做神经科学研究,在斯坦福上了Andrew NG的课之后,Ian决定投身AI.在寒假他和小伙伴读了Hinton的论文,然后搭了一台用CUDA跑Boltzmann ...
- 详解css3弹性盒模型(Flexbox)
目前没有浏览器支持 box-flex 属性. Firefox 支持替代的 -moz-box-flex 属性. Safari.Opera 以及 Chrome 支持替代的 -webkit-box-flex ...
- 2-Sat+输出可行解(个人模版)
2-Sat+输出可行解: //LightOJ 1251 #include<stdio.h> #include<string.h> #include<vector> ...
- vijos 1213:80人环游世界
描述 想必大家都看过成龙大哥的<80天环游世界>,里面的紧张刺激的打斗场面一定给你留下了深刻的印象.现在就有这么一个80人的团伙,也想来一次环游世界. 他们打算兵分多路,游遍每一个国家. ...
- 北京师范大学校赛C
https://www.nowcoder.com/acm/contest/submit/0dff89ad7b8444719df155d507f3e1dd?ACMContestId=3&tagI ...
- java web开发 高并发处理
转自:http://blog.csdn.net/zhangzeyuaaa/article/details/44542161 java处理高并发高负载类网站中数据库的设计方法(java教程,java处理 ...
- [国嵌攻略][067][tftp协议分析]
TFTP作用 用于网络下载,TFTP客户机在TFTP服务器中下载文件. TFTP交换过程 1.配置TFTP服务器 vim /etc/xinetd.d/tftp 2.交换过程 客户端发请求包到服务器 服 ...
- Ubuntu下 jdk环境变量设置
流程 1. 官网下载对应的jdk文件 2. 在根目录 / 下创建一个java目录 mkdir /java 3. 使用mv命令 将下载下来的文件(压缩格式),移动到上一步创建的/java目录下 Ps ...
- 将本地的项目导入到github仓库总结lxw
关键步骤: 第一:git clone https://github.com/lxw18231857001/demo-.git #把github上面的仓库克隆到本地 本地项目文件夹下 ...
- C# winform引用com组件,创建AXHOST组件失败解决方案
解决方法非常简单,请首先关闭你的开发工具然后删除所有*.vshost.exe 的文件. 重新打开visual studio开发工具,重新编译你的程序.