笔记, 静态页面前后端渲染

自己写 Demo 的时候用到的一个 trick, 觉得挺有意思的
我的页面是用 JavaScript 搭配 React 生成的, 前面文章提过了
那么就有两部分的 HTML, 一部分比如 <head>, 是 gulp 生成
另一部分是 React 在浏览器当中生成的, 对应 <body> 的内容
但是, 因为 React 在 gulp 里也能跑, 其实我直接插入就好了

比如说有个 Component 叫 Page, 包含整个页面的结构
首先在浏览器当中渲染用的代码是这样:

React.render(<Page>, document.body);

而在 gulp 里调用是渲染字符串:

React.renderToString(<Page>);

那么生成的页面, 第一次加载的时候就可以是初次渲染的内容了
考虑到加载时的效果, 有必要把 CSS 从模块抽离出来, 用插件
https://github.com/webpack/extract-text-webpack-plugin

Markdown 文件

接着遇到了新的情况, 我的页面用了 Markdown, 看这里
https://github.com/Cumulo/cumulo.org
为了渲染 Markdown, 我引用了一个组件, 用于编译:
https://github.com/acdlite/react-remarkable
这个组件的使用方法是把正文内容以 source 参数传入:

<Markdown source="**Markdown is awesome!**" />

也就意味着我的 doc.md 文件需要拿到字符串才行, 加个 loader:
https://github.com/webpack/raw-loader
然后, 在 CirruScript 代码里我就可以 require :./doc/md 引用了
这个首先解决了浏览器渲染环节的问题

接下来的问题是, gulp 里怎么办, Node 环境没有 loader 的用法啊
不过还好这条路并不是堵死的, 我之前见 CoffeeScript 做过
http://coffeescript.org/documentation/docs/register.html
http://stackoverflow.com/a/17294906/883571

if require.extensions
  for ext in ['.coffee', '.litcoffee', '.coffee.md']
    require.extensions[ext] = loadFile
loadFile = (module, filename) ->
  raw = fs.readFileSync filename, 'utf8'
  stripped = if raw.charCodeAt(0) is 0xFEFF then raw.substring 1 else raw
  answer = compile(stripped, {filename, sourceMap: true, literate: helpers.isLiterate filename})
  sourceMaps[filename] = answer.sourceMap
  module._compile answer.js, filename

大致的意思就是注册一遍对应的后缀, 让 Node 能够识别
一般比较容易用到 module._compile, 用于执行 JavaScript 代码
具体涉及 Node 模块化机制的细节, 我不深入了, 可以看相关文章:
http://fredkschott.com/post/2014/06/require-and-the-module-system/

我不清楚全部细节, 但是加载纯文本文件的实现并不难:

if (? require.extensions) $ do
  = (. require.extensions :.md) $ \ (module filename)
    var code $ fs.readFileSync filename :utf8
    = module.exports code
    return module

如果是加载 png 文件, 也就是 base64:

  if require.extensions?
    fs = require 'fs'
    require.extensions['.png'] = (module, filename) ->
      content = fs.readFileSync filename
      buf = new Buffer content
      module.exports = "data:image/png;base64," + buf.toString('base64')
      return module

Node API 文档上说这个用法不推荐, 而且不会保证可靠, 留意下
https://nodejs.org/api/globals.html#globals_require_extensions

用了这个以后, gulp 环境也能把 doc.md 识别和加载了
最终编译过程也把 Markdown 读取为字符串, 渲染到 React 页面里

    原文作者:题叶
    原文地址: https://segmentfault.com/a/1190000003696375
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞