webpack进阶篇(二十七):webpack实现SSR打包(下)

简介: webpack进阶篇(二十七):webpack实现SSR打包(下)

说明

玩转webpack学习笔记



webpack ssr 打包存在的问题


1、浏览器的全局变量 (Node.js 中没有 document, window)


  • 组件适配:将不兼容的组件根据打包环境进⾏适配
  • 请求适配:将 fetch 或者 ajax 发送请求的写法改成 isomorphic-fetch 或者 axios


2、样式问题 (Node.js ⽆法解析 css)


  • ⽅案⼀:服务端打包通过 ignore-loader 忽略掉 CSS 的解析
  • ⽅案⼆:将 style-loader 替换成 isomorphic-style-loader

如何解决样式不显示的问题?


使⽤打包出来的浏览器端 html 为模板


设置占位符,动态插⼊组件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <div id="root"><!--HTML_PLACEHOLDER--></div>
</body>
</html>



首屏数据如何处理?


服务端获取数据


替换占位符


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <div id="root"><!--HTML_PLACEHOLDER--></div>
    <!--INITIAL_DATA_PLACEHOLDER-->
</body>
</html>



实现


由于上一节我已经将 如何解决样式不显示的问题? 这个问题已经处理,这一节就简单实现 首屏数据如何处理?

1、在上一节的基础上添加<!--INITIAL_DATA_PLACEHOLDER-->占位符

<!DOCTYPE html>
<html lang="en">
<head>
    <%= require('raw-loader!./meta.html') %>
    <title>Document</title>
    <script><%= require('raw-loader!babel-loader!../../node_modules/lib-flexible/flexible.js') %></script>
</head>
<body>
    <div id="root"><!--HTML_PLACEHOLDER--></div>
    <script type="text/javascript" src="https://11.url.cn/now/lib/16.2.0/react.min.js"></script>
    <script type="text/javascript" src="https://11.url.cn/now/lib/16.2.0/react-dom.min.js"></script>
    <!--INITIAL_DATA_PLACEHOLDER-->
</body>
</html>


2、在server文件夹里添加 data.json 文件,然后在server文件夹的 index.js 里引入

data.json

{
  "error": [],
  "extra": [],
  "data": {
    "list": [
      [{
        "sub_count": 5556,
        "column_type": 1,
        "id": 192,
        "column_price_market": 9900,
        "column_bgcolor": "#F6F7FB",
        "column_title": "SQL必知必会",
        "column_cover_small": "https:\/\/static001.geekbang.org\/resource\/image\/1c\/38\/1c5a5b154b543af952312eef33217438.jpg",
        "column_cover": "https:\/\/static001.geekbang.org\/resource\/image\/c7\/0d\/c7ee0aabbcb6d2da09a1b4a56c1a730d.jpg",
        "had_sub": false,
        "price_type": 2,
        "column_unit": "45讲",
        "is_experience": false,
        "column_ctime": 1559640855,
        "update_frequency": "每周一 \/ 三 \/ 五更新",
        "is_onboard": true,
        "author_intro": "清华大学计算机博士",
        "column_sku": 100029501,
        "column_cover_wxlite": "https:\/\/static001.geekbang.org\/resource\/image\/cd\/f0\/cd26b744d388dbd4387dcfaa66dd8bf0.jpg",
        "column_price": 6800,
        "column_price_sale": 6800,
        "author_name": "陈旸",
        "column_subtitle": "从入门到数据实战"
      }]
    ],
    "nav": [{
      "id": 1,
      "name": "专栏",
      "color": "#5ba6ff",
      "icon": "https:\/\/static001.geekbang.org\/resource\/image\/dd\/9e\/dd8cbc79f017d1b01f643c7ea929d79e.png"
    }, {
      "id": 3,
      "name": "视频课程",
      "color": "#79c109",
      "icon": "https:\/\/static001.geekbang.org\/resource\/image\/4a\/c3\/4aebe8fb752fa21a0fd989a45d9847c3.png"
    }, {
      "id": 2,
      "name": "微课",
      "color": "#5ba6ff",
      "icon": "https:\/\/static001.geekbang.org\/resource\/image\/9c\/f1\/9c223ccae33c5245a3009857582f1df1.png"
    }]
  },
  "code": 0
}


index.js

if (typeof window === 'undefined') {
  global.window = {};
}
const fs = require('fs');
const path = require('path');
const express = require('express');
const { renderToString } = require('react-dom/server');
const SSR = require('../dist/search-server');
const template = fs.readFileSync(path.join(__dirname, '../dist/search.html'), 'utf-8');
const data = require('./data.json'); // 引入数据
const renderMarkup = (str) => {
  const dataStr = JSON.stringify(data);
  return template.replace('<!--HTML_PLACEHOLDER-->', str)
    .replace('<!--INITIAL_DATA_PLACEHOLDER-->', `<script>window.__initial_data=${dataStr}</script>`);
};
const server = (port) => {
  const app = express();
  app.use(express.static('dist'));
  app.get('/search', (req, res) => {
    console.log('SSR-----------》', SSR);
    console.log('renderToString(SSR)------>', renderToString(SSR));
    const html = renderMarkup(renderToString(SSR));
    res.status(200).send(html);
  });
  app.listen(port, () => {
    console.log(`Server is running on port:${port}`);
  });
};
server(process.env.PORT || 3000);


3、添加好了之后我们重启node服务就可以看到下面的效果


20200810211611875.png

目录
相关文章
|
1月前
|
缓存 前端开发 JavaScript
Webpack 打包的基本原理
【10月更文挑战第5天】
|
1月前
|
前端开发 JavaScript
ES6模块化和webpack打包
【10月更文挑战第5天】
|
1月前
|
缓存 前端开发 JavaScript
深入了解Webpack:模块打包的革命
【10月更文挑战第11天】深入了解Webpack:模块打包的革命
|
2月前
|
JavaScript 测试技术 Windows
vue配置webpack生产环境.env.production、测试环境.env.development(配置不同环境的打包访问地址)
本文介绍了如何使用vue-cli和webpack为Vue项目配置不同的生产和测试环境,包括修改`package.json`脚本、使用`cross-env`处理环境变量、创建不同环境的`.env`文件,并在`webpack.prod.conf.js`中使用`DefinePlugin`来应用这些环境变量。
110 2
vue配置webpack生产环境.env.production、测试环境.env.development(配置不同环境的打包访问地址)
|
1月前
|
缓存 前端开发 JavaScript
Webpack技术深度解析:模块打包与性能优化
【10月更文挑战第13天】Webpack技术深度解析:模块打包与性能优化
|
1月前
|
前端开发 JavaScript 开发者
深入了解Webpack:现代JavaScript应用的打包利器
【10月更文挑战第11天】 深入了解Webpack:现代JavaScript应用的打包利器
|
2月前
|
JavaScript 前端开发
手写一个简易bundler打包工具带你了解Webpack原理
该文章通过手写一个简易的打包工具bundler,帮助读者理解Webpack的工作原理,包括模块解析、依赖关系构建、转换源代码以及生成最终输出文件的整个流程。
|
4月前
|
缓存 JSON 前端开发
Webpack打包优化实践
【7月更文挑战第17天】Webpack的打包优化是一个持续的过程,需要开发者根据项目的实际情况选择合适的优化策略。通过拆分代码、压缩代码、使用Tree Shaking、优化加载器配置、利用缓存以及进行性能分析,我们可以有效提升Webpack的打包效率和应用的加载
|
JavaScript 前端开发 定位技术
vue2项目webpack打包的优化策略,降低打包文件后的大小
vue2项目webpack打包的优化策略,降低打包文件后的大小
439 0
|
JavaScript CDN
webpack打包构建优化
webpack打包构建优化
123 0
下一篇
无影云桌面