阅读 174

Vite 从入门到精通 | 高级应用

Vite 从入门到精通 | 高级应用

本文总结 Vite 中的高级应用, 包括 HMR 热更新功能, glob-import批量导入功能,预编译优化提升 Vite 性能,在非 Node 服务中集成 Vite,Vite 中对 SSR 的使用,静态站点导出,Vite 配置项总结等应用

Vite 中的 HRM 热更新

通过 vanilla 项目创建 HRM

创建项目

$ npm init @vitejs/app ✔ Project name: … vite-project ✔ Select a framework: › vanilla ✔ Select a variant: › vanilla 复制代码

实现单文件HMR 热更新

import './style.css' export function render () {   document.querySelector('#app').innerHTML = `   <h1>Hello Vite!</h1>   <a href="https://vitejs.dev/guide/features.html" target="_blank">Documentation</a> ` } render() // 集成 HMR // vite build 时 import.meta.hot 是不存在的, 所以加开发环境的判断条件 // 常规范式: 在开发环境中设置 HRM 热更新 if (import.meta.hot) {     // 接收热更新     // newModule 对应的当前文件    // Vite 接收到文件更新后, 执行这个方法 重新 render    import.meta.hot.accept((newModule) => {     newModule.render();    }) } 复制代码

附源码: github.com/xujiantong/…

Vite 中的 glob-import 批量导入功能

glob-import: 可以使用正则表达式, 引入一组的文件

通过 vite-vue3 项目实操 glob-import

创建项目

$ npm init @vitejs/app ✔ Project name: … vite-project ✔ Select a framework: › vue ✔ Select a variant: › vue $ cd vite-project $ yarn  $ yarn dev 复制代码

准备文件

在 src 目录下创建 glob 文件夹 并创建 文件

cd src mkdir glob touch a.js a.json b.js b.json test-1.js # 文件内容见源码 # https://github.com/xujiantong/vite-senior-apply/tree/feat/glob 复制代码

在 mian.js 中一键导入 glob 下面的所有文件

导入所有文件
// main.js import { createApp } from 'vue' import App from './App.vue' const globModules = import.meta.glob("./glob/*") console.log(globModules) createApp(App).mount('#app') 复制代码

image-20211002141032268.png

image-20211002142620208.png

使用文件里面的数据
import { createApp } from 'vue' import App from './App.vue' const globModules = import.meta.glob("./glob/*") console.log(globModules) // 查看 Key Value Object.entries(globModules).forEach(([k,v]) => {     console.log(k+ ":" + v)     v().then(m => console.log(k + ":" ,m.default)) }) createApp(App).mount('#app') 复制代码

image-20211002142939902.png

应用场景

多语言

只引入 JS
const globModules = import.meta.glob("./glob/*.js") 复制代码

只想引入 json 文件
const globModules = import.meta.glob("./glob/*.json") 复制代码

只想引入指定正则的文件
const globModules = import.meta.glob("./glob/*-[0-9].json") 复制代码

Glob-import 是 Vite 提供的功能

源码: github.com/xujiantong/…

Vite 中的 预编译

对于 node_modules 中安装的第三方的库, Vite 在第一次启动之前会去把我们所依赖的这些包进行编译放在 Cache 里面, 之后程序用到回去 Cache 里面去取。

/node_modules/.vite

  • CommonJS to ESM:  非 ESM 的文件会被编译成 ESM

    • 在开发过程中, Vite 是依赖于浏览器原生的 ESM 加载方式去加载文件的

  • 可配置 vite.config.js 指定哪些是需要预编译的

// vite.config.js export default defineConfig({   plugins: [vue()],   optimizeDeps: {     exclude: ["react"],     include: ["vue"],   } }) 复制代码

  • Bundle files together

非 Nodejs 服务集成 Vite

非 Nodejs 服务:java  go  python ...

  • 模板引擎使用 Vite

  • 引入路径问题

模板引擎增加标签 Dev

<script type="module" src="http://localhost:3000/@vite/client"> </script> <script type="module" src="http://localhost:3000/src/main.js"></script> 复制代码

解决路径问题 dev

服务端设置静态目录路径映射

打包生产时如何处理?

// vite.config.js build :{   manifest: true } 复制代码

Server 解析 manifest.json

将  index , vendor , css 输出到模板

在模板上接收变量

在 Nodejs 中如何集成 Vite

基础版

yarn add express

// server.js const express = require("express") const app = express() const { createServer: createViteServer} = require("vite") createViteServer({server: {     middlewareMode: 'html', // html: vite dev server, ssr:  }}).then((vite) => {     app.use(vite.middlewares)     app.listen(4000) })  复制代码

服务端渲染 SSR

开发环境 Dev

const express = require("express") const fs = require("fs") const app = express() const { createServer: createViteServer} = require("vite") createViteServer({server: {     middlewareMode: 'ssr', // html: vite dev server, ssr:  }}).then((vite) => {     app.use(vite.middlewares)     app.get("*", async (req,res)=> {         let template =  fs.readFileSync('index.html', 'utf-8')         template = await vite.transformIndexHtml(req.url, template)         const {render} = await vite.ssrLoadModule('/src/server-entry.jsx')         const html = await render(req.url)         const responseHtml = template.replace("<!--APP_HTML-->", html)         res.set("content-type", "text/html").send(responseHtml)     })     app.listen(4000) })  复制代码

Vite Config

// vim vite.config.js import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' // 引入 jsx 依赖 import vueJsx from '@vitejs/plugin-vue-jsx' // https://vitejs.dev/config/ export default defineConfig({   root: "", // index.html 存在的位置   base: "./",// 指定请求资源路径(URL)的前缀, 默认 ./   mode: "development", // 命令行启动时 --mode 同理, 指定 env, 默认 "development"(开发模式) "production" (生产模式)   define: "", // ≈ rollup 的 definePlugin, 定义全局常量的替换方式   plugins: [ // 使用插件     vue(),     vueJsx(),// 使用 vue-jsx   ],   publicDir:"", //静态资源存放目录   cacheDir: "", // 开发1时用到的缓存存放目录, 默认"node_modules/.vite"   resolve: {     alias: {},// 别名,路径映射: "@styles": "/src/styles"     dedupe:[], // 如果存在相同依赖的副本, 比如安装了 vue2, vue3, 用该属性来制定最终使用哪一个依赖     conditions: [], // 解决程序包中 情景导出 时的其他允许条件     mainFields: [], // package.json 中,在解析包的入口点时尝试的字段列表。注意:这比从 exports 字段解析的情景导出优先级低:如果一个入口点从 exports 成功解析,resolve.mainFields 将被忽略。     extensions: [], // 导入时想要省略的扩展名列表。不 建议忽略自定义导入类型的扩展名(例如:.vue),因为它会影响 IDE 和类型支持。    },   css: {     modules:[], // 配置 CSS modules 的行为     postcss: "", // 内联的 PostCSS 配置(格式同 postcss.config.js)     preprocessorOptions:{ //指定传递给 CSS 预处理器的选项       scss: {         additionalData: `$injectedColor: orange;`       }     },    },   json: {     namedExports:true, // 是否支持从 .json 文件中进行按名导入。     // json 文件很大的时候建议开启~     stringify: false,// 若设置为 true,导入的 JSON 会被转换为 export default JSON.parse("..."),这样会比转译成对象字面量性能更好,尤其是当 JSON 文件较大的时候。开启此项,则会禁用按名导入。   },   esbuild: {}, // ESbuild 转换选项   assetsInclude: {     assetsInclude: ['**/*.txt']   }, // 指定额外的 picomatch 模式 作为静态资源处理,  比如我想 import 一个 txt 文件   logLevel: 'info', // 打印日志级别   clearScreen: true,   envDir: "", //.env 文件存放目录   build: {     target: 'modules', // 设置最终构建的浏览器兼容目标     polyfillModulePreload: true, //用于决定是否自动注入 module preload 的 polyfill.     outDir: "dist",//指定输出路径     assetsDir: "assets",// 静态资源存放的路径     assetsInlineLimit: "4096", // 4kb, 小于此阈值的导入或引用资源将内联为 base64 编码,以避免额外的 http 请求。设置为 0 可以完全禁用此项。     cssCodeSplit: true, // css 文件拆分     sourcemap: 'hidden', // 构建后是否生成 source map 文件。     rollupOptions:{},     commonjsOptions:{},     dynamicImportVarsOptions:{},     lib:{},     manifest: false, // 当设置为 true,构建后将会生成 manifest.json 文件 包含了没有被 hash 的资源文件名和 hash 后版本的映射。可以为一些服务器框架渲染时提供正确的资源引入链接。     ssrManifest: false,     minify: 'esbuild',     terserOptions: {},     write: true, //设置为 false 来禁用将构建后的文件写入磁盘。这常用于 编程式地调用 build() 在写入磁盘之前,需要对构建后的文件进行进一步处理。     emptyOutDir: true, // 构建时是否先清空 dist     brotliSize: true, // 构建后压缩报告     chunkSizeWarningLimit: 500,// 压缩超过 500k 提醒     watch: null, //设置为 {} 则会启用 rollup 的监听器。在涉及只用在构建时的插件时和集成开发流程中很常用。     // 依赖优化项     optimizeDeps: {       entries: "",       include: [],       exclude: [],       keepNames: false, //  true 重命名符号避免冲突     }   } })


作者:墩墩大魔王丶
链接:https://juejin.cn/post/7015408423273496583


文章分类
后端
文章标签
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐