Posted in: Biology Science, IT

使用 Vue 开发生物信息学数据库的体会

这不是教程,而是我的随笔✏️

自从前年刚入职的时候猛干 7 天 Flask 开发之后,我就感觉 Flask 做后端还马马虎虎,做前端实在是在笨重了。所以萌生了上框架的想法。早在 2017 年时我就曾经尝试看 Vue 教程,结果因为看不懂放弃了,有点可惜。去年开始开发新项目时,知道这个项目负责,不上框架很可能搞不定。于是硬着头皮学习 Vue3,配个 ChatGPT 的帮助,终于搞定了。

传统的 HTML + CSS + JS 有什么不方便的地方?

在 2012 年我刚学 HTML + CSS + JS 时,遵循的都是以下模式:

HTML 放在 index.html 里面:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <link rel="icon" href="/favicon.ico">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>My Title</title>
    <script src="/js/my-script.js"></script>
    <link rel="stylesheet" href="/css/my-style.css">
  </head>
  <body>
    <header>This is Header</header>
    <main>This is main</main>
    <footer>This is Footer</footer>
  </body>
</html>

CSS 放在 /css/my-style.css 里面:

main {
   color: red
}

JS 放在 /js/my-script.js 里面:

console.log("Hello")

下面说一下不方便的地方:

  1. 开发时修改了 html,必须要手动刷新网页才能看见效果。当然这个还能忍。
  2. 开发时修改了 css 或 js,居然发现手动刷新网页也不能看见效果。原来是浏览器把 css 或 js 文件缓存下来了,必须手动清空缓存才能看见效果!这就太不方便了。直接禁用缓存?也不行,我们希望最后的产品给用户访问时、能够缓存这些静态文件。那么开发时禁用缓存、发布后开启缓存?如果发布后发现 bug 需要继续开发修复呢?要反复开关切换缓存,这就麻烦死了。
  3. 有好几个页面共用 <header> <footer>,纯 HTML 没有这种机制来实现。虽然 Apache 服务器有一些方法,例如 Server Side Includes(SSI),但说真的很不方便。

用框架进行开发(dev)和发布(build)

框架的优点在于它有开发(dev)模式和发布(build)模式。以 Vue3 开发 + NPM (Vite)打包为例:

在 dev 模式下,它利用 web worker 实现热更新,意思就是:只要你修改了文件,点击保存时,网页立即显示结果,不用手动刷新。

在 build 模式下,它把所有文件进行打包重组,此时 index.html 变成了这样:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <link rel="icon" href="/favicon.ico">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>My Title</title>
    <script src="/assets/index-e3e6f7fe.js"></script>
    <link rel="stylesheet" href="/assets/index-0ef21ce6.css">
  </head>
  <body>
    <header></header>
    <main></main>
    <footer></footer>
  </body>
</html>

这里有几个地方很有意思:

  1. index.html 不再放实际的内容,而是只剩了一个空壳。“This is Header”、“This is main”这些文字都消失了。
  2. 那么这些东西到哪里去了呢?它们都被塞入了 /assets/index-e3e6f7fe.js 文件里面。所有与 HTML 以及 JS 相关的内容(无论源代码里面有几个文件)都被打包进了这个单独的 JS 文件,文件名字后面带着一个随机的 Hash 字符串(e3e6f7fe)。相应地,所有 CSS 相关的内容都被打包进了一个单独的 CSS 文件 /assets/index-0ef21ce6.css,文件名字后面也带着一个随机的 Hash 字符串(0ef21ce6)。每次 build 时,如果源代码有变化,这些字符串就会变。这就很好地解决了缓存的问题:
    • 网站没有更新时(即使反复 build),这些 JS 和 CSS 文件的名字不变,浏览器自动使用上一次的缓存。
    • 网站有更新时,JS 和 CSS 文件名字发生改变,浏览器会下载新的版本。
  3. 这些文件因为是打包重组的,打开后里面都是各种类似于乱码的字符,实际上也不需要打开。

接下来列举一些体会:

第一:index.html 文件不能缓存

如上所示,index.html 只是一个空壳,大小一般不超过 1KB,当然没必要缓存,而且也不能缓存。否则 CSS 和 JS 文件改变了、客户端都不知道。例如对于 apache 服务器来说可以这么设置:

<Files "index.html">
    Header set Cache-Control "no-cache, no-store, must-revalidate"
</Files>

之前没注意这个问题,每次 build 新版本之后,都需要手动刷新一下页面才能看到发布后的新结果,其实就是因为浏览器把老的 index.html 缓存下来了。

第二:src/assets 和 public 目录的区别

两者都是拿来放静态文件的,但区别很大:

src/assets 目录下面的文件在打包之后,文件名后面会带上 hash 值,因此一般用于 CSS、JS 或其他经常需要编辑(版本更新)的文本文件。打包之后进入 dist/assets 目录。

public 目录下面的文件在打包之后文件名维持原状,因此一般用于图片或其他不需要经常变动的二进制文件。打包之后进入 dist 根目录。注意由于文件名没有 hash 值了,如果文件内容改了名字却没有改,就要小心缓存的问题。

第三:拆分 /assets/下面的 index-[hash].css 和 index-[hash].js

当我需要用各种第三方的 UI 库(例如:Bootstrap、HighCharts、Mapbox、多功能表格等)时,问题就来了:在打包的时候,它们的 CSS 和 JS 会与我自己写的 CSS 和 JS 合并,导致 /assets/下面的 index-[hash].cssindex-[hash].js 文件很大。虽然有 gzip 压缩,可是我哪怕只修改网页中的一个标点符号,都会导致 index-[hash].js 重建,这是不是太得不偿失了?显然必须拆分它们,在开发后期,第三方的 UI 库已经很稳定,一般不会再更改。Vue3 开发的特点是:第三方的 UI 库都会安装在 node_modules 目录下面,所以只要设置 vite.config.js 如下即可:

    build: {
      rollupOptions: {
        output: {
          manualChunks(id) {
            if (id.includes('node_modules')) {
              return 'modules';
            }
          }
        }
      }
    }

这样配置之后,build 之后除了生成 index-[hash].css 和 index-[hash].js 之外,还会生成 modules-[hash].css 和 modules-[hash].js。前者是自己写的内容,文件很小,但经常变。后者全是第三方库,文件较大,但很少变。这样每发布一个新版本时,用户只需要接受小的 index-[hash].css 和 index-[hash].js 更新就可以了。

Comments (9) on "使用 Vue 开发生物信息学数据库的体会"

  1. Google Chrome 107.0.0.0 Android 6.0.1

    框架做大項目是必需的,不過我現在做的都是基於wordpress的小網頁,wordpress也有一個ajax功能,也可以配合後端了,所以暫時用不到框架。

    另,每次評論時,第一次提交都會因reCAPTCHA的問題而失敗,要提交幾次才上去。

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注