前端技术点滴整理-1

一、ETag相关

ETag(Entity Tag)是 HTTP 1.1 协议中的一部分,用于确定浏览器缓存的一个资源在服务器上是否已经被修改。它是一个可以分配给特定版本和实例的资源的标识符,通常是一个哈希值。服务器可以在发送资源时,将该资源的 ETag 一起发送给客户端。然后客户端在再次请求该资源时,会将此 ETag 值一起发送给服务器,服务器根据 ETag 判断资源是否有变动。

ETag 的工作原理是这样的:

  1. 浏览器第一次请求一个资源(比如一个图片),服务器在返回这个资源的同时,也把这个资源的 ETag 值(通常是一个哈希值)在响应头中一并返回,浏览器收到资源后,会将这个资源及其 ETag 值缓存起来。
  2. 当浏览器再次请求这个资源时,会将之前保存的 ETag 值放在请求头中一并发送给服务器。服务器会比对请求头中的 ETag 值和服务器上该资源的当前 ETag 值是否一致,以此来判断资源是否有变动。
  3. 如果 ETag 没变,说明资源没有变动,服务器会返回 304 状态码,告诉浏览器直接使用本地缓存即可。如果 ETag 变了,说明资源已经被改动过,服务器会返回新的资源内容和新的 ETag 值。

使用 ETag 的方法如下:

  1. 在服务器端,可以在响应头中添加 ETag,例如 ETag: "12345"
  2. 在客户端,可以在请求头中添加 If-None-Match,例如 If-None-Match: "12345"

ETag 可以有效地节省带宽和服务器资源,因为当资源没有变化时,服务器可以不用返回资源内容,只需要返回一个 304 状态码即可。同时,ETag 也有助于防止同时写入("mid-air"写入)。这是当多个用户同时尝试更改同一资源时可能会发生的问题。通过将 ETag 值放入 If-Match 请求头中,可以让服务器只在 ETag 值匹配时才执行操作。如果 ETag 值不匹配,说明资源已经被其他用户更改,服务器可以返回 412(Precondition Failed)状态码,拒绝执行操作。

二、JS引用方式

type=Module和UMD(Universal Module Definition)是JavaScript模块加载方式的两种不同策略。它们的主要区别在于使用方式和兼容性。

当在<script>标签中使用type="module"时,该脚本将被当作ES6模块。这意味着在这样的脚本中可以使用import和export语法。此外,这些脚本默认是延迟加载的,即它们会等到所有HTML文档都被完全加载和解析后再运行。

ES6模块是现代浏览器支持的原生模块系统。然而,老版本的浏览器并不支持ES6模块,因此如果要支持老版本浏览器,可能需要使用一些构建工具,如Babel和webpack等,将ES6模块转换为其他类型的模块。

UMD(Universal Module Definition)

UMD是一种兼容CommonJS和AMD两种规范的模块定义方式。这种方式的主要目的是使一个模块能够在各种环境中运行,包括浏览器环境和服务器环境。

UMD模块可以通过<script>标签直接在浏览器中引入,并且不需要特殊的属性。然而,由于UMD模块需要兼容多种环境,所以它的代码通常会比其他类型的模块更复杂。

总结起来,type=module更适合于现代浏览器环境,而UMD则旨在提供一种在各种环境中都能运行的通用解决方案。

三、VUE3 国际化实现方案

Vue3的国际化实现方案主要使用的是vue-i18n插件。以下是一个示例:

首先,安装vue-i18n插件:

npm install vue-i18n@next

然后,创建一个i18n.js文件,用于配置国际化选项:

import { createI18n } from 'vue-i18n'

const messages = {
  en: {
    message: {
      hello: 'Hello World'
    }
  },
  zh: {
    message: {
      hello: '你好,世界'
    }
  }
}

const i18n = createI18n({
  locale: 'en', // 设置默认语言
  messages,
})

export default i18n

在你的main.js中,引入这个配置并挂载到Vue实例上:

import { createApp } from 'vue'
import App from './App.vue'
import i18n from './i18n'

createApp(App).use(i18n).mount('#app')

在你的组件中,你可以使用$t方法来获取国际化的消息:

<template>
  <p>{{ $t('message.hello') }}</p>
</template>

你也可以在任何地方动态切换语言:

this.$i18n.locale = 'zh'

四、VUE实例的生命周期管理

Vue实例的生命周期管理是通过一系的生命周期钩子函数来实现的,这些钩子函数在Vue实例的不同阶段被调用,可以让开发者在恰当的时机添加自己的代码。

以下是Vue实例的生命周期钩子函数:

  1. beforeCreate:在实例初始化之后,数据观测 (data observer) 和 event/watcher 事件配置之前被调用。

  2. created:在实例创建完成后被立即调用。在这一步,实例已完成以下的配置:数据观测(data observer),属性和方法的运算,watch/event事件回调。然而,挂载阶段还没开始,$el属性目前不可见。

  3. beforeMount:在挂载开始之前被调用,相关的render函数首次被调用。

  4. mounted:在el被新创建的vm.el替换,并挂载到实例上去之后调用该钩子。如果root实例挂载了一个文档内的元素,当mounted被调用时vm.el也在文档内。

  5. beforeUpdate:数据更新时调用,发生在虚拟DOM重新渲染和打补丁之前。可以在这个钩子中进一步改变状态,这不会触发附加的重渲染过程。

  6. updated:由于数据更改导致的虚拟DOM重新渲染和打补丁,在这之后会调用该钩子。

  7. beforeDestroy:实例销毁之前调用。在这一步,实例仍然完全可用。

  8. destroyed:Vue实例销毁后调用。调用后,所有的事件监听器会被移除,所有的子实例也会被销毁。

以上就是Vue实例的生命周期管理,通过这些钩子函数,我们可以更好地控制和管理Vue实例的状态。

五、Vite和Webpack最核心的区别和不同

Vite和Webpack是两种用于现代前端开发的构建工具,它们在许多方面有所不同,但最关键的区别主要在于以下几点:

  1. 构建速度:Vite使用了ESBuild,比Webpack更快。ESBuild采用Go语言编写,利用多核并行转译,大大提高了打包速度。而Webpack的构建速度相对较慢。

  2. 开发模式:Vite在开发模式下,采用原生ESM模块,按需编译,无需等待整个应用编译完成,从而实现了极快的热更新。而Webpack在开发模式下,需要对所有模块进行编译打包,然后才能进行热更新。

  3. 插件系统:Vite的插件系统更简单,更易于使用。Vite插件基于rollup插件设计,对于开发者来说,使用起来更加方便。而Webpack的插件系统相对复杂,需要更多的学习和理解。

  4. 配置:Vite的配置相对简单,更加易于理解和使用。而Webpack的配置更加复杂。

  5. 兼容性:Webpack更老,因此对旧的浏览器和语法有更好的支持。Vite则需要现代浏览器支持原生ESM。

  6. 体积:相比于Webpack,Vite的体积更小,更轻量。

  7. 默认支持:Vite默认支持Vue.js,而Webpack则需要配置。

在选择哪个工具时,需要考虑项目的具体需求,如构建速度、兼容性、易用性等因素。

六、关于ESM

ESM是ES Modules的缩写,它是JavaScript的官方模块系统,是ECMAScript 6(也称为ES2015)引入的一种新的模块化方式。

在ESM中,你可以使用import和export关键字来导入和导出函数、对象或值。这种模块化方式可以帮助你更好地组织和共享代码

ESM与之前的CommonJS模块系统(在Node.js中使用)有一些关键的区别,包括:

  1. ESM是静态的,这意味着你不能在运行时改变或创建模块。所有的导入和导出都需要在顶级范围(非函数内)进行,并且必须在编译时确定。这使得静态分析和优化(如tree shaking)成为可能。

  2. ESM支持异步加载和动态加载。

  3. ESM支持循环依赖和默认导出。

由于ESM是JavaScript语言的标准组成部分,因此它在现代浏览器中得到了广泛的支持,也被许多现代JavaScript工具(如Babel,Webpack,Rollup,Vite等)所支持。