CcbeanBlog CcbeanBlog
首页
  • 前端文章

    • JavaScript
    • HTML+CSS
    • Vue
    • React
  • 系列笔记

    • React使用学习
    • Vue2源码探究
  • Node文章

    • 基础
    • 问题
    • 框架
  • 系列笔记

    • 数据结构与算法
  • 构建工具文章

    • webpack
  • 系列笔记

    • Webpack5使用学习
  • MySQL
  • Linux
  • 网络
  • 小技巧
  • 杂记
  • 系列笔记

    • Protobuf Buffers
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

Ccbean

靡不有初,鲜克有终
首页
  • 前端文章

    • JavaScript
    • HTML+CSS
    • Vue
    • React
  • 系列笔记

    • React使用学习
    • Vue2源码探究
  • Node文章

    • 基础
    • 问题
    • 框架
  • 系列笔记

    • 数据结构与算法
  • 构建工具文章

    • webpack
  • 系列笔记

    • Webpack5使用学习
  • MySQL
  • Linux
  • 网络
  • 小技巧
  • 杂记
  • 系列笔记

    • Protobuf Buffers
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 邂逅Webpack
  • Webpack的配置和处理CSS资源
  • Webpack加载和处理其它资源
  • Webpak模块化原理
  • Webpack中的source-map
  • Webpack中的babel
  • Webpack中的DevServer和HMR
  • Webpack环境分离和代码分离
  • Webpack中的DLL、Terser和ScopeHoisting
  • Webpack中的TreeShaking以及其它优化
  • Webpack打包分析
  • Webpack自定义Loader
  • Webpack自定义Plugin
  • 分析React和Vue脚手架
  • Gulp的使用
  • Rollup的使用
  • Vite的使用
    • 认识Vite
    • 浏览器原生模块化支持
    • Vite的使用
    • Vite的功能
      • HMR
      • CSS的处理
      • CSS
      • CSS Module
      • CSS预处理器
      • PostCSS
      • 静态资源处理
      • JSON的处理
      • TypeScript的处理
      • Vue的处理
      • React的处理
      • 文件处理简析
      • Vite中的connect
    • Vite中的ESBuild
    • Vite的打包
    • 项目中使用Vite
  • Webpack5使用学习
ccbean
2022-07-03
目录

Vite的使用

# Vite的使用

# 认识Vite

Vite的定位是下一代前端开发与构建工具,能显著提升前端开发体验。

实际开发中,编写的代码往往不能被浏览器直接识别,如ES6、TypeScript、Vue等。

所以必须通过构建工具对代码进行转换、编译,如 webpack (opens new window)、Rollup (opens new window) 和 Parcel (opens new window) 等工具,它们极大地改善了前端开发者的开发体验。

但是随着项目越来越大,需要处理的JavaScript代码量呈指数级增长。

构建工具需要很长时间才能开启服务器,HMR也需要几秒钟才能在浏览器中反映出来,开发体验很差。

Vite 旨在利用生态系统中的新进展解决上述问题:浏览器开始原生支持 ES 模块,且越来越多 JavaScript 工具使用编译型语言编写。

  • 它主要由两部分组成:
    • 一个开发服务器,它基于 原生 ES 模块 (opens new window) 提供了 丰富的内建功能 (opens new window),如速度快到惊人的 模块热更新(HMR) (opens new window)。
    • 一套构建指令,它使用 Rollup (opens new window) 打包你的代码,并且它是预配置的,可输出用于生产环境的高度优化过的静态资源。

# 浏览器原生模块化支持

如果不借助其它工具,加载上百个模块的JS代码,对于浏览器请求是巨大的消耗。如加载Loadash,可能我们只使用其中几个方法,但是浏览器需要加载几百个文件,消耗巨大。

其次,代码可能是TypeScript、less、vue等,浏览器不能直接识别。

Vite解决了上面的这些问题。

代码如下:

// index.js
import { formatDate } from './utils/format.js'
import _ from '../node_modules/lodash-es/lodash.default.js';


console.log('Hello Vite');

console.log(formatDate());

console.log(_.join(['A', 'B', 'C']))

// format.js
export function formatDate() {
  return '2022-07-03';
}

在index.html中引入












 



<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <h1>Hello World</h1>
  <!-- 默认支持esmodule -->
  <script src="./index.js" type="module"></script>
</body>
</html>

使用LiveServer打开index.html,可以在浏览器中看到,JS代码可正常执行,浏览器默认值实际ESModule模块的。然而lodash模块加载了几百个JS文件。

# Vite的使用

通过下面命令安装Vite,便于学习构建工具。

npm i -D vite

注:官方文档中通过npm create vite@latest是将Vite作为脚手架来创建项目,不方便很多细节的理解。

此时修改lodash库的引入方式,手动引入Vite不会做任何的优化:

import { formatDate } from './utils/format.js'
// import _ from '../node_modules/lodash-es/lodash.default.js';
import _ from 'lodash-es';


console.log('Hello Vite');

console.log(formatDate());

console.log(_.join(['A', 'B', 'C']))

npx vite来启动项目,此时可以看到,Network中只关于Lodash只加载了lodash-es.js文件。

Vite的使用02

Vite将这个Lodash库做了合并,减少HTTP的请求次数,在打包阶段再通过TreeShaking进行进一步优化。

# Vite的功能

https://cn.vitejs.dev/guide/features.html

对非常基础的使用来说,使用 Vite 开发和使用一个静态文件服务器并没有太大区别。然而,Vite 还通过原生 ESM 导入提供了许多主要用于打包场景的增强功能。

文档中对各功能做了详细介绍,这里对开发中支持的常见文件类型做演练。

# HMR

Vite 提供了一套原生 ESM 的 HMR API (opens new window)。 具有 HMR 功能的框架可以利用该 API 提供即时、准确的更新,而无需重新加载页面或清除应用程序状态。

# CSS的处理

Vite不需要做任何配置即可加载CSS模块。

# CSS

base.css

body {
  background: red;
}

.title {
  font-size: 20px;
  user-select: none;
}

直接在入口文件中做引入:

import { formatDate } from './utils/format.js'
import _ from 'lodash-es';
import './css/base.css';

console.log('Hello Vite');

console.log(formatDate());

console.log(_.join(['A', 'B', 'C']))

可在浏览器中直接看到效果,CSS直接作为内联样式被引入到了HTML文件中。

# CSS Module

Vite支持CSS Module。

.red {
  color: green;
}

在入口文件中引入:

import classes from './css/hello.module.css';

document.getElementById('foo').className = classes.green;

# CSS预处理器

Vite 同时提供了对 .scss, .sass, .less, .styl 和 .stylus 文件的内置支持。

有如下代码:

main.less

@mainColor: white;
@maineSize: 30px;

.main {
  color: @mainColor;
  font-size: @maineSize;
}

footer.scss

.footer {
  color: gainsboro;
  span {
    background: purple;
  }
}

只需要安装相关的依赖,不需要做任何的配置:

npm i -D less sass

在入口文件中引入:

import './css/main.less';
import './css/footer.scss';

# PostCSS

Vite会自动应用PostCSS配置到已导入的CSS代码。

只需要安装依赖,并配置即可postcss.config.js即可。

安装依赖

npm i postcss postcss-preset-env -D

配置postcss.config.js

module.exports = {
  plugins: [
    require('postcss-preset-env')
  ]
};

在浏览器中,可以看到已经引入的CSS、Less、Scss、以及PostCSS对它们做的处理。

Vite的使用03

# 静态资源处理

静态资源的加载方式有多种。

import dovePng from './img/dove.png'; // 直接加载
import doveURL from './img/dove.png?url' // 显示加载资源为url
import doveString from './img/dove.png?raw' // 以字符串形式加载资源

console.log(dovePng); // /src/img/dove.png
console.log(doveURL); // /src/img/dove.png
console.log(doveString); // 二进制字符串

# JSON的处理

JSON 可以被直接导入 —— 同样支持具名导入

import dataJson, { count } from './json/data'

// json的处理
console.log(dataJson.hello, count);

# TypeScript的处理

Vite 天然支持引入 .ts 文件。

Vite 使用 esbuild (opens new window) 将 TypeScript 转译到 JavaScript,约是 tsc 速度的 20~30 倍,同时 HMR 更新反映到浏览器的时间小于 50ms。

math.ts

export function sum(num1: number, num2: number) {
  return num1 + num2;
}

入口文件中引入

import { sum } from './ts/math';

console.log(sum(20, 30));

# Vue的处理

默认情况下,Vite无法对Vue做处理,直接引入Vue代码会报错,需要使用@vitejs/plugin-vue (opens new window)插件。

23:24:38 [vite] Internal server error: Failed to parse source for import analysis because the content contains invalid JS syntax. Install @vitejs/plugin-vue to handle .vue files.

安装插件和Vue相关依赖:

npm i @vitejs/plugin-vue vue -D

配置vite.config.js

import vue from '@vitejs/plugin-vue'

module.exports = {
  plugins: [vue()]
}

App.vue

<template>
  <div id="app">
    <h2 class="title">{{message}}</h2>
  </div>
</template>

<script>
export default {
  data() {
    return {
      message: "Hello Vue ~"
    }
  }
}
</script>

<style scoped>
  .title {
    color: blue
  }
</style>

入口中使用:

import VueApp from './vue/App.vue';
import { createApp } from 'vue';

createApp(VueApp).mount("#vueapp");

# React的处理

默认情况下,Vite支持React代码,因为ESModule是原生支持React使用的JSX语法的。

安装React依赖

npm i react react-dom -D

创建App.jsx

import React, { Component } from "react";

class App extends Component {
  constructor(props) {
    super(props);

    this.state = {
      message: "Hello React",
    };
  }

  render() {
    return (
        <h2>{this.state.message}</h2>
    );
  }
}

export default App;

注意,入口文件也需要是JSX,否则会报错,index.jsx

import React from 'react';
// import ReactDom from 'react-dom';
import { createRoot }  from 'react-dom/client';
import ReactApp from './react/App.jsx';

// ReactDom.createRoot(<ReactApp/>, document.getElementById("app"));
// 新语法,焯!
createRoot(document.getElementById("reactapp")).render(<ReactApp/>);

# 文件处理简析

可以看到,Vite在返回文件时,直接返回了原文件类型,如ts、less、scss,但这些类型浏览器本身是不支持的。

那么为什么浏览器直接返回这些类型呢?

原因是,Vite提前将所有格式的文件,提前编译成了JS文件,然后Vite中的connect服务器,通过HTTP 304重定向到已经编译好的JS文件。获取到编译好的文件后,浏览器再进行解析。

Vite的使用04

Vite的使用05

Vite的使用06

可以看到,所有的文件都是JS文件,并不是原文件。

通过重定向,将请求修改为另一个请求,connect擅长处理这样的任务。

# Vite中的connect

Vite2后,Vite内部使用connect (opens new window)库来做服务。已经不再使用Koa了(Vite1使用的是Koa),至于为什么换成Connect,官方文档中做了相关说明

Since most of the logic should be done via plugin hooks instead of middlewares, the need for middlewares is greatly reduced. The internal server app is now a good old connect (opens new window) instance instead of Koa.

由于大多数逻辑应该通过插件钩子而不是中间件来完成,因此对中间件的需求大大减少。内部服务器应用现在是一个很好的旧版的connect实例,而不是Koa。

https://v2.vitejs.dev/guide/migration.html#for-plugin-authors

# Vite中的ESBuild

Vite 使用 esbuild (opens new window) 预构建依赖 (opens new window)。esbuild 使用 Go 编写,并且比以 JavaScript 编写的打包器预构建依赖快 10-100 倍。

esbuild的特点:

  • 超快的构建速度,且不需要缓存
  • 支持ES6和CommonJS模块化
  • 支持ES6的Tree Shaking
  • 支持Go、JavaScript的API (opens new window)
  • 支持TypeScript (opens new window)和 JSX (opens new window) 语法编译
  • 支持SourceMap (opens new window)
  • 支持代码压缩 (opens new window)
  • 支持扩展其它插件 (opens new window)

有了esbuild,就不需要再使用Babel对JS代码做处理。

esbuild为什么这么快?

  • esbuild使用Go语言编写,可以直接转换成机器码,而无需经过字节码。JavaScript代码需要先编译解析成AST —> 转成字节码 —> 优化字节码 —> 转成机器码。Go比JavaScript快很多。
  • esbuild可以充分利用CPU的多内核,esbuild会单独开一个进程,在这个进程中它会尽可能多地开启线程,多线程运行在CPU多个内核中,并行执行,效率更高,并且尽可能让CPU饱和运行。
  • esbuild的所有内容都是从零开始编写的,而不是使用第三方,所以从一开始就考虑到了各种性能问题。

# Vite的打包

Vite打包也很简单,只需运行 vite build 命令。默认情况下,它使用 <root>/index.html 作为其构建入口点,并生成能够静态部署的应用程序包。

Vite使用Rollup做打包,因为Rollup 在应用打包方面更加成熟和灵活。

为什么生产环境仍需打包? (opens new window)

为何不用 ESBuild 打包? (opens new window)

打包:

npx vite build

查看效果:

npx vite preview

vite preview 命令会在本地启动一个静态 Web 服务器,将 dist 文件夹运行在 http://localhost:4173。这样在本地环境下查看该构建产物是否正常可用就方便多了。

可以将这些命令配置到scripts中

"scripts": {
  "dev": "vite",
  "build": "vite build",
  "preview": "vite preview"
},

# 项目中使用Vite

上面是从零开始使用Vite,相当于是Webpack或Rollup的打包工具。

但是实际项目中,并不需要从零配置,直接使用Vite的脚手架工具即可:

npm init vite@latest

npm-init (opens new window)本质上操作如下:

  • 执行npm exec crrete-vite@latest,create-vite脚手架通过npm-exec (opens new window)解析,它会执行本地或者远程的npm包命令,这样就不需要本地安装脚手架。

  • 当然,也可以本地安装npm i -g create-vite@latest,和本地安装create-react-app一样。使用npm init react-app react-demo也无需本地安装React脚手架来安装创建React应用。npm init会自动加上create-前缀,无需手动添加。

编辑 (opens new window)
上次更新: 2022/07/15, 21:43:17
Rollup的使用

← Rollup的使用

最近更新
01
阅读精通正则表达式总结
09-29
02
项目搭建规范的配置
07-15
03
Rollup的使用
06-30
更多文章>
Theme by Vdoing | Copyright © 2018-2023 Ccbeango
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式