saber 源码分析

2019-07-12  本文已影响0人  织雪纱奈

what

Saber is a static website generator, it is like Hexo but, you can use Vue, React or other view layerto write layouts

把page下的md/vue文件生成html,本地启项目,还可以打包部署

大象放进冰箱的三步

如果要我来实现大概会这样

  1. 把 md 转换生成 html,把 vue 转换生成 html
  2. 通过 express/koa/polka 启服务
  3. webpack 用来 hrm,打包生成 public 文件部署

大体作者本人也是这样实现的

配置

  1. 使用 lerna 来管理多包发布
  2. xo 做测试
  3. 使用 git-cz 提交,做changelog 记录

saber package

目录结构如下

屏幕快照 2019-07-12 下午3.07.50.png

最主要的是 saber 文件
本地安装启动 lib/index.js
全局启动是 lib/cli.js

saber-cli

打开 cli.js,使用 cac 获取 option 用户配置,若无,会设置默认配置
配置分三个

  1. dev mode 启动,先着重研究这个
  2. build 就是打包生成 public
  3. server 上面的解释是 Serve the output directory,没有大明白,大体是生产环境下,起服务,比如对build 后的目录做预览什么
cli
  .command('[app]', 'Run the application in dev mode', {
    ignoreOptionDefaultValue: true
  })
  .alias('dev')
  .option('--lazy', 'Enable lazy page compilation')
  .option('--port <port>', 'Server port', { default: 3000 })
  .option('--host <host>', 'Server host', { default: '0.0.0.0' })
  .action((cwd = '.', options) => {
    setNodeEnv('development')

    const { host, port, lazy } = options
    delete options.host
    delete options.port
    delete options.lazy
    return require('..')(Object.assign({ cwd, dev: true }, options), {
      server: {
        host,
        port
      },
      build: {
        lazy
      }
    })
      .serve()
      .catch(handleError)
  })

[app] 暂时理解为什么都没有,这个中括号我记得是有额外意思的,内置变量
和 webpack的配置:
options: {
name: 'static/media/[name].[hash:8].[ext]',
}一个用法
关于这个更详细的资料,不知哪里能查到,看到的告知一声,不剩感激

action 是执行

获取本目录的 index.js 传入配置,调用方法,执行 serve

saber-index

定义 Saber calss,引用 tapable,tapable 是很重要的一个,可以理解为复杂的 emit on
具体请看戳我

 async serve() {
    await this.prepare()
    await this.run()
    const server = http.createServer(this.renderer.getRequestHandler())
    server.listen(this.config.server.port, this.config.server.host)
  }

执行 prepare
执行 run
拿到 server
监听 端口

prepare

就跟名字一样,一系列配置准备工作

this.RendererClass = this.config.renderer
      ? resolvePackage(this.config.renderer, {
          cwd: this.configDir,
          prefix: 'saber-renderer-'
        })
      : require('../vue-renderer/lib')
    this.renderer = new this.RendererClass(this)
// 默认 renderer 不存在
// 加载 /vue-renderer/lib 文件
// 执行 VueRenderer 传入 saber 对象

VueRenderer

通过 webpack-chain 做一系列 webpack 配置
写route 文件

getRequestHandler

const webpack = require('webpack')
    const server = require('polka')()

    this.api.hooks.onCreateServer.call(server)

    const clientConfig = this.api
      .createWebpackChain({ type: 'client' })
      .toConfig()

    clientConfig.plugins.push(new webpack.HotModuleReplacementPlugin())

    const clientCompiler = webpack(clientConfig)

    const devMiddleware = require('webpack-dev-middleware')(clientCompiler, {
      logLevel: 'silent',
      publicPath: clientConfig.output.publicPath
    })

    const hotMiddleware = require('webpack-hot-middleware')(clientCompiler, {
      log: false
    })

webpack-dev-middleware 把文件写入内存
webpack-hot-middleware 和 hrm 配合实现热更新
返回结果,这个函数堪称最重要最精彩的部分

上一篇 下一篇

猜你喜欢

热点阅读