iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 26
1

Nuxt 不像 Angular 這種大型框架,功能包山包海,核心功能不夠得自行擴充。
雖然提過如何透過全域/頁面設定客製、用 Plugin 收納初始化片段,但對於某一功能需要在 Nuxt App 生命週期中做更深度的功能注入和客製,這遠遠不夠。

Nuxt 包裝 Module Container,其提供 API 供開發者在 Nuxt 生命週期中注入客製功能,以達成功能切割、深度整合。諸如自動加上新 layout、掛編譯 hook、換 serverMiddleware,都做得到。

並且容易使用 - 在 nuxt.config.js 列舉模組與傳入參數

export default {
  modules: [
    // Simple usage
    '~/modules/simple'

    // Passing options
    ['~/modules/simple', { token: '123' }],
    
    // 
  ]
}

Nuxt 怎麼實現 Module?

Module Container 按順序執行 modules 列舉 function

export default class ModuleContainer {
  constructor(nuxt) {
    this.nuxt = nuxt /* nuxt instance */
    this.options = nuxt.options /* nuxt.config.js */
    this.requiredModules = {} /* 關連模組 */
  }

  async ready() {
    // Call before hook
    await this.nuxt.callHook('modules:before', this, this.options.modules)

    // Load every module in sequence
    await sequence(this.options.modules, this.addModule.bind(this))

    // Call done hook
    await this.nuxt.callHook('modules:done', this)
  }
  
  /* ... */
}

modules/simple.js
定義 Module,一個接收 nuxt.config.js 傳入參數的 function

export default function SimpleModule (moduleOptions) {
  // Write your code here
}

// REQUIRED if publishing the module as npm package
// module.exports.meta = require('./package.json')

Module 內定義初始化、擴充功能需要額外載入哪些東西進 Nuxt,稍微列舉 Module Container 的 API

/* 註冊程式碼樣板 */
/* Plugins 程式碼樣板、網站基礎樣板 (通常需要調整 VueRouter 才用得到)...等等,都可以替換 */
addTemplate(template) {}

/* 註冊 Plugin */
addPlugin(template) {}

/* 註冊 Layout */
addLayout(template, name) {}

/* 註冊 serverMiddleware */
addServerMiddleware(middleware) {}

/* 調整編譯步驟 */
extendBuild(fn) {}

/* 擴充路由 (同 nuxt.config.js 自訂路由) */
extendRoutes(fn) {}

Nuxt - Module Container 文件我省略部分


Async Module

Module 中若有非同步行為,為了確保執行順序如預期,最好包裝成 Async Module

簡單來講,Function 回傳 Promise 物件或手動呼叫 Callback

基本上原理通 asyncData(),舉例我偏好的 async / await

import fse from 'fs-extra'

export default async function asyncModule() {
  // You can do async works here using `async`/`await`
  let pages = await fse.readJson('./pages.json')
  
  /* Do print pages content, or something else */
}

如此可以確保模組中的後續動作正常執行

下一篇用 @nuxtjs/axios 講解 module 打包


上一篇
25. Nuxt Plugin 如何讓 Axios 更好用 (下)
下一篇
27. @nuxtjs/axios 如何透過 module 包裝 axios
系列文
Nuxt - 使用 Vue.js 做 SSR 的第一哩路31

尚未有邦友留言

立即登入留言