前言

前段时间,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 的方式,可能会从 __dirnameprocess.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 开发单页应用之图片引用的问题探索的更多相关文章

  1. Laravel 5.5 + Vue 开发单页应用

    上次我用 laravel5.3 + Vue 开发了一个简单的单页应用,这次我打算将其升级到 laravel5.5,在升级的过程中,做一下记录,其源码放在 github 上面,源码地址   开发环境 软 ...

  2. 使用Vue快速开发单页应用

    本文所涉及代码全在vue-cnode 单页应用,即在一个页面集成系统中所有功能,整个应用只有一个页面.因为路由的控制在前端,单页面应用在页面切换时比传统页面更快,从而在前端体验更好. 将逻辑从后端转移 ...

  3. 【前端vue开发架构】vue开发单页项目架构总结

    为营销活动设计的前端架构 主要的技术栈为 Vuejs,Webpack,请自行阅读如下技术或者框架的文档: 一.基础说明: node (https://nodejs.org/en/) npm (http ...

  4. 基于环信SDK的IM即时通讯填坑之路(vue)

    公司最近使用第三方环信SDK的进行通信聊天,基本已完成.记录下填坑之路 1.可以通过以下方式引用 WebSDK 1.安装 npm install easemob-websdk --save 2. 先 ...

  5. Android Tips – 填坑手册

    出于: androidChina   http://www.androidchina.net/3595.html 学习 Android 至今,大大小小的坑没少踩,庆幸的是,在强大的搜索引擎与无私奉献的 ...

  6. webapp填坑记录[更新中]

    网上也有许多的 webapp 填坑记录了,这几个月,我在公司正好也做了2个,碰到了一些问题,所以我在这里记录一下我所碰到的问题: meta 头部声明在开发的时候,刚刚创建 HTML 文件,再使用浏览器 ...

  7. webapp填坑记录

    网上也有许多的 webapp 填坑记录了,这几个月,我在公司正好也做了2个,碰到了一些问题,所以我在这里记录一下我所碰到的问题: meta 头部声明在开发的时候,刚刚创建 HTML 文件,再使用浏览器 ...

  8. 微信公众号支付备忘及填坑之路-java

    一.背景 最近公司给第三方开发了一个公众号,其中最重要的功能是支付,由于是第一次开发,遇到的坑特别的多,截止我写博客时,支付已经完成,在这里我把遇到的坑记录一下(不涉及退款).不得不吐槽一下,腾讯这么 ...

  9. css 填坑常用代码分享

    以下是常用的代码收集,没有任何技术含量,只是填坑的积累.转载请注明出处,谢谢. 因为提交比较麻烦,后来转置github:https://github.com/jsfront/src/blob/mast ...

随机推荐

  1. CTF---隐写术入门第二题 小苹果

    小苹果分值:10 来源: hanyuhang 难度:易 参与人数:2159人 Get Flag:862人 答题人数:996人 解题通过率:87% flag格式: CTF{} 解题链接: http:// ...

  2. 洛谷 P1019 单词接龙【经典DFS,温习搜索】

    P1019 单词接龙 题目描述 单词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已知一组单词,且给定一个开头的字母,要求出以这个字母开头的最长的“龙”(每个单词都最多在“龙”中出现两次),在 ...

  3. UVALive3882-And Then There Was One-约瑟夫问题-递推

    And Then There Was One Time limit: 3.000 seconds Let's play a stone removing game. Initially, n ston ...

  4. POJ_1064 二分搜索

    /*POJ 1064 *题目大意:有N条绳子,他们的长度分别为Li,如果从他们中切割K条长度相同的绳子的话,这K条绳子每条最长能有多长?答案保留到小数点后2位 *算法分析:这个问题用二分搜索可以非常容 ...

  5. Linux编译安装Mariadb数据库

    一.安装cmake cd /usr/local/src tar zxvf cmake-2.8.12.1.tar.gz cd cmake-2.8.12.1 ./configure 注意报错需要安装gcc ...

  6. os系统

    任务延时函数OSTimeDly 功能:调用该函数的任务将自己延时一段时间并执行一次任务调度,一旦规定的延时时间完成或有其它的任务通过调用OSTimeDlyResume()取消了延时,调用OSTimeD ...

  7. Apache日志分析_shell命令行

    说明: 1.我的日志预先设定好按日生成文件:"CustomLog "|/opt/apache/bin/rotatelogs /opt/apache/logs/www.website ...

  8. Redis单机版安装

    1.工具简单介绍 1.博主使用的是Xshell工具 ps:需要设置端口和连接名称,端口一般默认为22,需要的童鞋可以自行百度 2.Redis单机版安装 第一步:安装gcc编译环境 yum instal ...

  9. mybatis_helloWorld_sequence图(3)

    摘录自:http://blog.csdn.net/y172158950/article/details/17006127 1. 依据resource获取Reader的sequence图 String  ...

  10. wigs的理解和应用

    1. 首先了解下,Web应用的本质,大体如下: 1.浏览器发送一个HTTP请求: 2.服务器收到请求,生成一个HTML文档: 3.服务器把HTML文档作为HTTP响应的Body发送给浏览器: 4.浏览 ...