You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This is an example of how to setup server-side compilation and cache.
The idea is to use the same codebase of vue3-sfc-loader (v0.9.2+) on the server with the appropriate options: compiledCache to record compiled assets getFile to record all requested dependencies and exclude undesired ones handleModule to handle excluded modules createCJSModule to prevent js module creation
server
importpathfrom'path'importfsfrom'fs'import{fileURLToPath}from'url'const__dirname=fileURLToPath(newURL('.',import.meta.url))importexpressfrom'express';importLRUCachefrom'lru-cache'import{loadModule}from'vue3-sfc-loader'classHttpErrorextendsError{constructor(code,message){super(message)this.name=HttpError.name;this.code=code;Error.captureStackTrace(this,HttpError)}}constapp=express();functionv3sfclMiddleware(readFile){constSKIP_MODULE=Symbol();// common cache for all requestsconstglobalCache=newLRUCache({maxSize: 1024*1024,sizeCalculation: (value,key)=>key.length+value.length,updateAgeOnHas: false,updateAgeOnGet: true,});returnasync(req,res,next)=>{// we need to make the difference with a normal request and a vue3-sfc-loader cache requestif(req.header('X-v3sfcl-cache')!=='true')returnnext();try{// dependency cache for this request onlyconstcacheDeps=[];awaitloadModule(req.originalUrl,{moduleCache: {vue: null},// we don't need modules server-sidecreateCJSModule(){// v0.9.2+return{exports: {}};},// record all dependent compiled assets for the requested filecompiledCache: {get(key){cacheDeps.push(key);returnglobalCache.get(key);},set(key,value){globalCache.set(key,value);},},// record all dependent files for the requested fileasyncgetFile(url){// do not process files from other origins, this will be done client-sideif(!url.startsWith('/'))return{type: SKIP_MODULE};// issue skip handling type, caught by handleModulecacheDeps.push(url);if(globalCache.has(url))returnglobalCache.get(url);// actual file readingconstcontent=awaitreadFile(url);globalCache.set(url,content);returncontent;},// we need to handle file types we don't want to handle sever-sidehandleModule(type){if(type===SKIP_MODULE)// handle skip handling typereturnnull;// issue a null-module},// we don't need style server-sideaddStyle: ()=>{},});// convert cacheDeps to its related contentconstdata=Object.fromEntries(cacheDeps.map(key=>[key,globalCache.get(key)]));// we respond to a X-v3sfcl-cache requestres.set('X-v3sfcl-cache','true');res.status(200).end(JSON.stringify(data));}catch(ex){if(exinstanceofHttpError){res.status(ex.code).header('Content-Type','text/plain').end(ex.message);return;}throwex;}}}asyncfunctionreadFile(url){// TBD: check that file access is legitimateconsole.log('readFile',url)try{returnawaitfs.promises.readFile(path.join(__dirname,url),'utf-8')}catch{console.log(`${url} not found`)thrownewHttpError(404,`${url} not found`);}}app.use('/public',v3sfclMiddleware(readFile));app.use('/public',express.static(path.join(__dirname,'public')))app.listen(8181);
client (index.html)
<!DOCTYPE html><html><head><linkrel="shortcut icon" href="data:image/x-icon;," type="image/x-icon"></head><body><scriptsrc="https://unpkg.com/vue/dist/vue.runtime.global.prod.js"></script><scriptsrc="https://cdn.jsdelivr.net/npm/vue3-sfc-loader/dist/vue3-sfc-loader.js"></script><script>const{ loadModule }=window['vue3-sfc-loader'];constcache=Object.create(null);constoptions={devMode: false,moduleCache: {vue: Vue,},compiledCache: {get: key=>cache[key],set: (key,value)=>cache[key]=value,},asyncgetFile(url){if(urlincache)returncache[url];console.log('getFile',url)constactualUrl=newURL(url,window.location.origin);constres=awaitfetch(actualUrl,{method: 'GET',headers: {//
...actualUrl.origin===window.location.origin ? {'X-v3sfcl-cache': 'true',} : {},}});if(res.headers.get('X-v3sfcl-cache')==='true'){constdata=awaitres.json();Object.assign(cache,data);returncache[url];}return{getContentData: asBinary=>asBinary ? res.arrayBuffer() : res.text(),}},// handleModule hook is not mandatory, default one is ok.// this just illustrates files that are required in source .vue file but not handled by server-side cacheasynchandleModule(type,getContentData){if(type==='.png'){constarrayBuffer=awaitgetContentData(true);return'data:image/png;base64,'+btoa(String.fromCharCode(...newUint8Array(arrayBuffer)));}},addStyle(){// ...},log(type, ...args){console[type](...args);},}loadModule('/public/main.vue',options).then(rootComponent=>{constapp=Vue.createApp(rootComponent)app.mount(document.body);}).catch(ex=>console.error(ex));</script></body></html>
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
This is an example of how to setup server-side compilation and cache.
The idea is to use the same codebase of vue3-sfc-loader (v0.9.2+) on the server with the appropriate options:
compiledCache
to record compiled assetsgetFile
to record all requested dependencies and exclude undesired oneshandleModule
to handle excluded modulescreateCJSModule
to prevent js module creationserver
client (
index.html
)Beta Was this translation helpful? Give feedback.
All reactions