这不是教程,而是我的随笔✏️
自从前年刚入职的时候猛干 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")
下面说一下不方便的地方:
- 开发时修改了 html,必须要手动刷新网页才能看见效果。当然这个还能忍。
- 开发时修改了 css 或 js,居然发现手动刷新网页也不能看见效果。原来是浏览器把 css 或 js 文件缓存下来了,必须手动清空缓存才能看见效果!这就太不方便了。直接禁用缓存?也不行,我们希望最后的产品给用户访问时、能够缓存这些静态文件。那么开发时禁用缓存、发布后开启缓存?如果发布后发现 bug 需要继续开发修复呢?要反复开关切换缓存,这就麻烦死了。
- 有好几个页面共用
<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>
这里有几个地方很有意思:
-
index.html
不再放实际的内容,而是只剩了一个空壳。“This is Header”、“This is main”这些文字都消失了。 - 那么这些东西到哪里去了呢?它们都被塞入了
/assets/index-e3e6f7fe.js
文件里面。所有与 HTML 以及 JS 相关的内容(无论源代码里面有几个文件)都被打包进了这个单独的 JS 文件,文件名字后面带着一个随机的 Hash 字符串(e3e6f7fe
)。相应地,所有 CSS 相关的内容都被打包进了一个单独的 CSS 文件/assets/index-0ef21ce6.css
,文件名字后面也带着一个随机的 Hash 字符串(0ef21ce6
)。每次 build 时,如果源代码有变化,这些字符串就会变。这就很好地解决了缓存的问题:- 网站没有更新时(即使反复 build),这些 JS 和 CSS 文件的名字不变,浏览器自动使用上一次的缓存。
- 网站有更新时,JS 和 CSS 文件名字发生改变,浏览器会下载新的版本。
- 这些文件因为是打包重组的,打开后里面都是各种类似于乱码的字符,实际上也不需要打开。
接下来列举一些体会:
第一: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].css
和 index-[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 更新就可以了。
框架做大項目是必需的,不過我現在做的都是基於wordpress的小網頁,wordpress也有一個ajax功能,也可以配合後端了,所以暫時用不到框架。
另,每次評論時,第一次提交都會因reCAPTCHA的問題而失敗,要提交幾次才上去。
網路問題?我試了一下這裡的網路環境下是正常提交的。
我之前就是要点一下右下角的图标,就可以提交。否则第一次肯定是失败
现在去掉这个东西了
附议,我每次也要提交多次 😐
修改了一下,把插件移除了。现在应该不会有这个问题了。
测试一下
前端是挺有意思的,我最近这一年也在玩
确实,因为看起来赏心悦目
如果本身是 WordPress 网站扩展到小程序、app之类,就直接可以用 WordPress 做后端,只适合小型公司或者个人网站,优化好中型也ok。
wordpress 天生是为写 blog 设计的,用于其他方面感觉有点怪怪的,还不如自己重新写来的快。
自从它转型成cms后就不是了,不然当年也不会有那么多中小企业用。也不是所有东西“重写”就会更好,以前很多coder都因为嫌弃wp转cms后臃肿开始玩重写,只能说当作练习,重复造轮子不一定会更好,还有成本问题。
感谢分享关于运用 Vue 开发生物信息学数据库的体验。文章中提到的使用 Vue 框架在开发过程中能解决缓存问题的例子,感觉特别有启发。最近我在尝试解决相似的问题时,发现 https://sebbie.pl/tag/javascript/ 详细讨论了 JavaScript 框架在开发中的不同用法,也许对大家还挺有帮助。继续加油!