Vite
中的热更新,通过 Vite
命令行生成的项目默认都开启了热更新,同时 Vite
中的热更新是根据不同框架去实现的。HMR API
,对于 import.meta.hot
,通过 vite build
去 build
代码之后,在 build
的 production
的 bundle
里面是没有 hot
代码的,对于发布线上的代码是没有 hot
的需要,需要判断。对于 import.meta.hot.accept
,vite
推了一个热更新,它就会接收到这个热更新,main.js
,代码如下:
import './style.css'
function render() {
document.querySelector('#app').innerHTML = `
Hello Vite!
Documentation
`;
}
render();
if (import.meta.hot) {
import.meta.hot.accept((newModule) => {
newModule.render();
});
}
Vite
中的 glob-import
,具备批量导入的功能,可以使用 import.meta.glob
。如果直接编译引入,可以使用 globEager
。比如批量导入 glob
目录下的所有文件,代码如下:
const globModules = import.meta.glob('./glob/*');
// const globModules = import.meta.glob('./glob/*-[0-9].js');
// const globModules = import.meta.globEager('./glob/*');
Object.entries(globModules).forEach(([k, v]) => {
v().then(m => console.log(k + ':' + m.default));
});
Vite
中的预编译,会将非 ES Module
的文件编译成 ES Module
,这是因为 Vite
依赖浏览器原生的 ES Module
加载方式。在 vite.config.js
中,optimizeDeps
可以指明项目中哪些文件需要预编译,哪些不需要预编译,include
是需要预编译,exclude
是不需要预编译。预编译也会将零散的文件打包到一起,代码如下:
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
export default defineConfig({
plugins: [react()],
optimizeDeps: {
include: ['react'],
exclude: ['lodash-es']
}
})
在 nodejs
服务中集成 vite
,vite
提供的这些方法也是异步的,代码如下:
server-entry.jsx
import ReactDOMServer from 'react-dom/server';
import { StaticRouter } from 'react-router-dom';
import { App } from './App';
export function render(url, context) {
return ReactDOMServer.renderToString(
<StaticRouter location={url} context={context}>
<App />
</StaticRouter>
);
}
server.js
const express = require('express');
const app = express();
const { createServer: createViteServer } = require('vite');
// vite 的 devServer 服务
createViteServer({
server: {
// middlewareMode: 'html',
middlewareMode: 'ssr',
}
}).then((vite) => {
app.use(vite.middlewares);
app.get('*', async (req, res) => {
// res.set('content-type', 'text/html');
// res.send(fs.readFileSync('index.html'));
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('', 'html');
res.set('content-type', 'text/html').send(responseHtml);
});
app.listen(4000);
});
Node
集成 build
的 vite ssr
,代码如下:
server.js
const express = require('express');
const fs = require('fs');
const app = express();
const template = fs.readFileSync('dist/client/index.html');
const isProd = process.env.NODE_ENV === 'production';
// app.use(express.static('dist/client'));
app.get('*', async (req, res) => {
const render = require('./dist/server/server-entry').render;
const context = {};
const html = await render(req.url, context);
if (context.url) {
res.redirect(301, context.url);
return;
}
const responseHtml = template.replace('', 'html');
res.set('content-type', 'text/html').send(responseHtml);
});
app.listen(4000);
// const { createServer: createViteServer } = require('vite');
// // vite 的 devServer 服务
// createViteServer({
// server: {
// // middlewareMode: 'html',
// middlewareMode: 'ssr',
// }
// }).then((vite) => {
// app.use(vite.middlewares);
// // vite 中提供的这些方法都是异步的
// app.get('*', async (req, res) => {
// // res.set('content-type', 'text/html');
// // res.send(fs.readFileSync('index.html'));
// 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('', 'html');
// res.set('content-type', 'text/html').send(responseHtml);
// });
// app.listen(4000);
// });
修改 package.json
中的 scripts
下的 build
,如下:
"scripts": {
"dev": "vite",
"build": "npm run build:client && npm run build:server",
"build:client": "vite build --outDir dist/client",
"build:server": "vite build --outDir dist/server --ssr src/server-entry.jsx",
"preview": "vite preview",
"start": "NODE_ENV=devlopment node server.js"
},
Vite
中 SSR
静态站点导出,prerender.js
,代码如下:
const path = require('path');
const fs = require('fs');
const template = fs.readFileSync('dist/client/index.html');
const render = require('./dist/server/server-entry').render;
const routesToRender = path.readdirSync('src/pages').map((file) => {
return file.replace('.jsx', '').toLowerCase();
});
for (const route of routesToRender) {
const context = {};
const html = render(route, context)
const responseHtml = template.replace('', 'html');
const filePath = `dist/static/${route}.html`;
fs.writeFileSync(filePath, responseHtml);
console.log(`prerender ${filePath}`);
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)