筆記, 靜態頁面先後端渲染

本身寫 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 頁面裏

相關文章
相關標籤/搜索