首页IT科技vis包括的内容有哪些(对vite的简单了解)

vis包括的内容有哪些(对vite的简单了解)

时间2025-05-02 06:48:06分类IT科技浏览3665
导读:一.什么是构建工具 浏览器只认识html,css,js。...

一.什么是构建工具

浏览器只认识html,css,js           。

构建工具做了那些:

1.模块化开发支持:支持直接从node_modules里引入代码+多种模块化支持

2. 处理代码兼容性:比如Babel语法降级           ,less,ts语法转换(不是构建工具做                 ,构建工具将这些语法对应的处理工具集成进来自动化处理

3.提高项目性能:压缩文件      ,代码分割

4.优化开发体验:

构建工具会自动监听文件的变化     ,当文件变化以后自动帮你调用对应的集成工具进行重新打包                 ,然后再次浏览器重新运行(整个过程叫做热更新            , hot )

开发服务器:跨域的问题     ,用vue-cli react-cli 解决跨域的问题(dev代理)

总结:构建工具让我们可以不用每次关心代码在浏览器重如何运行

二.vite介绍

(一)什么是vite

vite 是一种新型的前端构建工具                ,能够显著的提升前端开发者的体验                 。它主要有俩部分组成:

一个开发服务器:它基于原生的es模块            ,提供了丰富的内建功能,如速度快到惊人的模块热更新HMR.

一套构建指令:使用Rollup打包代码                ,并且它是预构建的                 ,可输出用于生产环境的高度优化过的静态资源      。

vite旨在提供开箱即用的配置,但同时它也提供插件API和JavaSccript API 带来高度的可扩展性并且有完整的类型支持     。

(二)为什么选vite?

主要因为俩方面缓慢的服务器启动和缓慢的更新                 。具体查看官网

总结:

vite解决打包问题:vite只启动一台静态页面的服务器           ,对文件代码不打包                 ,服务器会根据客户端的请求加载不同的模块处理      ,实现真正的按需加载            。 vite解决热更新问题:Vite采用立即编译当前修改文件的办法           ,同时vite还会使用缓存机制(http缓存=>vite内置缓存)                 ,加载更新后的文件内容      ,所以     ,vite具有了快速冷启动           、按需编译                 、模块热更新等优良特质(Vite 同时利用 HTTP 头来加速整个页面的重新加载(再次让浏览器为我们做更多事情):源码模块的请求会根据 304 Not Modified 进行协商缓存                 ,而依赖模块请求则会通过 Cache-Control: max-age=31536000,immutable 进行强缓存            ,因此一旦被缓存它们将不需要再次请求     。) vite基于缓存的热更新     ,vue-cli基于webpack的热更新

三.vite与webapck比较

1.vite启动时间快:

webpack先打包                ,再启动开发服务器            ,请求服务器时直接给予打包后的结果

vite 直接启动开发服务器(根据服务器支持 es module,把压力给了服务器)                ,请求哪个模块再对哪个模块进行实时编译

2. 机制不一样:

原理:webpack:逐级递归识别依赖                 ,构建依赖图谱->转化AST语法树->处理代码->转换为浏览器可识别的代码

vite:基于浏览器原生 ES module,利用浏览器解析 imports           ,服务器端按需编译返回

3.生态不及webpack                 ,加载器      、插件不够丰富

4.生产环境esbuild构建对于css和代码分割不够友好

静态资源图片压缩,还有文件打包做回滚      ,涉及到babel-plugins就有问题

5.vite 打包实际就是 rollup打包

四.理解vite脚手架和vite的区别

官网搭建vite:

yarn create vite

其实是全局安装一个create-vite(vite的脚手架)           ,而不是vite(vite 就是一个简单的构建工具)                。

create-vite 与vite的关系是?——》create-vite内置了vite            。

五. 依赖预构建

 (一) 依赖预构建的目的

为了兼容 CommonJS 和 UMD(开发阶段中                 ,Vite 的开发服务器将所有代码视为原生 ES 模块。因此      ,Vite 必须先将作为 CommonJS 或 UMD 发布的依赖项转换为 ESM);

以及提升性能(如:lodash-es 有超过 600 个内置模块!浏览器会同时发出600多个http请求     ,尽管服务器端处理这些请求的时候是没有问题的                 ,但是大量的请求会在浏览器端造成网络拥塞            ,导致页面的加载速度相当的慢     ,通过vite预构建                ,加载成一个模块            ,浏览器只要做一次http请求就够了)

(二)自动依赖搜寻

        默认情况下,在模块预构建完成以后                ,对构建好的模块会进行缓存;如果没有找到相应的缓存                 ,Vite 将抓取你的源码,并自动寻找引入的依赖项           ,并将这些依赖项作为预构建包的入口点                。预构建通过 esbuild 执行                 ,所以它通常非常快                 。

        在服务器已经启动之后      ,如果遇到一个新的依赖关系导入           ,而这个依赖关系还没有在缓存中                 ,Vite 将重新运行依赖构建进程并重新加载页面。

(三)需要预构建的模块

1.  只有 bare import 会执行依赖预构建

 bare import:一般是 npm 安装的模块      ,是第三方的模块     ,不是我们自己写的代码                 ,一般情况下是不会被修改的            ,因此对这部分的模块提前执行构建并且进行缓存     ,有利于提升性能           。 monorepo下的模块不会被预构建                ,部分模块虽然是 bare import            ,但这些模块也是开发者自己写的,不是第三方模块                ,因此 Vite 没有对该部分的模块执行预构建                 。 // vue 是 bare import import vue from "vue" import xxx from "vue/xxx" // 用路径去访问的模块                 ,不是 bare import import foo from "./foo.ts" import foo1 from "/foo.ts"

 2. vite的判断

实际路径在 node_modules 的模块会被预构建,这是第三方模块 实际路径不在 node_modules 的模块           ,证明该模块是通过文件链接                 ,链接到 node_modules 内的(monorepo 的实现方式)      ,是开发者自己写的代码           ,不执行预构建

(四)缓存

vite缓存分2部分:

A. 文件系统缓存:Vite 会将预构建的依赖缓存到 node_modules/.vite.

package.json 中的 dependencies 列表 包管理器的 lockfile                 ,例如 package-lock.json, yarn.lock      ,或者 pnpm-lock.yaml 可能在 vite.config.js 相关字段中配置过的 

以上这个文件发生变化     ,vite就会重新执行预构建      。你想要强制 Vite 重新构建依赖                 ,你可以用 --force 命令行选项启动开发服务器            ,或者手动删除 node_modules/.vite 目录           。 

"scripts": {

    "dev": "vite --force"

  },

B. 浏览器缓存:解析后的依赖请求会以 HTTP 头 max-age=31536000,immutable 强缓存     ,以提高在开发时的页面重载性能                 。一旦被缓存                ,这些请求将永远不会再到达开发服务器      。 

如果安装了不同的版本 通过本地编辑来调试依赖项

以上2种方式浏览器缓存则失效     。 

(五)过程

首先vite会找到对应的依赖            ,然后调用esbuild( 对js 语法进行处理的一个库)将其他规范的代码(如common.js 规范的:module.exports形式导出的)转换成esmodule规范,然后放到当前目录下的/node_modules/.vite/deps(Vite 会将预构建的依赖缓存到 node_modules/.vite),同时对esmodule规范的各个模块进行统一集成                 。

他解决了3个问题:

1. 不同的第三方包会有不同的导出格式(这个是vite没法约束人家的事情)

如:common.js 规范 

2. 对路径的处理上可以直接使用.vite/deps                ,方便路径重写(解决路径冲突问题)

3. 叫做网络多包传输性能问题(这也是原生esmodule规范不敢支持node_modules的原因之一)                 ,有了依赖预构建以后无论他有多少的额外exports 和import,vite都会尽可能将他们进行集成最后只生产一个或者几个模块

如安装lodash-es,引入:import _ from loadsh-es

lodash-es可以看到引入很多其他方的依赖

 在vite 的处理下           ,在浏览器中就可以看到 都转成了函数方法

 如果在vite.config.js 配置文件加

export default {

    exclude:["loadsh-es"],//当遇到loadsh-es这个依赖的时候                 ,不进行依赖预构建

}

这个时候看到的      ,就跟node_modules /lodash-es文件一样,引入很多的依赖包            。

 所以vite 依赖预构建很好的解决引入第三方包有多依赖的情况     。

六 环境变量的处理

(一)环境变量理解

会根据当前的代码环境产生值的变化的变量就叫环境变量                。

代码环境:

开发环境.env.development

测试环境 .env.staging

生产坏境 .env.production

vite中使用环境变量:import.meta.env

import.meta.env.Mode : 获取环境(如development 开发环境           ,production 生产环境)

import.meta.env.BASE_URL:  部署用的基本url

import.meta.env.PROD :PROP是production的缩写                 ,表示应用是否允许在生产环境中

import.meta.env.dev:表示应用是否允许在开发环境中

七 模块热重载

interface ImportMeta { readonly hot?: { //data 表示更新模块的不同实例之间持久化:也就是它可以用于将信息从模块的前一个版本传递到下一个版本 readonly data: any //accept:表示在模块移除的时候执行的一些回调 accept(): void accept(cb: (mod: any) => void): void accept(dep: string, cb: (mod: any) => void): void accept(deps: string[], cb: (mods: any[]) => void): void //prune:表示在模块移除的时候,执行这个回调 prune(cb: () => void): void //dispose:可以接受自身的模块或者是一个期望被其他模块接受的模块      ,可以使用dispose来清除任何 尤其更新副本产生的持久的副作用 dispose(cb: (data: any) => void): void //decline:表示模块不可热更新     ,如果在传播HMR更新时                 ,遇到这个模块            ,浏览器应该执行完全的重新加载 decline(): void //invalidate:这个方法现在执行的时候     ,只是重新加载页面 invalidate(): void // on:表示可以监听自定义的HMR on(event: string, cb: (...args: any[]) => void): void } }

八 vite 功能

(一)vite+vue3 支持JSX和ts

Vue 3 JSX 支持:@vitejs/plugin-vue-jsx

操作如:输入命令: npm init vite vite-vue3 

vite.config.ts用于存放vite的配置的地方            。目前只有vue3官方提供的plugin。

import { defineConfig } from vite

import vue from @vitejs/plugin-vue

// https://vitejs.dev/config/

export default defineConfig({

  plugins: [vue()]

})

这里plugin-vue支持app.vue,但不支持app.jsx     、app.tsx.如果需要                ,需要安装vue3官方提供的一个插件plugin-vue-jsx                。

npm install -D @vitejs/plugin-vue-jsx

修改vite.config.ts引入

import { defineConfig } from vite

import vue from @vitejs/plugin-vue

import vueJsx from @vitejs/plugin-vue-jsx

// https://vitejs.dev/config/

export default defineConfig({

    plugins: [vue(), vueJsx()]

})

删除src\App.vue            ,新建src\App.jsx (ts的话,就把App.ts)

import { defineComponent } from vue

export default defineComponent({

    setup() {

        return () => {

            return <div>Hello Vue3 jsx</div>

        }

    }

})

把main.ts 改成main.jsx(ts:main.ts)

import { createApp } from vue

import ./style.css

import App from ./App

createApp(App).mount(#app)

运行可以看到

 (二)Vite中使用CSS

Vite支持原生最新的CSS——css variable 集成了postcss                 。 @import alias css-modules css pre-processors

 (1)Vite支持原生最新的CSS——css variable

style.css

.color-red {

    color: red;

}

App.jsx 

import { defineComponent } from vue

export default defineComponent({

    setup() {

        return () => {

            return <div className=color-red>Hello Vue3 jsx</div>

        }

    }

})

css variables让我们可以在CSS中使用变量(变量名前一定要有两个-                ,否则不生效;然后使用var()方式来获取变量值),变量可以被覆盖                 ,如果在低层级重新赋值则会覆盖样式。

style.css 

:root {

    --main-bg-color: #ccc;

}

.color-red {

    color:  var(--main-bg-color);

}

  (2)集成了postcss

Postcss是一个使用js插件来转换样式的工具,Postcss 的插件会检查你的css           。

postcss 一种对css编译的工具           ,类似babel对js的处理                 ,

(3) @import alias 别名

为防止出现无数的路径指引长度                 。可以配置修改vite.config.ts如下:

import { defineConfig } from vite

import vue from @vitejs/plugin-vue

import vueJsx from @vitejs/plugin-vue-jsx

// https://vitejs.dev/config/

export default defineConfig({

    plugins: [vue(), vueJsx()],

    resolve: {

        alias: {

            @: /src,

            @assets: /src/assets,

        },

    },

})

 assets/css/index.css

.fontSize {

    font-size: 30px;

}

App.jsx

import { defineComponent } from vue

import @assets/css/index.css

export default defineComponent({

    setup() {

        return () => {

            return <div className=color-red fontSize>Hello Vue3 jsx</div>

        }

    }

})

(4)CSS Modules

任何以 .module.css 为后缀名的 CSS 文件都被认为是一个 CSS modules 文件      。

css modules优势

解决全局命名冲突问题 css modules只关心组件本身 命名唯一 模块化 可以使用composes来引入自身模块中的样式以及另一个模块的样式 解决嵌套层次过深的问题 使用扁平化的类名

导入这样的文件会返回一个相应的模块对象:

 assets/css/example.module.css

.fontWeight {

    font-weight: 300;

}

App.jsx 

import { defineComponent } from vue

import @assets/css/index.css

import classes from @assets/css/example.module.css

export default defineComponent({

    setup() {

        return () => {

            return <div className={`color-red fontSize ${classes.fontWeight}`}>Hello Vue3 jsx</div>

        }

    }

})

如果 css.modules.localsConvention 设置开启了 camelCase 格式变量名转换(例如 localsConvention: camelCaseOnly)      ,你还可以使用按名导入           。 

修改vite.config.ts

import { defineConfig } from vite

import vue from @vitejs/plugin-vue

import vueJsx from @vitejs/plugin-vue-jsx

// https://vitejs.dev/config/

export default defineConfig({

   ...

    css:{

        modules:{

            // 小驼峰

            localsConvention:camelCase

        }

    }

})

App.jsx 

import { defineComponent } from vue

import @assets/css/index.css

import { fontWeight } from @assets/css/example.module.css

export default defineComponent({

    setup() {

        return () => {

            return <div className={`color-red fontSize ${fontWeight}`}>Hello Vue3 jsx</div>

        }

    }

})

(5)CSS 预处理器

Vite 也同时提供了对 .scss, .sass, .less, .styl 和 .stylus 文件的内置支持                 。没有必要为它们安装特定的 Vite 插件           ,但必须安装相应的预处理器依赖:

npm install -D sass  npm install -D less

 (三)vite中使用Web Worker

        javaScript语言采用的事单线程编程                 ,也就是说所有的任务只能在一个线程上完成      ,一次只能做一件事     ,那前面的任务没做完                 ,后面的任务只能等着      。那随着完美电脑计算能力的增强            ,尤其是多核的cpu的出现     ,单线程带来很大的不便                ,无法充分发挥计算机的计算能力     。

        那 web worker 的作用就是JavaScript创造的多线程环境            ,它是在html5出现的时候随机推出来的,它允许主线程来创建 worker 线程                ,将一些任务分配给后者来运行                 。在主线程运行的同时                 ,worker线程在后台运行 ,俩者互不干扰           ,等到worker线程完成计算任务                  ,再把结果返回给主线程            。

这样做的好处就是一些计算密集型或者是高延迟的任务被worker线程负担了      ,而主线程就会很流畅     。比如说主线程通常会负责ui的交互           ,不会阻塞或者是拖慢                 ,那worker线程一旦创建成功就会始终运行      ,不会被主线程的活动所打断(比如像用户点击按钮啊     ,提交表单啊等等)这样就有利于随时响应我们主线程的通行                。

纯js下使用 web worker线程

const worker = new  Worker(./worker.js)

vite中使用 web worker线程

import MyWorker from ./worker?worker

const worker = new MyWorker()

如下案例:

worker.js

var i = 0; function timeCount() { i++; postMessage(i); setTimeout(timeCount, 1000); } timeCount();

 main.js

//纯js const worker = new Worker(./worker.js) worker.onmessage = function (ev) { console.log(worker, ev.data) } // vite中使用 web worker线程 import MyWorker from ./worker?worker const worker = new MyWorker() worker.onmessage = function (ev) { console.log(worker, ev.data) }

 (四)vite中使用WebAssembly

WebAssembly是一个可移植                 ,体积小            ,加载快并且兼容Web的全新技术     ,是大前端的重要内容            。他可以实现JS在宿主环境中(比如在浏览器里边                ,直接的调用c c++等程序)            ,前端的性能从此有了更好的解决方案。大概流程如下

1.  编译一个.wasm 环境 

2. vite 中调用.wasm

import init from ./example.wasm

init().then((exports) => {

  exports.test()

})

 (五)vite中导入json及GLOB

json文件直接导入

// 导入整个对象 import json from ./example.json // 对一个根字段使用具名导入 —— 有效帮助 treeshaking! import { field } from ./example.json

 Glob 导入

Vite 支持使用特殊的 import.meta.glob 函数从文件系统导入多个模块:

在glob文件下创建json/js等文件

const modules = import.meta.glob(./glob/*);

console.log(module)

//打印出来内容如

 modules = {

  ./glob/foo.json: () => import(./glob/foo.json),

  ./dir/bar.js: () => import(./glob/bar.js)

}

九 浏览器兼容性

支持原生ESM script标签                 、支持原生ESM 动态导入                。

import { defineConfig } from vite

import vue from @vitejs/plugin-vue

// https://vitejs.dev/config/

export default defineConfig({

    plugins: [vue()],

    build:{

     target:es2015// 这样的话,打包的文件就可以支持es6文件

    }

})

低版本的浏览器兼容                ,需要安装插件

npm i @vitejs/plugin-legacy -D

vite.config.ts 文件填写配置 

import { defineConfig } from vite

import vue from @vitejs/plugin-vue

import legacyPlugin from @vitejs/plugin-legacy

// https://vitejs.dev/config/

export default defineConfig({

    plugins: [

        vue(),

        legacyPlugin({

            targets:[chrome 52],  // 需要兼容的目标列表                 ,可以设置多个

            additionalLegacyPolyfills:[regenerator-runtime/runtime] // 面向IE11时需要此插件

        })

    ]

})

打包            、运行到浏览器                 。

新版本浏览器运行正常!旧版本浏览器运行正常!

注意:@vitejs/plugin-legacy不能使vue3支持ie11

十 服务端渲染SSR-vue3

创建项目vite-ssr-vue3 

操作如:输入命令: npm init vite vite-ssr-vue3 

编写一个简单的vue3项目

页面创建:src/pages 文件下创建 home.vue 和about.vue

如:home.vue

<template> <div>Home</div> </template> <script> export default { } </script> <style> </style>

App.vue

<template> <div> <router-link to="/">Home</router-link> <router-link to="/about">About</router-link> <router-view></router-view> </div> </template> <script> export default { } </script> <style> </style>

路由创建:src/router/index,js

import { createRouter as _createRouter, createWebHistory } from vue-router // 载入pages里面定义的所有的组件 const pages = import.meta.glob(../pages/*.vue); // 获取路由 const routes = Object.keys(pages).map(path => { const name = path.match(/\.\.\/pages(.*)\.vue$/)[1].toLowerCase(); return { path: name === /home ? / : name, component: pages[path],//()=>import(../pages/*.vue) } }) export function createRouter() { return _createRouter({ history: createWebHistory(), routes }) }

引入路由:main.js

import { createApp } from vue import ./style.css import App from ./App.vue import { createRouter } from ./router/index.js createApp(App).use(createRouter()).mount(#app)

运行

转成服务端渲染ssr--开发环境

创建node服务:

安装 npm i express -D

创建vite-ssr-vue3/server.js 

const fs = require(fs) const path = require(path) const express = require(express) const { createServer: createViteServer } = require(vite) async function createServer() { const app = express() // 以中间件模式创建 Vite 应用,这将禁用 Vite 自身的 HTML 服务逻辑 // 并让上级服务器接管控制 // // 如果你想使用 Vite 自己的 HTML 服务逻辑(将 Vite 作为 // 一个开发中间件来使用)           ,那么这里请用 html const vite = await createViteServer({ server: { middlewareMode: ssr } }) // 使用 vite 的 Connect 实例作为中间件 app.use(vite.middlewares) app.use(*, async (req, res) => { //现 * 处理程序供给服务端渲染的 HTM const url = req.originalUrl try { // 1. 读取 index.html let template = fs.readFileSync( path.resolve(__dirname, index.html), utf-8 ) // 2. 应用 Vite HTML 转换。这将会注入 Vite HMR 客户端                 , // 同时也会从 Vite 插件应用 HTML 转换           。 // 例如:@vitejs/plugin-react-refresh 中的 global preambles template = await vite.transformIndexHtml(url, template) // 3. 加载服务器入口                 。vite.ssrLoadModule 将自动转换 // 你的 ESM 源码使之可以在 Node.js 中运行!无需打包 // 并提供类似 HMR 的根据情况随时失效      。 const { render } = await vite.ssrLoadModule(/src/entry-server.js) // 4. 渲染应用的 HTML           。这假设 entry-server.js 导出的 `render` // 函数调用了适当的 SSR 框架 API                 。 // 例如 ReactDOMServer.renderToString() const appHtml = await render(url) // 5. 注入渲染后的应用程序 HTML 到模板中      。 const html = template.replace(`<!--ssr-outlet-->`, appHtml) // 6. 返回渲染后的 HTML     。 res.status(200).set({ Content-Type: text/html }).end(html) } catch (e) { // 如果捕获到了一个错误      ,让 Vite 来修复该堆栈           ,这样它就可以映射回 // 你的实际源码中                 。 vite.ssrFixStacktrace(e) console.error(e) res.status(500).end(e.message) } }) app.listen(3000) } createServer()

模块化的转化:src/entry-server.js   

import {createApp} from ./main import { renderToString} from vue/server-renderer export async function render(url){ const {app,router} = createApp(); router.push(url); await render.isReady(); const ctx = {}; const html = await renderToString(app,ctx); return html; }

main.js

import { createSSRApp} from vue import ./style.css import App from ./App.vue import { createRouter } from ./router/index.js export function createApp(){ const app = createSSRApp(App); const router = createRouter(); app.use(router); return { app, router } }

在html增加<!--ssr-outlet--> 为了                 ,替换内容

改造路由::src/router/index,js

import { createRouter as _createRouter, createWebHistory, createMemoryHistory } from vue-router // 载入pages里面定义的所有的组件 const pages = import.meta.glob(../pages/*.vue); // 获取路由 const routes = Object.keys(pages).map(path => { const name = path.match(/\.\.\/pages(.*)\.vue$/)[1].toLowerCase(); return { path: name === /home ? / : name, component: pages[path],//()=>import(../pages/*.vue) } }) export function createRouter() { return _createRouter({ history: import.meta.env.SSR ? createMemoryHistory() : createWebHistory(), routes }) }

 运行:

 html 的内容都显示出来      ,这样做搜索引擎的话容易了            。

将来我们爬虫     ,爬取我们的页面的时候是可以爬取到相关的内容     。服务端渲染的一个最大的意义所在                。

十一 参考

Vite学习指南

Vite世界指南(带你从0到1深入学习 vite)

封装dotenv库实现类似Vite加载环境变量的行为

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
国产名牌t恤衫都有什么名(国产ChatGPT命名图鉴) seo网站优化排名推广(seo网站优化推广整站排名教程)