vite-plugin-seo-climsi-prerender
Version:
`vite-plugin-seo-climsi-prerender` 插件是一个用于 `Vite` 构建工具的预渲染插件,它可以将你的单页面应用 (SPA) 在构建时静态预渲染为 HTML 文件,以提高首次加载速度和SEO友好性。适用于对站点少量页面生成静态HTML。支持 `Vue、React`等所有框架
10 lines (9 loc) • 5.11 kB
JavaScript
/**
* name: vite-plugin-seo-climsi-prerender
* version: 0.1.2
*/
import E from"child_process";import f from"path";import L from"fs";import*as U from"sass";import D from"puppeteer";import F from"fs";import w from"path";import h from"fs";import C from"path";var p=e=>e&&e.replace(/\\/g,"/"),g=e=>{let t=C.dirname(e);h.existsSync(t)||g(t),h.existsSync(e)||h.mkdirSync(e)};function $(e){return new Promise(t=>setTimeout(t,e))}var H=async e=>{let t=await D.launch(Object.assign({headless:"new"},e.puppeteer||{})),o=await t.newPage();console.log("cookies",e.cookies);let s="[vite-plugin-seo-climsi-prerender:routes]",r={};e.network&&(r={waitUntil:"networkidle0"});for(let i of e.routes){if(!e.noCookiesRoutes.includes(i))await o.setCookie(...e.cookies);else{let a=await o.cookies();a.length>0?(await o.deleteCookie(...a),console.log("\u6240\u6709 cookies \u5DF2\u88AB\u6E05\u7A7A")):console.log("\u6CA1\u6709\u627E\u5230 cookies")}let n=e.local+e.baseUrl+i;e.hashHistory&&(n=`${e.local+e.baseUrl}/#${i}`),await o.goto(n,r),await o.setViewport({width:1024,height:768}),await o.waitForSelector("body"),e.delay&&await $(e.delay);let l=await o.content();e.removeStyle!==!1&&(l=l.replace(/<style\b[^<]*(?:(?!<\/style>)<[^<]*)*<\/style>/gi,""));let c=new RegExp(e.local,"g");if(l=l.replace(c,""),e.callback&&(l=e.callback(l,i)||l),i.indexOf("?")!==-1)console.log(`${s} ${i} is error,unexpected?`);else{let a=w.join(e.outDir,i);g(a);let d=w.join(a,"index.html");F.writeFileSync(d,l),console.log(`${s} ${d.replace(/\\/g,"/")} is success!`)}}await t.close(),console.log(`${s} is complete`)},S=H;import u from"fs";import m from"path";var y="",T=(e,t,o)=>{let s=u.readFileSync(m.join(e,"index.html"),"utf-8");if(t==="server"){let r=/<script[^>]*?\b\/main\b[^>]*?>.*?<\/script>/gi;return(s.match(r)||[]).join(`
`)}else{let r=/<link[^>]*?rel=['|"]stylesheet['|"][^>]*?\.css[^>]*?>/gi,i=s.match(r),l=u.readFileSync(m.join(e,o||"","index.html"),"utf-8").match(r)||[],c=l;return i&&(c=l.filter(a=>!i.includes(a))),c.join(`
`).replace('"./','"/')}},x=(e,t)=>e.replace(/<!--link\shref="(.*)"-->/gi,function(o,s){let r=m.join(t,s);return u.existsSync(r)?u.readFileSync(r,{encoding:"utf8"}):o}),P=(e,t,o)=>{let r=u.readFileSync(t,"utf-8").replace("</head>",`${y}
</head>`);r=x(r,e),typeof o=="function"&&(r=o(r,t)||r),u.writeFileSync(t,r),console.log("[vite-plugin-seo-climsi-prerender:publicHtml] "+p(m.relative(e,t)))},v=(e,t,o,s)=>{if(!u.existsSync(e)){console.log(`${e}\u8DEF\u5F84\u4E0D\u5B58\u5728`);return}u.readdirSync(e).forEach(i=>{let n=m.join(e,i);u.statSync(n).isFile()&&m.extname(n)===".html"&&!p(n).endsWith(t)&&P(o,n,s),u.statSync(n).isDirectory()&&v(n,t,o,s)})},R=async e=>{let{mode:t,root:o,filePath:s,outDir:r=""}=e;if(y||(y=T(o,t,r)),t==="server"){let i=m.join(o,"public",s),n=u.readFileSync(i,"utf-8");return n=n.replace("</body>",`${y}
</body>`),n=x(n,o),typeof e.callback=="function"&&(n=e.callback(n,s)||n),n}else if(typeof s=="boolean"){let i=m.join(o,r),n=p(m.join(r,"index.html"));v(i,n,o,e.callback)}else for(let i in s){let n=m.join(o,r,s[i]);P(o,n,e.callback)}},b=R;var k=e=>{let t=[];return typeof e=="object"&&(t=e||[]),{allUrl:t,isAllUrl:typeof e=="boolean"&&e}},j=(e,t)=>{let o=f.join(e,t.entry),s=U.compile(o),r=f.join(e,t.outDir);g(f.dirname(r)),L.writeFileSync(r,s.css),console.log(`transform scss: ${t.entry} => ${t.outDir}`)},M=e=>{let t={outDir:"",mode:"",root:"",local:"",base:"",isProduction:!1,command:""},o=e.publicHtml||!1;return{name:"vitePluginSeoPrerender",enforce:"post",configResolved(s){t.outDir=s.build.outDir,t.mode=s.mode,t.root=s.root,t.base=s.base,t.isProduction=s.isProduction,t.command=s.command},buildStart(){var s;(s=e==null?void 0:e.scss)!=null&&s.length&&e.scss.forEach(r=>{j(t.root,r)})},configureServer(s){let{allUrl:r,isAllUrl:i}=k(o);(r.length||i)&&s.middlewares.use(async(n,l,c)=>{let a=decodeURIComponent(n.url.replace(t.base,"/"));if(i&&a.endsWith(".html")||r.includes(a)){let d=await b({root:t.root,filePath:a,mode:"server",callback:e.callback});if(d){l.setHeader("Content-Type","text/html"),l.end(d);return}}c()})},handleHotUpdate({file:s,server:r}){var i;if(s.endsWith(".html")){let{allUrl:n,isAllUrl:l}=k(o);if(l||n.length){let c=f.join(t.root,"public"),a=f.relative(c,s);r.ws.send({type:"full-reload",path:"/"+p(a)})}}if((i=e==null?void 0:e.scss)!=null&&i.length&&s.endsWith(".scss")){let n=p(s);e.scss.forEach(l=>{n.includes(l.entry)&&j(t.root,l)})}},async closeBundle(){var l;if(!t.isProduction)return;let{allUrl:s,isAllUrl:r}=k(o);if((r||s.length)&&await b({root:t.root,filePath:r||s,mode:"build",outDir:t.outDir,callback:e.callback}),!((l=e==null?void 0:e.routes)!=null&&l.length))return;console.log("[vite-plugin-seo-climsi-prerender:routes] is start..");let i=E.exec("vite preview",c=>{if(c){console.error("\u6267\u884C\u547D\u4EE4\u65F6\u53D1\u751F\u9519\u8BEF\uFF1A",c);return}}),n="";i.stdout.on("data",async c=>{let a=c.match(/http:\/\/(.*?)\//g);a&&a.length&&!n&&(n=a[0].replace(/\x1B\[\d+m/g,"").slice(0,-1),console.log("Local: "+n),t.local=n,await S(Object.assign(e,t)),i.kill("SIGTERM"),process.exit(),n="")})}}},te=M;export{te as default};