前言

前段时间,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. 记一次python的一些参数

    isdigit把字符串转化为整数 用法 if xx.isdigit(): xx=int(xx) index创建一个小原组,用法print(a.index(b),b)从0开始

  2. bzoj:1673 [Usaco2005 Dec]Scales 天平

    Description Farmer John has a balance for weighing the cows. He also has a set of N (1 <= N <= ...

  3. 电铸3D18K硬金 电铸易熔合金 电铸中空硬金饰品合金

        俊霖电铸3DK金易熔合金是要求相互关连,互为条件,缺一不可,是产品完整性和完美性的重要体现.    第一.适用性:电铸3DK金易熔合金的性能应适用于电铸.首饰.K金饰品.摆件等工艺品的易熔合金 ...

  4. [国嵌攻略][152][I2C总线介绍]

    IIC电气特性 I2C(inter intergrated circuit)总线是由philps公司开发的两线式串行总线,用于连接微控制器及其外围设备. I2C总线只有两根双向信号线: SDA:ser ...

  5. CMD命令操作MySql数据库详解

    第一:mysql服务的启动和停止 1.  net stop mysql 2.  net start mysql 第二:登录 mysql –u用户名 [–h主机名或者IP地址] –p密码 例如:mysq ...

  6. Thinkphp+Nginx(PHPstudy)下报的404错误,403错误解决

    最近一个TP5的项目说放到Nginx下测试看看,下载个 PHPstudy,放到WWW下,配置好域名,直接给个报个404: 解决方法: 1.先在phpstudy下配置好域名目录指向项目下的public下 ...

  7. FileZilla出现Failed to convert command to 8 bit charset 

    FileZilla这款FTP客户端软件,自从华哥使用以来,采用其默认的设置,一直用得很顺畅,没有出现过什么问题.但是今天碰到了一个问题.如图. 错误信息为:Failed to convert comm ...

  8. javascript alert乱码的解决方法

    http://www.jb51.net/article/42805.htm 提示时中文乱码,拼音什么的都没有问题呀,下面我在论坛找到一解决办法,下面与大家分享. 解决办法一: 复制代码 代码如下: e ...

  9. ADO.NET复习总结(3)--参数化SQL语句--防止sql注入式攻击

    1.SQL 注入 2.使用参数化的方式,可以有效防止SQL注入,使用类parameter的实现类SqlParameter Command的属性parameters是一个参数集合. 3.举例<查询 ...

  10. eclipse 按住ctrl 按钮没有反映

    以下是修改为XML Editior打开方法Window -> Preferences -> General -> Editors -> File Associations Fi ...