vite概念
-
vite是一个面向现代浏览器的一个更轻、更快的Web应用开发工具
-
它基于ECMAScript标准原生模块系统(ES Modules)实现
vite项目依赖
-
vite
-
@vue/compiler-sfc
基础使用
-
vite serve
-
是一个用于启动web开发的服务器,启动服务器的时候不需要编译所有的代码文件,启动非常快
-
-
Vite build
-
Rollup
-
Dynamic import
-
Polyfill
-
-
vite核心功能
-
静态Web服务器
-
编译单文件组件
-
拦截浏览器不识别的模块,并处理
-
-
HMR
-
vite HMR
-
立即编译当前所修改的文件
-
-
Webpack HMR
-
会自动以这个文件为入口重写build一次,所有的涉及到的依赖也都会被加载一遍
-
-
vite特性
-
快速冷启动
-
模块热更新
-
按需编译
-
开箱即用
-
TypeScript-内置支持
-
less/sass/stylus/postcss-内置支持(需要单独安装)
-
jsx
-
Web Assembly
-
代码案例
#!/usr/bin/env node
const path=require('path')
const { Readable } =require('stream')
const Koa = require('koa')
const send = require('koa-send')
const compilerSFC=require('@vue/compiler-sfc')
const { COPYFILE_EXCL } = require('constants')
const app = new Koa()
const streamToString = stream => new Promise((resolve, reject) => {
const chunks = []
stream.on('data', chunk => chunks.push(chunk))
stream.on('end', () => resolve(Buffer.concat(chunks).toString('utf-8')))
stream.on('error', reject)
})
const stringToStream =text =>{
const stream =new Readable()
stream.push(text)
stream.push(null)
return stream
}
// 3.加载第三方模块
app.use(async (ctx, next) => {
//ctx.path ->/@modules/vue
if (ctx.path.startsWith('/@modules/')) {
const moduleName = ctx.path.substr(10)
const pkgPath=path.join(process.cwd(),'node_modules',moduleName,'package.json')
const pkg=require(pkgPath)
ctx.path=path.join('/node_modules',moduleName,pkg.module)
}
await next()
})
// 1.开启静态文件服务器
app.use(async (ctx, next) => {
await send(ctx, ctx.path, { root: process.cwd(), index: 'index.html' })
await next()
})
// 4.处理单文件组件
app.use(async (ctx,next)=>{
if(ctx.path.endsWith('.vue')){
const contents = await streamToString(ctx.body)
const { descriptor} = compilerSFC.parse(contents)
let code
// 第一次请求
if(!ctx.query.type){
code=descriptor.script.content
// console.log(code)
code = code.replace(/export\s+default\s+/g, 'const __script = ')
code += `
import { render as __render } from "${ctx.path}?type=template"
__script.render = __render
export default __script
`
}
else if(ctx.query.type==='template'){
const templateRender = compilerSFC.compileTemplate({ source:descriptor.template.content })
code =templateRender.code
}
ctx.type='application/javascript'
ctx.body = stringToStream(code)
}
await next()
})
// 2.修改第三方模块的路径
app.use(async (ctx, next) => {
if (ctx.type === 'application/javascript') {
const contents = await streamToString(ctx.body)
// import vue from 'vue'
// import App from './App.vue'
ctx.body = contents
.replace(/(from\s+['"])(?![\.\/])/g, '$1/@modules/')
.replace(/process\.env\.NODE_ENV/g, '"development"')
}
})
app.listen(3000)
console.log('Server running @http://localhost:3000')