Nuxt.js 模塊

2020-02-13 17:12 更新
模塊是Nuxt.js擴(kuò)展,可以擴(kuò)展其核心功能并添加無(wú)限的集成。

介紹

在使用Nuxt開(kāi)發(fā)應(yīng)用程序時(shí),您很快就會(huì)發(fā)現(xiàn)框架的核心功能還不夠。 Nuxt可以使用配置選項(xiàng)和插件進(jìn)行擴(kuò)展,但是在多個(gè)項(xiàng)目中維護(hù)這些自定義是繁瑣、重復(fù)和耗時(shí)的。 另一方面,開(kāi)箱即用支持每個(gè)項(xiàng)目的需求將使Nuxt非常復(fù)雜且難以使用。

這就是Nuxt提供更高階模塊系統(tǒng)的原因,可以輕松擴(kuò)展核心。 模塊只是在引導(dǎo)Nuxt時(shí)按順序調(diào)用的函數(shù)。 框架在加載之前等待每個(gè)模塊完成。 如此,模塊幾乎可以自定義Nuxt的任何地方。 我們可以使用功能強(qiáng)大的 Hookable Nuxt.js系統(tǒng)來(lái)完成特定事件的任務(wù)。

最重要的是, Nuxt模塊可以合并到npm包中。 這使得它們易于跨項(xiàng)目開(kāi)發(fā)重用并與Nuxt社區(qū)共享, 我們可以創(chuàng)建一個(gè)高質(zhì)量的Nuxt附加組件生態(tài)系統(tǒng)。

如果你:

  • 是優(yōu)秀團(tuán)隊(duì)的成員,需要快速引導(dǎo)新項(xiàng)目。
  • 厭倦了為集成Google Analytics等常見(jiàn)任務(wù)重新造輪子。
  • 是一個(gè)優(yōu)秀的開(kāi)源愛(ài)好者,希望輕松與社區(qū)分享您的工作。
  • 是一家重視質(zhì)量和可重用性的企業(yè)公司的成員。
  • 通常是在短期限內(nèi)完成,沒(méi)有時(shí)間深入了解每個(gè)新庫(kù)或集成的細(xì)節(jié)。
  • 厭倦了處理對(duì)低級(jí)接口的重大改變,并且需要能夠正常工作的東西。

Nuxt.js 模塊列表

Nuxt.js 團(tuán)隊(duì)提供 官方 模塊:

  • @nuxt/http: 基于ky-universal的輕量級(jí)和通用的HTTP請(qǐng)求
  • @nuxtjs/axios: 安全和使用簡(jiǎn)單Axios與Nuxt.js集成用來(lái)請(qǐng)求HTTP
  • @nuxtjs/pwa: 使用經(jīng)過(guò)嚴(yán)格測(cè)試,更新且穩(wěn)定的PWA解決方案來(lái)增強(qiáng)Nuxt
  • @nuxtjs/auth: Nuxt.js的身份驗(yàn)證模塊,提供不同的方案和驗(yàn)證策略

Nuxt.js社區(qū)制作的模塊列表可在 https://github.com/topics/nuxt-module 中查詢

基本模塊

如上所述,模塊只是簡(jiǎn)單的功能。它們可以打包為npm模塊或直接包含在項(xiàng)目源代碼中。

modules/simple.js

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

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

moduleOptions

這是用戶使用modules數(shù)組傳遞對(duì)象,我們可以使用它來(lái)定制它的行為。

this.options

您可以使用此屬性直接訪問(wèn)Nuxt選項(xiàng)。這是nuxt.config.js,其中包含所有默認(rèn)選項(xiàng),可用于模塊之間的共享選項(xiàng)。

this.nuxt

這是對(duì)當(dāng)前Nuxt實(shí)例的引用。 請(qǐng)參考 Nuxt class docs for available methods.

this

modules中的context, 請(qǐng)參考 ModuleContainer 來(lái)查看可用的方法。

module.exports.meta

如果要將模塊發(fā)布為npm包,則需要配置此選項(xiàng)。Nuxt內(nèi)部使用meta來(lái)更好地處理您的包。

nuxt.config.js

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

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

然后,我們告訴Nuxt為項(xiàng)目加載一些特定模塊,并將可選參數(shù)作為選項(xiàng)。 請(qǐng)參考 模塊配置 文檔來(lái)查看更多!

異步模塊

并非所有模塊都會(huì)同步完成所有操作,例如:您可能希望開(kāi)發(fā)一個(gè)需要獲取某些API或執(zhí)行異步IO的模塊。為此,Nuxt支持在異步模塊中返回Promise或調(diào)用回調(diào)。

使用 async/await

請(qǐng)注意,僅在Node.js > 7.2中支持使用async / await。 因此,如果您是模塊開(kāi)發(fā)人員,至少要警告用戶使用它們時(shí)Node.js版本不能低于7.2。 對(duì)于大量異步模塊或更好的傳統(tǒng)支持,您可以使用bundler將其轉(zhuǎn)換為兼容較舊的Node.js版本或Promise方法。

import fse from 'fs-extra'

export default async function asyncModule () {
  // You can do async works here using `async`/`await`
  const pages = await fse.readJson('./pages.json')
}

返回 Promise

import axios from 'axios'

export default function asyncModule () {
  return axios.get('https://jsonplaceholder.typicode.com/users')
    .then(res => res.data.map(user => '/users/' + user.username))
    .then((routes) => {
      // Do something by extending Nuxt routes
    })
}

使用回調(diào)

import axios from 'axios'

export default function asyncModule (callback) {
  axios.get('https://jsonplaceholder.typicode.com/users')
    .then(res => res.data.map(user => '/users/' + user.username))
    .then((routes) => {
      callback()
    })
}

常見(jiàn)模塊

優(yōu)先級(jí)最高選項(xiàng)

有時(shí)在nuxt.config.js中注冊(cè)模塊時(shí)可以使用頂級(jí)選項(xiàng)更方便,這允許我們組合多個(gè)選項(xiàng)源。

nuxt.config.js

export default {
  modules: [
    ['@nuxtjs/axios', { anotherOption: true }]
  ],

  // axios module is aware of this by using `this.options.axios`
  axios: {
    option1,
    option2
  }
}

module.js

export default function (moduleOptions) {
  const options = Object.assign({}, this.options.axios, moduleOptions)
  // ...
}

提供插件

通常,模塊在添加時(shí)需提供一個(gè)或多個(gè)插件。 例如:bootstrap-vue 模塊需要將自己注冊(cè)到Vue中。 為此我們可以使用 this.addPlugin 方法。

plugin.js

import Vue from 'vue'
import BootstrapVue from 'bootstrap-vue/dist/bootstrap-vue.esm'

Vue.use(BootstrapVue)

module.js

import path from 'path'

export default function nuxtBootstrapVue (moduleOptions) {
  // Register `plugin.js` template
  this.addPlugin(path.resolve(__dirname, 'plugin.js'))
}

模板插件

已注冊(cè)的模板和插件可以利用lodash templates模板有條件地更改已注冊(cè)插件的輸出。

plugin.js

// Set Google Analytics UA
ga('create', '<%= options.ua %>', 'auto')

<% if (options.debug) { %>
// Dev only code
<% } %>

module.js

import path from 'path'

export default function nuxtBootstrapVue (moduleOptions) {
  // Register `plugin.js` template
  this.addPlugin({
    src: path.resolve(__dirname, 'plugin.js'),
    options: {
      // Nuxt will replace `options.ua` with `123` when copying plugin to project
      ua: 123,

      // conditional parts with dev will be stripped from plugin code on production builds
      debug: this.options.dev
    }
  })
}

添加CSS庫(kù)

考慮是否存在CSS庫(kù)以避免重復(fù),并添加一個(gè)選項(xiàng)來(lái)禁用模塊中的CSS庫(kù)。請(qǐng)參見(jiàn)下面的示例。

module.js

export default function (moduleOptions) {
  if (moduleOptions.fontAwesome !== false) {
    // Add Font Awesome
    this.options.css.push('font-awesome/css/font-awesome.css')
  }
}

Emit assets

我們可以注冊(cè)webpack插件用來(lái)在構(gòu)建期間發(fā)出資源。

module.js

export default function (moduleOptions) {
  const info = 'Built by awesome module - 1.3 alpha on ' + Date.now()

  this.options.build.plugins.push({
    apply (compiler) {
      compiler.plugin('emit', (compilation, cb) => {
        // This will generate `.nuxt/dist/info.txt' with contents of info variable.
        // Source can be buffer too
        compilation.assets['info.txt'] = { source: () => info, size: () => info.length }

        cb()
      })
    }
  })
}

注冊(cè)自定義 loaders

我們可以使用this.extendBuild在nuxt.config.js中執(zhí)行與build.extend相同的操作。

module.js

export default function (moduleOptions) {
    this.extendBuild((config, { isClient, isServer }) => {
      // `.foo` Loader
      config.module.rules.push({
        test: /\.foo$/,
        use: [...]
      })

      // Customize existing loaders
      // Refer to source code for Nuxt internals:
      // https://github.com/nuxt/nuxt.js/tree/dev/packages/builder/src/webpack/base.js
      const barLoader = config.module.rules.find(rule => rule.loader === 'bar-loader')
  })
}

在指定鉤子上運(yùn)行任務(wù)

您的模塊可能只需要在特定條件下執(zhí)行操作,而不僅僅是在Nuxt初始化期間。我們可以使用強(qiáng)大的Tapable插件來(lái)執(zhí)行特定事件的任務(wù)。Nuxt將等待鉤子返回Promise或被定義為async(異步)。

export default function () {
  // Add hook for modules
  this.nuxt.hook('module', (moduleContainer) => {
    // This will be called when all modules finished loading
  })

  // Add hook for renderer
  this.nuxt.hook('renderer', (renderer) => {
    // This will be called when renderer was created
  })

  // Add hook for build
  this.nuxt.hook('build', async (builder) => {
    // This will be called once when builder created

    // We can even register internal hooks here
    builder.hook('compile', ({ compiler }) => {
      // This will be run just before webpack compiler starts
    })
  })

  // Add hook for generate
  this.nuxt.hook('generate', async (generator) => {
    // This will be called when a Nuxt generate starts
  })
}

Module package commands

實(shí)驗(yàn)性的

從v2.4.0 開(kāi)始,您可以通過(guò)Nuxt模塊的包(package)添加自定義nuxt命令。為此,您必須NuxtCommand在定義命令時(shí)遵循API規(guī)則。假設(shè)放置的一個(gè)簡(jiǎn)單示例my-module/bin/command.js如下所示:

#!/usr/bin/env node

const consola = require('consola')
const { NuxtCommand } = require('@nuxt/cli')

NuxtCommand.run({
  name: 'command',
  description: 'My Module Command',
  usage: 'command <foobar>',
  options: {
    foobar: {
      alias: 'fb',
      type: 'string',
      description: 'Simple test string'
    }
  },
  run (cmd) {
    consola.info(cmd.argv)
  }
})

這里有一些值得注意的事情。首先,注意調(diào)用/usr/bin/env來(lái)檢索Node可執(zhí)行文件。另請(qǐng)注意,ES模塊語(yǔ)法不能用于命令,除非您手動(dòng)合并esm到代碼中。

接下來(lái),您將注意到如何使用NuxtCommand.run()指定命令的設(shè)置和行為。定義選項(xiàng)options,通過(guò)解析minimist。解析參數(shù)后,run()``將使用NuxtCommand`實(shí)例作為第一個(gè)參數(shù)自動(dòng)調(diào)用。

在上面的示例中,cmd.argv用于檢索解析的命令行參數(shù)。有更多的方法和屬性NuxtCommand --將提供有關(guān)它們的文檔,因?yàn)榇斯δ軐⑦M(jìn)一步測(cè)試和改進(jìn)。

要使您的命令可以通過(guò)Nuxt CLI識(shí)別bin,請(qǐng)使用nuxt-module約定將其列在package.json的部分下,該約定module與您的包名稱相關(guān)。使用此二進(jìn)制文件,您可以根據(jù)argv需要進(jìn)一步解析更多subcommands命令。

{
  "bin": {
    "nuxt-foobar": "./bin/command.js"
  }
}

一旦安裝了軟件包(通過(guò)NPM或Yarn),您就可以nuxt foobar ...在命令行上執(zhí)行。

modules有許多鉤子和可能性。請(qǐng)參考 Nuxt Internals 了解有關(guān)Nuxt內(nèi)部API的更多信息。


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)