【无标题】

起凡Code闲聊

原文

以前的vue-cli是基于webpack,而webpack在开发阶段启动的速度是十分缓慢。原因是webpack会把一整个项目从入口开始(index.html)将涉及的所有的模块打包成一个js文件(图1)。

随着现代浏览器对js模块的支持,现在在浏览器中就可以使用exportimport关键字来生命模块和导入模块,这意味着浏览器现在不需要一次性获取所有的模块,可以在需要的时候去请求相应的模块(图2)。

并且当我们修改了代码时,vite只会更新代码涉及到模块进行热模块替换(HMR),使用我们在使用vite进行开发是每次更新都是十分的丝滑,很少出现整个页面都全部重新加载的情况。

需要注意的是,vite在打包时(npm run build)使用的是rollup。在开发时npm run dev使用的是esbuild。也就是说打包时会打包成几个大的js,而不是像开发时那样划分出很多模块。因为这样会增多浏览器和服务端的http请求,使得服务器压力增大。除此之外rollup在打包方面更加灵活有丰富的拓展插件。

图1 基于打包器的开发服务器

图2 基于ESM的开发服务器

笔记

1. Webpack 的痛点

  • 基于打包器的开发服务器(图1):

    • Webpack 在开发阶段会将整个项目从入口文件(如 index.html)开始,递归分析所有依赖,并将它们打包成一个或多个大的 JavaScript 文件。

    • 这种方式的缺点是:

      • 启动速度慢:项目越大,依赖越多,打包时间越长。

      • 热更新(HMR)效率低:即使只修改一个小文件,Webpack 也可能需要重新构建整个模块依赖图。

    • 对于大型项目,开发体验会变得非常卡顿。


2. Vite 的优势

  • 基于 ESM 的开发服务器(图2):

    • Vite 利用了现代浏览器对原生 ES 模块(ESM)的支持,直接在浏览器中按需加载模块。

    • 具体原理:

      • 开发阶段,Vite 不会预先打包所有模块,而是将代码拆分成多个小模块。

      • 当浏览器请求某个模块时,Vite 会动态编译并返回该模块。

      • 这种方式避免了 Webpack 的"全量打包"问题,极大地提升了开发服务器的启动速度。

    • 热更新(HMR)

      • Vite 只会更新修改的模块,而不是重新加载整个页面。

      • 这使得开发体验非常流畅,几乎感觉不到延迟。


3. Vite 的构建工具

  • 开发阶段(npm run dev

    • Vite 使用 esbuild 作为开发阶段的构建工具。

    • esbuild 是一个用 Go 语言编写的高性能 JavaScript 打包工具,速度极快,比传统的 JavaScript 打包工具(如 Webpack)快 10-100 倍。

    • esbuild 负责将模块编译成浏览器可以理解的 ESM 格式。

  • 生产阶段(npm run build

    • Vite 使用 Rollup 作为生产阶段的打包工具。

    • Rollup 是一个专注于打包 JavaScript 库的工具,支持 Tree Shaking(移除未使用的代码)和生成更小的包。

    • 在生产环境中,Vite 会将代码打包成几个大的 JavaScript 文件,而不是像开发阶段那样划分出很多小模块。

      • 这是因为:

        • 减少 HTTP 请求数量,降低服务器压力。

        • 生产环境不需要动态加载模块,打包成少量文件可以提高加载性能。


4. Vite 的设计哲学

  • 开发阶段

    • 利用现代浏览器的 ESM 支持,实现按需加载和快速启动。

    • 通过 esbuild 实现极快的模块编译。

  • 生产阶段

    • 使用 Rollup 进行高效打包,生成优化的生产代码。

    • 兼顾性能和开发体验。


5. Vite 与 Webpack 的对比

特性 Vite Webpack
启动速度 极快(按需加载) 慢(全量打包)
热更新(HMR) 高效(只更新修改的模块) 较慢(可能重新构建依赖图)
开发阶段构建工具 esbuild(极快) Webpack(较慢)
生产阶段构建工具 Rollup(高效打包) Webpack(功能强大但较慢)
模块加载方式 基于 ESM 的按需加载 全量打包
适用场景 现代前端项目(支持 Vue、React 等) 传统前端项目(兼容性更强)

6. 总结

  • Vite 的出现解决了 Webpack 在开发阶段的性能瓶颈,提供了更快的启动速度和更流畅的热更新体验。

  • 它充分利用了现代浏览器的特性(如 ESM),并结合 esbuild 和 Rollup 的优势,实现了开发和生产阶段的高效构建。

  • 对于现代前端项目(尤其是使用 Vue、React 等框架的项目),Vite 是一个非常值得尝试的构建工具。

安装

安装 vite

复制代码
npm i vite -D

在package.json中添加npm script

复制代码
{
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "preview": "vite preview"
  }
}

{

  "scripts":{
    "dev":"vite",
    "build":"vite build",
    "preview":"vite preview"
  },
    "dependencies": {
    "vite": "^6.2.2"
  }
}

1. scripts 部分

  • scripts 是 npm 的脚本命令配置,用于定义一些常用的命令。

  • 在你的配置中,定义了三个脚本:

    "dev": "vite"
    • 运行 npm run dev 时,会启动 Vite 的开发服务器。

    • 这个命令会:

      • 启动一个本地开发服务器。

      • 支持热更新(HMR),修改代码后会自动刷新页面。

      • 提供极快的启动速度,因为 Vite 不会预先打包所有模块,而是按需加载。

    "build": "vite build"
    • 运行 npm run build 时,会使用 Vite 进行生产构建。

    • 这个命令会:

      • 将项目打包成生产环境可用的静态文件(HTML、CSS、JS 等)。

      • 使用 Rollup 进行打包,生成优化的代码。

      • 支持 Tree Shaking(移除未使用的代码)和代码压缩。

    "preview": "vite preview"
    • 运行 npm run preview 时,会启动一个本地服务器来预览生产构建的结果。

    • 这个命令会:

      • 在本地启动一个静态文件服务器,预览 npm run build 生成的打包结果。

      • 用于在生产部署前检查构建结果是否正确。


2. devDependencies 部分

  • devDependencies 是开发依赖,表示这些包仅在开发环境中使用,不会被打包到生产环境中。

  • 在你的配置中,只有一个开发依赖:

    "vite": "^6.2.2"
    • 这是 Vite 的版本号。

相比于vue-cli你会发现vite的项目中,index.html不在public目录下,并且你可以看见index.html中直接引用了js/ts文件。原因是vite会把index.html视为你源码的一部分。默认index.html是整个项目的入口。

index.html

复制代码
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<script type="module">

  import {showCurrentTime} from './index.js'

  setInterval(() => document.querySelector(".time").innerHTML = showCurrentTime() + '', 1000)

</script>

<body>
<div>当前时间:<span class="time"></span></div>
</body>
</html>

一个简单的 HTML 文件,结合了 JavaScript 模块化(ESM)的功能,用于动态显示当前时间。以下是对代码的详细解释和改进建议:


1. HTML 结构

  • 这是一个标准的 HTML5 文档结构。

  • 关键部分:

    • <div>当前时间:<span class="time"></span></div>:用于显示当前时间,时间会动态更新到 <span> 中。

    • <script type="module">:表示这是一个 ES 模块脚本,支持 importexport


2. JavaScript 模块化

  • 代码中使用了 ES 模块化语法:

    复制代码
    import { showCurrentTime } from './index.js';
    • index.js 文件中导入 showCurrentTime 函数。

    • 需要确保 index.js 文件存在,并且导出了 showCurrentTime 函数。

  • setInterval 用于每秒更新一次时间:

    复制代码
    setInterval(() => document.querySelector(".time").innerHTML = showCurrentTime() + '', 1000);
    • 每秒调用一次 showCurrentTime 函数,并将返回值插入到 <span class="time"> 中。

    • + '' 的作用是将返回值强制转换为字符串(如果 showCurrentTime 返回的不是字符串)。


1. setInterval

  • setInterval 是一个 JavaScript 定时器函数,用于每隔指定的时间(以毫秒为单位)重复执行某个函数。

  • 语法:

    复制代码
    setInterval(callback, delay);
    • callback:要执行的函数。

    • delay:间隔时间(以毫秒为单位)。

  • 在代码中:

    复制代码
    setInterval(() => document.querySelector(".time").innerHTML = showCurrentTime() + '', 1000);
    • delay1000 毫秒(即 1 秒),所以每秒执行一次回调函数。

2. 箭头函数 () => { ... }

  • 这是一个箭头函数,用于定义回调函数。

  • 语法:

    复制代码
    () => { /* 函数体 */ }
  • 在代码中,箭头函数的内容是:

    复制代码
    document.querySelector(".time").innerHTML = showCurrentTime() + '';

3. document.querySelector(".time")

  • document.querySelector 是用于选择 DOM 元素的方法。

  • ".time" 是一个 CSS 选择器,表示选择类名为 time 的元素。

  • 在你的 HTML 中,对应的元素是:

    复制代码
    <span class="time"></span>

4. innerHTML

  • innerHTML 是 DOM 元素的属性,用于设置或获取元素内部的 HTML 内容。

  • 在你的代码中:

    复制代码
    document.querySelector(".time").innerHTML = showCurrentTime() + '';
    • .time 元素的内容设置为 showCurrentTime() 的返回值。

5. showCurrentTime()

  • 这是一个自定义函数,假设它返回当前时间的字符串表示。

  • 例如:

    复制代码
    function showCurrentTime() {
      const now = new Date();
      return now.toLocaleTimeString(); // 返回当前时间的字符串表示
    }
  • 返回值可能是 "14:35:22" 这样的格式。


6. + ''

  • + '' 的作用是将 showCurrentTime() 的返回值强制转换为字符串。

  • 这是一种常见的技巧,确保即使 showCurrentTime() 返回的不是字符串(例如数字或对象),也能正确显示。


7. 代码的执行流程

  • 每秒执行一次箭头函数:

    1. 调用 showCurrentTime() 获取当前时间。

    2. 将时间字符串赋值给 .time 元素的 innerHTML

    3. 页面中显示的时间会每秒更新一次。



index.js

复制代码
export const showCurrentTime=()=>{
    const date=new Date();
    return  `${date.getFullYear()}-${date.getMonth()+1}-${date.getDate()} ${date.getHours()}:${date.getMinutes()}:${date.getSeconds()}`
}

一个用于返回当前时间的函数 showCurrentTime,使用了 ES6 的模块化语法(export)和模板字符串。以下是对代码的详细解析和改进建议:


1. 代码解析

  • export

    • 使用 exportshowCurrentTime 函数导出,使其可以被其他模块导入和使用。

    • 例如:

      复制代码
      import { showCurrentTime } from './index.js';
      复制代码
  • const showCurrentTime = () => { ... }

    • 这是一个箭头函数,用于返回当前时间的格式化字符串。
  • new Date()

    • 创建一个 Date 对象,表示当前时间。
  • date.getFullYear()

    • 获取当前年份(例如 2023)。
  • date.getMonth() + 1

    • 获取当前月份(0 到 11),需要加 1 才能得到正确的月份(1 到 12)。
  • date.getDate()

    • 获取当前日期(1 到 31)。
  • date.getHours()

    • 获取当前小时(0 到 23)。
  • date.getMinutes()

    • 获取当前分钟(0 到 59)。
  • date.getSeconds()

    • 获取当前秒数(0 到 59)。
  • 模板字符串

    • 使用反引号(`````)【感叹号左边】和 ${} 语法,将变量嵌入字符串中。

    • 例如:

      复制代码
      export const showCurrentTime=()=>{
          const date=new Date();
          return  `${date.getFullYear()}-${date.getMonth()+1}-${date.getDate()} ${date.getHours()}:${date.getMinutes()}:${date.getSeconds()}`
      }
      复制代码
    • 返回的字符串格式为:YYYY-MM-DD HH:MM:SS

图3 目录结构

运行

执行 npm run dev 访问http://localhost:5173

图4 效果

相关推荐
yzhSWJ19 分钟前
vue设置自定义logo跟标题
前端·javascript·vue.js
vvilkim1 小时前
Vue.js 中的 Tree Shaking:优化你的应用性能
前端·javascript·vue.js
浪裡遊1 小时前
uniapp中的vue组件与组件使用差异
前端·vue.js·uni-app
Vg2 小时前
vue3的更新之插槽
vue.js
Vg2 小时前
vue3的更新之类式组件
vue.js
逆袭的小黄鸭2 小时前
仿 ElementPlus 组件库(五)—— Dropdown 组件实现
前端·vue.js
Vg2 小时前
vue3的更新之Fragment和Portal
vue.js
catino3 小时前
el-select下拉框,搜索时,若是匹配后的数据有且只有一条,则当失去焦点时,默认选中该条数据
javascript·vue.js·elementui
FanetheDivine3 小时前
不要在vue中使用jsx
vue.js·react.js
是加菲喵呀3 小时前
架构设计之pc和手机应用适配方案
前端·vue.js