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

各大网站域名大全网站产品优化

各大网站域名大全,网站产品优化,网站做网站做任务,90设计网好吗一、背景 目前主流的前端架构分为SSR、CSR、SSG#xff0c;比较适合首屏直出的方案除了CSR都还不错#xff0c;因为服务端会直接返回路由对应的html css#xff0c;浏览器直接解析DOM即可#xff0c;而水合的作用是什么#xff1f;服务端首次返回的是静态页面#xff0…一、背景 目前主流的前端架构分为SSR、CSR、SSG比较适合首屏直出的方案除了CSR都还不错因为服务端会直接返回路由对应的html css浏览器直接解析DOM即可而水合的作用是什么服务端首次返回的是静态页面页面需要”动“起来的话则需要水合即将页面所需的JS引入并加载、给DOM绑定交互等等核心的API即ReactDOM.hydrateRoot。 二、同构渲染 这样服务端渲染一次、客户端渲染一次的流程也称为同构渲染一般情况是通过Nodejs实现文件服务基于组件文件通过React Server API——renderToString就像这样 import { renderToString } from react-dom/server; import App from ./App;console.log(renderToString(App/));而在客户端接收到服务端渲染所生成的html string后基于客户端水合API——react DOM API——hydrateRoot进行组件与静态标签的关联就像这样 import React from react; import { hydrateRoot } from react-dom/client; import ./index.css; import App from ./App;hydrateRoot(document.getElementById(root), App/);三、手写一个SSR 基于同构渲染的秘密我们解开了那手写一个基础的SSR服务其实很简单我们可以把整个加载链路拆解成三步 起一个本地express服务用于按路由返回html前端构建时约定式路由/pages解析每个路由下的根组件生成html模板webpack构建工程代码产出bundle.js前端项目中引入bundle.js进行同构渲染水合逻辑 整体的项目工程如下 ├── .next // 生成文件服务html、构建结果 ├── src │ ├── pages // 页面 │ │ ├── a.jsx // 页面A │ │ ├── b.jsx // 页面B │ │ ├── c.jsx // 页面C │ ├── client.js // 水合 ├── generateHtml.js // 路由转换html能力 ├── server.js // 文件服务 ├── teamplate.html // html基础模板 ├── webpack.config.js └── package.json3.1、文件服务搭建 我们起一个简单的工程项目并安装基础依赖。 mkdir ssr-demo cd ssr-demo npm init -y npm i express react react-dom webpack webpack-cli fs-extraexpress服务代码如下 const express require(express); const path require(path);// 定义根目录 const rootDir path.resolve(__dirname, ./); const outputDir path.join(rootDir, .next);const app express(); const PORT process.env.PORT || 3000;// 提供 .next 目录的静态文件服务 app.use(express.static(outputDir));// 启动服务器 app.listen(PORT, () {console.log(Server is running on http://localhost:${PORT}); }); 代码中启用了静态文件服务在路由解析服务实现后每次项目构建阶段都会在.nest路由生成所有页面的html用于在服务端直接返回。 3.2、路由解析服务 接下来我们实现服务端核心部分将所有路由的组件解析成html模板在此之前需要有一个基础的html模板用于动态插入组件部分的标签html模板如下 !DOCTYPE html html langenheadmeta charsetUTF-8 /titleMy App/title/headbody data-component{{componentName}}{{content}}script src/client.bundle.js defer/script/body /html其中content是实际渲染的组件标签、componentName用于在后续水合阶段定位组件、script用于执行水合逻辑。 遍历生成所有html文件的代码如下 // src/generate.js require(babel/register)({presets: [babel/preset-env, babel/preset-react], });const fs require(fs-extra); // 使用 fs-extra 方便处理文件 const path require(path); const React require(react); const ReactDOMServer require(react-dom/server);// 定义根目录 const rootDir path.resolve(__dirname, ./); const pagesDir path.join(rootDir, src/pages); const outputDir path.join(rootDir, .next);// 生成 HTML 文件 const generateHtmlFiles () {return new Promise((resolve, reject) {fs.readdir(pagesDir, (err, files) {if (err) {reject(Error reading pages directory);return;}const promises files.map((file) {const filePath path.join(pagesDir, file);const fileExt path.extname(file);// 只处理以 .jsx 结尾的文件if (fileExt .jsx) {const pageName path.basename(file, fileExt);const PageComponent require(filePath).default; // 导入组件const renderedContent ReactDOMServer.renderToString(React.createElement(PageComponent));const templatePath path.resolve(__dirname, template.html); // Load HTML templatereturn new Promise((resolve, reject) {fs.readFile(templatePath, utf8, (err, template) {if (err) {console.error(Error loading template:, err);reject(err);return;}const html template.replace({{content}}, renderedContent).replaceAll({{componentName}}, pageName); // 注入组件名称// 构造输出路径放在以页面名字为名的文件夹中const outputDirForPage path.join(outputDir, pageName);const outputFilePath path.join(outputDirForPage, index.html);fs.ensureDirSync(outputDirForPage); // 确保页面目录存在fs.outputFileSync(outputFilePath, html, utf8);console.log(Generated HTML for ${pageName}: ${outputFilePath});resolve();});});}return Promise.resolve(); // 对于不是 .jsx 文件的情况});Promise.all(promises).then(() resolve(HTML generation completed!)).catch(reject); // 处理生成过程中的异常});}); };// 直接调用生成函数并输出结果 generateHtmlFiles().then((message) {console.log(message);process.exit(0); // 结束进程}).catch((err) {console.error(err);process.exit(1); // 发生错误结束进程}); 3.3、webpack打包前端工程 这里比较好理解整个前端客户端代码也需要打包包括水合的代码我们基于webpack构建初始化一个基础的打包配置 const path require(path);module.exports {entry: path.resolve(__dirname, src, client.js),output: {path: path.resolve(__dirname, .next), // 输出到 .next 目录filename: client.bundle.js, // 根据入口名称生成文件名publicPath: /, // 公开路径},module: {rules: [{test: /\.(js|jsx)$/,exclude: /node_modules/,use: {loader: babel-loader,options: {presets: [babel/preset-env, babel/preset-react],},},},],},resolve: {extensions: [.js, .jsx],},mode: production, // 可以根据需要设置为 development };配置完webpack之后我们前三步的流程可以串起来了这个效果和webpack dev server比较类似我们基于流程顺序配置对应的package.json scripts scripts: {build: webpack --config webpack.config.js,generate: node generateHtml.js,server: node server.js,start: npm run build npm run generate npm run server},build负责构建前端工程generate负责生成所有页面的htmlserver负责创建最终的文件服务 3.4、渲染的终点——水合 这段代码运行时服务端已经返回html文件此时是同构渲染的终点通过hydrateRoot API将服务端的标签在浏览器水合让页面组件动起来即可。 实现代码 // // src/client.js import React from react; import ReactDOM from react-dom/client;console.log(React); const hydrateComponent (componentName) {// 动态 import 组件import(./pages/${componentName}.jsx).then(({ default: Component }) {const domContainer document.getElementById(componentName);if (domContainer) {ReactDOM.hydrateRoot(Component /, domContainer);} else {console.error(No container found for component ${componentName});}}).catch((error) {console.error(Error loading component:, error);}); };// 从 HTML 中提取组件名称然后进行水合 document.addEventListener(DOMContentLoaded, () {const componentName document.body.getAttribute(data-component);hydrateComponent(componentName); }); 至此整个demo就完成了。 大致的效果如下 结尾 本文希望对于原本不是很了解SSR、SSG方案的同学可以快速的理解与传统单页应用的区别并且可以基于这个demo了解到服务端渲染、webpack dev server的工作原理。 对于实现同构渲染的方案有建议的同学欢迎评论探讨。
http://www.dnsts.com.cn/news/116048.html

相关文章:

  • 试用型网站html电影网页制作模板
  • 网站招聘顾问做啥的江门网站建设方案报价
  • 凡科建站是永久的吗建设营销型网站
  • 网站源码和模板免费模板简历在哪下
  • 网站商城开发公司在线视频网站怎么做
  • 上海长宁网站建设怎么做自动下单网站
  • 佛山网站建设thualwordpress和dede seo
  • aspnet网站开发实例网站网站建设专业
  • 百度收录快的发帖网站php订餐网站开发文献
  • 网站二级页面设计要求浙江做网站多少钱
  • 湟源县wap网站建设公司常州微信网站建设
  • 郑州网站制作咨询求手机网站
  • 建设网站号码是多少钱南京网站建设外贸
  • 网站 被 抄袭建站之星模板好吗
  • 百度蜘蛛抓取新网站网站开发服务转包合同
  • 周年庆网站要怎么做重庆市工程建设信息网成绩查询
  • 网站设计做什么的怎么用php自己做网站
  • 海珠区网站建设集团网站建设教程
  • 商业店铺设计网站制作优化全包
  • 酒店网站建设案例网站空间大小 论坛
  • 重庆网站推广运营公司qq营销软件
  • 浙江网站建设广告语wordpress 打开好慢
  • 甘肃省城乡与建设厅网站首页wordpress 布局调整
  • 云浮网站建设兼职html5网站后台制作
  • 网站建设人员求职信贴吧网站建设
  • 学网站开发好吗wordpress豆瓣采集
  • 个人简历电子版模板免费无锡做网站优化公司
  • 网页设计推荐网站自己做的网站如何百度能搜索
  • 有道云笔记做网站网络营销的特点哪四个
  • 温州专业微网站制作公司电子商务网站建设策划书范文