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

本身写 Demo 的时候用到的一个 trick, 以为挺有意思的
个人页面是用 JavaScript 搭配 React 生成的, 前面文章提过了
那么就有两部分的 HTML, 一部分好比 <head>, 是 gulp 生成
另外一部分是 React 在浏览器当中生成的, 对应 <body> 的内容
可是, 由于 React 在 gulp 里也能跑, 其实我直接插入就行了html

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

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

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

React.renderToString(<Page>);

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

Markdown 文件

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

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

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

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

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/gulp

我不清楚所有细节, 可是加载纯文本文件的实现并不难:api

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 页面里

相关文章
相关标签/搜索