当前位置: 首页 > news >正文

vite如何处理项目中的资源

web开发服务器

实现简易的开发服务器

  1. 初始化项目
## 新建文件夹
vite_dev_server## 初始化工程
npm init -y## 安装服务框架
npm i koa## 新建入口文件
index.js## 新增启动脚本
{"scripts": {"dev": "node index.js"}
}
const Koa = require("koa")const app = new Koa()// 接收到请求后触发use注册的回调函数
app.use((ctx) => {// ctx: 请求上下文;  request: 请求信息;  response:响应信息;console.log("ctx", ctx.request, ctx.response);
})// 启动服务
app.listen(5173, () => {console.log("vite dev serve liste on 5173");
})

  1. 新建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><body>hello! my is node sever.
</body></html>
const Koa = require("koa")
const fs = require("fs")
const path = require("path")const app = new Koa()// 接收到请求后触发use注册的回调函数
app.use(async (ctx) => {// ctx: 请求上下文;  request: 请求信息;  response:响应信息;// console.log("ctx", ctx.request, ctx.response);if (ctx.request.url === "/") {const indexContent = await fs.promises.readFile(path.resolve(__dirname, "./index.html")) // 读文件ctx.response.body = indexContent // 设置响应体ctx.response.set("Content-Type", "text/html") // 设置响应体格式, application/json text/html text/javascript}
})// 启动服务
app.listen(5173, () => {console.log("vite dev serve liste on 5173");
})

  1. 新建main.js, 在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><body>hello! my is node sever.<script type="module" src="/main.js"></script>
</body></html>
console.log("main js hihi");
const Koa = require("koa")
const fs = require("fs")
const path = require("path")const app = new Koa()// 接收到请求后触发use注册的回调函数
app.use(async (ctx) => {// ctx: 请求上下文;  request: 请求信息;  response:响应信息;// console.log("ctx", ctx.request, ctx.response);if (ctx.request.url === "/") {const indexContent = await fs.promises.readFile(path.resolve(__dirname, "./index.html")) // 读文件ctx.response.body = indexContent // 设置响应体ctx.response.set("Content-Type", "text/html") // 设置响应体格式, application/json text/html text/javascript}if (ctx.request.url === "/main.js") {const mainContent = await fs.promises.readFile(path.resolve(__dirname, "./main.js")) // 读文件ctx.response.body = mainContent // 设置响应体ctx.response.set("Content-Type", "text/javascript") // 设置响应体格式, application/json text/html text/javascript}
})// 启动服务
app.listen(5173, () => {console.log("vite dev serve liste on 5173");
})

  1. 新建App.vue, 在main.js中引入,响应给浏览器

开发服务返回给浏览器的vue文件已经是编译后的文件了, 我们也要这样做

// 我这里请求失败了, 大概是这个输出有问题
console.log("app vue haha")
import "/App.vue"console.log("main js hihi");
const Koa = require("koa")
const fs = require("fs")
const path = require("path")const app = new Koa()// 接收到请求后触发use注册的回调函数
app.use(async (ctx) => {// ctx: 请求上下文;  request: 请求信息;  response:响应信息;console.log("ctx", ctx.request, ctx.response);if (ctx.request.url === "/") {const indexContent = await fs.promises.readFile(path.resolve(__dirname, "./index.html")) // 读文件ctx.response.body = indexContent // 设置响应体ctx.response.set("Content-Type", "text/html") // 设置响应体格式, application/json text/html text/javascript}if (ctx.request.url === "/main.js") {const mainContent = await fs.promises.readFile(path.resolve(__dirname, "./main.js")) // 读文件ctx.response.body = mainContent // 设置响应体ctx.response.set("Content-Type", "text/javascript") // 设置响应体格式, application/json text/html text/javascript}if (ctx.request.url === "/app.vue") {const appContent = await fs.promises.readFile(path.resolve(__dirname, "./App.vue")) // 读文件// /**//  * 如果vue文件, 我们要做处理, 转译为JS返回给前端, 这个过程肯定是非常复杂的, 这里了解一下原理//  * 1. 简单理解就是要进行字符串替换: appContent.toString().find("<template>") 如果匹配到了内容, 就要把全部内容替换为JS代码//  * 2. 实际过程:  经过AST语法分析 ==> 得到所有元素 ==> 使用 Vue.createElement() 方法 ==> 把得到的元素重新构建成原生的DOM//  * 3. 核心就是把vue文件转译为JS文件, 因为浏览器只认识JS文件//  */ctx.response.body = appContent // 设置响应体ctx.response.set("Content-Type", "text/javascript") // 设置响应体格式, application/json text/html text/javascript}
})// 启动服务
app.listen(5173, () => {console.log("vite dev serve liste on 5173");
})

处理css

了解Vite怎么处理css

vite天生就支持对css文件的直接处理,

  1. 新建index.css
html,
body {width: 100%;height: 100%;background-color: aqua;
}
  1. 在main.js中引入css
import './index.css'
  1. 启动项目

  1. 下面是vite处理css的步骤
  • vite在读取到main.js中引用到了index.css
  • 直接去使用fs模块去读取index.css中文件内容
  • 直接创建一个style标签,将index.css中文件内容直接copy进style标签里
  • 将style标签插入到index.html的head中

  • 将该css文件中的内容直接替换为js脚本(方便热更新或者css模块化), 同时设置Content-Type为js, 从而让浏览器以JS脚本的形式来执行该css后置的文件

如何避免样式冲突?

  1. 会什么会冲突:
  • 一个组件最外层的元素类名一般取名: wrapper
  • 一个组件最底层的元素雷明明我们一般取名: footer
  • 你取了footer这个名字,别人因为没有看过你这个组件的源代码,也可能去取名footer这个类名
  • 最终可能会导致样式被覆盖(因为类名重复),这就是我们在协同开发的时候很容易出现的问题
  1. 模拟样式冲突:
<!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><body><div id="div"></div><script src="./main.js" type="module"></script>
</body></html>
#div {width: 200px;height: 200px;background-color: red;
}
#div {width: 200px;height: 200px;background-color: green;
}
import './a.css'
import './b.css'

  1. 如何解决协作开发中的样式冲突问题:
  • cssmodule就是来解决这个问题的
  • module.css(module是一种约定,表示需要开启css模块化)
  • 他会将你的所有类名进行一定规则的替换(将div替换成div_10b22_1)
  • 同时创建一个映射对象{div:"div_10b22_1"}
  • 将替换过后的内容塞进style标签里然后放入到head标签中(能够读到index.html的文件内容)
  • a.module.css内容进行全部抹除,替换成JS脚本
  • 将创建的映射对象在脚本中进行默认导出
#div {width: 200px;height: 200px;background-color: red;
}
#div {width: 200px;height: 200px;background-color: green;
}
import './a.module.css'
import './b.module.css'

vite处理less或css

  1. 当vite识别到.less结尾的文件后, 先把less语法转译为css语法
  2. 按照处理css的步骤继续处理

vite.config.js中的css配置(module篇)

在vite.config.js中我们通过css属性去控制整个vite对于css的处理行为

  1. localConvention: 修改生成的配置对象的key的展示形式 (驼峰还是中划线形式)
  • camelCase: 驼峰命名

  • camelCaseOnly: 只保留驼峰命名

  • dashes: 中划线命令

  • dashesOnly: 只保留中划线命名(理论上是默认值)(实测结果如下, 不知道咋回事)

  • 默认值: 只保留中划线命名

#div {width: 200px;height: 200px;background-color: red;
}#div-conteainer {width: 100px;
}
import css from './a.module.css'
console.log(css);
import { defineConfig } from 'vite'export default defineConfig({css: {modules: { // 对css模块化的默认行为进行覆盖localsConvention: "dashesOnly"}}
})

  1. scopeBehaviour: 配置当前的模块化行为是模块化 还是全局化

tocal: 开启模块化css, 拼接哈希值 (默认值)

global: 全局化css (关闭模块化css)

import { defineConfig } from 'vite'export default defineConfig({css: {modules: { // 对css模块化的默认行为进行覆盖localsConvention: "camelCaseOnly"}}
})

  1. generateScopedName: 生成的类名的规则
  • 可以配置为函数,也可以配置成字符串规则: https://github.com/webpack/loader-utils#interpolatename
import { defineConfig } from 'vite'export default defineConfig({css: {modules: { // 对css模块化的默认行为进行覆盖,最终丢给postcss覆盖其modules配置generateScopedName: "[name]_[local]_[hash:5]",// generateScopedName: (name, filename, css) => {//   // name: 代表此刻css文件中的类型//   // filename: 当前css文件的绝对路径//   // css: 当前的样式//   return `${name}_${Math.random().toString(36).substr(3, 8)}`// },}}
})

  1. hashPrefix: 生成的hash会根据你的类名+一些其他的字符串(文件名+ 他内部随机生成一个字符串)去进行生成,如果你想要你生成hash更加的独特一点,你可以配置hashPrefix
import { defineConfig } from 'vite'export default defineConfig({css: {modules: {hashPrefix: "wang"}}
})

  1. rglobalModulePaths: 你不想参与到css模块化的路径
import { defineConfig } from 'vite'export default defineConfig({css: {modules: {globalModulePaths: ["./b.module.css"]}}
})

vite配置文件中css配置(preprocessorOptions篇)

主要是用来配置css预处理的一些全局参数

# 假设没有使用构建工具,我们又想去编译less文件的话yarn add less; # 内含lessc的编译器# 你只要安装了node,你就可以使用node index.js
# 你只要安装了less 你就可以使用lessc去编译less文件
  1. math: 处理表达式的范围
import { defineConfig } from 'vite'export default defineConfig({css: {preprocessorOptions: { // 格式key + config,  key代表预处理的名less: { // 整个配置对象都会最终给到less的执行参数(全局参数)中去math: "always", // 默认只会处理()内的表达式, 配置后处理所有表达式},sass: {}}}
})
#div {padding: 20px / 2; // 全部处理margin: (20px / 2); // 默认处理
}
#配置后的执行效果等同于
npm lessc --math="always" index.module.less
  1. globalVars: 定义全局变量

很多工程都是这样使用全局变量

@mainColor: red
@import url(./variables.less);#div {padding: 20px / 2; // 全部处理margin: (20px / 2); // 默认处理background-color: @mainColor;
}

也可以这样定义全局变量, 效果一样

import { defineConfig } from 'vite'export default defineConfig({css: {preprocessorOptions: { // 格式key + config,  key代表预处理的名less: { // 整个配置对象都会最终给到less的执行参数(全局参数)中去globalVars: { // 全局变量mainColor: "red"}},sass: {}}}
})

devSourcemap 文件索引

  1. 假设我们的代码被压缩或者被编译过了,这个时候假设程序出错,他将不会产生正确的错误位置信息
  2. 如果设置了sourceMap,他就会有一个索引文件 map, 提示我们正确的代码位置信息
import { defineConfig } from 'vite'export default defineConfig({css: {devSourcemap: false // 默认false, 开启true}
})
  1. 未开启的效果, 只能定位到style标签, 因为编译后就是把sytle标签插入到HTML中

  1. 开启后的效果, 可以定位到正确的源码文件

postcss

vite天生对postcss有非常良好的支持

  1. postcss 他的工作就是保证css执行起来是万无一失的
  • 我们写的css代码(怎么爽怎么来)--> 交给postcss处理 --->调用less sass等预处理器将扩展语法编译为css语法 ->再将高级css语法进行降级--> 在进行前缀补全 --> 浏览器执行
  • 我们写的is代码(怎么爽怎么来)-->babel -->将ts语法转换js语法 -->做一次语法降级 -->浏览器客户端去执行
  1. css的新提案 (未来css将支持css变量)
:root {--globalColor: lightblue;
}#div {width: 200px;height: 200px;background-color: var(--globalColor);
}

演示下单独使用postcss

  1. 初始化工程
npm init -y
  1. 安装依赖
npm install postcss-cli postcss -D
  1. 新建index.css
:root {--globalColor: red;
}div {background-color: var(--globalColor);
}
  1. 编译css文件
npx postcss index.css -o result.css
# 得到的编译结果, 我们没做任何配置, 原样输出:root {--globalColor: red;
}div {background-color: var(--globalColor);
}
/*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImluZGV4LmNzcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSIsImZpbGUiOiJyZXN1bHQuY3NzIiwic291cmNlc0NvbnRlbnQiOlsiOnJvb3Qge1xyXG4gIC0tZ2xvYmFsQ29sb3I6IHJlZDtcclxufVxyXG5cclxuZGl2IHtcclxuICBiYWNrZ3JvdW5kLWNvbG9yOiB2YXIoLS1nbG9iYWxDb2xvcik7XHJcbn0iXX0= */
  1. 安装预设的配置插件
npm install postcss-preset-env -D
  1. 添加配置文件
const postcssPresetEnv = require("postcss-preset-env")//预设环境里面是会包含很多的插件
// 语法降级-->postcss-low-level
// 编译插件postcss-compiler
// ... 省的自己一个一个安装了module.export = {plugins: [postcssPresetEnv(/* pluginOptions */)]
}
  1. 重新编译 (做了语法兼容处理)
:root {--globalColor: red;
}div {background-color: red;background-color: var(--globalColor);
}
  1. 为什么把postcss称为后处理器?
  • 业内把less/sass称为前处理器, 作用是先一步把扩展的css语法转译为原生css语法
  • 把postcss称为后处理器, 作用是后一步把原生css语法中的高级语法做降级处理
  • 实际上postcss本身就可以集成处理less/sass法语的插件
  • 只是随着生态的发展, 在脚手架中集成less/sass, 再把原生css交给postcss处理, 已经形成共识, 所以postcss处理less/sass语法的插件也就没必要维护了

再vite中配置postcss

  1. 安装预设的配置插件
npm install postcss-preset-env -D
  1. 配置
import { defineConfig } from 'vite'
const postcssPresetEnv = require("postcss-preset-env") // 所以的ES规范最终也会编译为commonJS规范. 因为这里是node环境export default defineConfig({css: {postcss: {plugins: [postcssPresetEnv()]}}
})
  1. 代码
:root {--globalColor: lightblue;
}#div {width: 200px;height: 200px;background-color: var(--globalColor);/* 新语法: 盒子宽度设置为父元素宽度的30%, 但最小不小于100px, 最大不大于200px, *//* postcss会帮我们语法降级, vite内部会维护一个主流浏览器的属性支持表, 根据这个表决定是否降级 */width: clamp(100px, 30%, 200px);user-select: none;
}#div-conteainer {width: 100px;
}

  1. vite也可以识别 postcss.config.js 配置文件, 优先级低于配置属性

处理静态资源

什么是静态资源 ?

  1. 对于服务端, 除了动态API以外,其它资源都被视作静态资源
  2. vite对静态资源基本上是开箱即用的

vite怎么加载静态资源

{"name": "张三","age": 18
}
// 学习vite怎么加载静态资源
// import imgUrl from "./assets/images/DE.jpg?url" 
import imgUrl from "./assets/images/DE.jpg?raw"
import json from "./a.json"const img = document.createElement("img")
img.src = imgUrl
document.body.append(img)// 在vite中, json文件导入后得到对象, 其他工具会的得到JSON字符串
console.log("json=", json);// 在url模式下(默认), 拿到图片的绝对路径 /assets/images/DE.jpg
// 在raw模式下, 拿到图片文件的 Buffer (二进制字符串) (也就是原始文件)
console.log("imgUrl=", imgUrl);
import './imageLoader.js'

路径别名的配置

  1. 怎么配置
import { defineConfig } from 'vite'
import path from 'path'export default defineConfig({resolve: {alias: {"@": path.resolve(__dirname, ""),"@assets": path.resolve(__dirname, "./assets")}}
})

import imgUrl from "@assets/images/DE.jpg?url"
  1. 实现原理: 服务端会进行字符串替换, 使用到@符号的地方会被替换为绝对路径

vite对svg资源的处理

  1. 概念
  • svg: scalable vector graphics 可伸缩矢量图形(新的图片格式)
  1. 优势
  • 优点: svg是不会失真, 尺寸小
  • 缺点: 没法很好的去表示层次丰富的图片信息
  • 我们在前端领域里更多的是用svg 去做图标
  1. 使用方式
import svgIcon from './assets/images/AAVE.svg'
import svgRwa from './assets/images/AAVE.svg?raw'// 1.第一种使用svg的方式
// const img = document.createElement("img")
// img.src = svgIcon
// document.body.appendChild(img)// 2.第二种使用方式
document.body.innerHTML = svgRwa
const svgEl = document.getElementsByTagName("svg")[0]
svgEl.onmouseenter = function () {this.style.fill = "red"
}

http://www.dtcms.com/a/423910.html

相关文章:

  • 文网文网站建设wordpress只显示首页
  • sk07.【scikit-learn基础】--『监督学习』之支持向量机
  • 网站建设与管理好学吗打广告网站
  • 免费门户网站源码长春企业网站建设价格
  • 【APK安全】HTTPS证书校验的核心风险与防御指南
  • 小迪web自用笔记41
  • 国外网站国内做好还是国外做邹城住房城乡建设部网站
  • 预付做网站定金如何免费的网站模板哪里有
  • 黄金、白银、石油期货市场API对接文档
  • linux入门5.1(Nginx服务器)
  • Hadess入门到实战(5) - 如何管理通用Generic制品
  • 丰台手机网站建设2023年新闻摘抄
  • Adobe Journey Optimizer 实战应用:企业如何整合全渠道营销与实时互动
  • 网站建设客户相关问题佛山网页设计师
  • 【附源码】基于Spring Boot的高校爱心捐助平台的设计与实现
  • PPIO上线DeepSeek-V3.2-Exp:引入稀疏注意力机制,API 大幅降价
  • 成都私人视频网站制作平台沈阳看男科的权威医院
  • 从零开始掌握 uv:新一代超快 Python 项目与包管理器(含 Windows 支持)
  • 天津网站建设 泰姆仕四川网络营销推广
  • 政务网站建设经验做法东莞企业网站建设预算大概多少
  • 怎么做网站icp备案有没有学做家具的网站
  • 新天力科技冲刺北交所:供应链韧性成资本市场“加分项”
  • Linux之线程池
  • 摄影师网站html5wordpress分类加密
  • 免费机械网站模板绵阳市建设工程监督网站
  • React Native 中的 useCallback
  • 哪些网站做的比较好看480元做网站
  • DSC蓝宝石法:精准测量材料比热容的核心技术
  • 在 Kubernetes 集群中运行并发布应用程序
  • Node.js面试题及详细答案120题(81-92) -- 框架与生态篇