模塊是Nuxt.js擴展,可以擴展其核心功能并添加無限的集成。
在使用Nuxt開發(fā)應用程序時,您很快就會發(fā)現(xiàn)框架的核心功能還不夠。 Nuxt可以使用配置選項和插件進行擴展,但是在多個項目中維護這些自定義是繁瑣、重復和耗時的。 另一方面,開箱即用支持每個項目的需求將使Nuxt非常復雜且難以使用。
這就是Nuxt提供更高階模塊系統(tǒng)的原因,可以輕松擴展核心。 模塊只是在引導Nuxt時按順序調(diào)用的函數(shù)。 框架在加載之前等待每個模塊完成。 如此,模塊幾乎可以自定義Nuxt的任何地方。 我們可以使用功能強大的 Hookable Nuxt.js系統(tǒng)來完成特定事件的任務。
最重要的是, Nuxt模塊可以合并到npm包中。 這使得它們易于跨項目開發(fā)重用并與Nuxt社區(qū)共享, 我們可以創(chuàng)建一個高質(zhì)量的Nuxt附加組件生態(tài)系統(tǒng)。
如果你:
Nuxt.js 團隊提供 官方 模塊:
Nuxt.js社區(qū)制作的模塊列表可在 https://github.com/topics/nuxt-module 中查詢
如上所述,模塊只是簡單的功能。它們可以打包為npm模塊或直接包含在項目源代碼中。
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ù)組傳遞對象,我們可以使用它來定制它的行為。
this.options
您可以使用此屬性直接訪問Nuxt選項。這是nuxt.config.js,其中包含所有默認選項,可用于模塊之間的共享選項。
this.nuxt
這是對當前Nuxt實例的引用。 請參考 Nuxt class docs for available methods.
this
modules中的context, 請參考 ModuleContainer 來查看可用的方法。
module.exports.meta
如果要將模塊發(fā)布為npm包,則需要配置此選項。Nuxt內(nèi)部使用meta來更好地處理您的包。
nuxt.config.js
export default {
modules: [
// Simple usage
'~/modules/simple'
// Passing options
['~/modules/simple', { token: '123' }]
]
}
然后,我們告訴Nuxt為項目加載一些特定模塊,并將可選參數(shù)作為選項。 請參考 模塊配置 文檔來查看更多!
并非所有模塊都會同步完成所有操作,例如:您可能希望開發(fā)一個需要獲取某些API或執(zhí)行異步IO的模塊。為此,Nuxt支持在異步模塊中返回Promise或調(diào)用回調(diào)。
請注意,僅在Node.js > 7.2中支持使用async / await。 因此,如果您是模塊開發(fā)人員,至少要警告用戶使用它們時Node.js版本不能低于7.2。 對于大量異步模塊或更好的傳統(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')
}
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
})
}
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()
})
}
有時在nuxt.config.js中注冊模塊時可以使用頂級選項更方便,這允許我們組合多個選項源。
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)
// ...
}
通常,模塊在添加時需提供一個或多個插件。 例如:bootstrap-vue 模塊需要將自己注冊到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'))
}
已注冊的模板和插件可以利用lodash templates模板有條件地更改已注冊插件的輸出。
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庫以避免重復,并添加一個選項來禁用模塊中的CSS庫。請參見下面的示例。
module.js
export default function (moduleOptions) {
if (moduleOptions.fontAwesome !== false) {
// Add Font Awesome
this.options.css.push('font-awesome/css/font-awesome.css')
}
}
我們可以注冊webpack插件用來在構建期間發(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()
})
}
})
}
我們可以使用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')
})
}
您的模塊可能只需要在特定條件下執(zhí)行操作,而不僅僅是在Nuxt初始化期間。我們可以使用強大的Tapable插件來執(zhí)行特定事件的任務。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
})
}
實驗性的
從v2.4.0 開始,您可以通過Nuxt模塊的包(package)添加自定義nuxt命令。為此,您必須NuxtCommand在定義命令時遵循API規(guī)則。假設放置的一個簡單示例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來檢索Node可執(zhí)行文件。另請注意,ES模塊語法不能用于命令,除非您手動合并esm到代碼中。
接下來,您將注意到如何使用NuxtCommand.run()指定命令的設置和行為。定義選項options,通過解析minimist。解析參數(shù)后,run()``將使用NuxtCommand`實例作為第一個參數(shù)自動調(diào)用。
在上面的示例中,cmd.argv用于檢索解析的命令行參數(shù)。有更多的方法和屬性NuxtCommand --將提供有關它們的文檔,因為此功能將進一步測試和改進。
要使您的命令可以通過Nuxt CLI識別bin,請使用nuxt-module約定將其列在package.json的部分下,該約定module與您的包名稱相關。使用此二進制文件,您可以根據(jù)argv需要進一步解析更多subcommands命令。
{
"bin": {
"nuxt-foobar": "./bin/command.js"
}
}
一旦安裝了軟件包(通過NPM或Yarn),您就可以nuxt foobar ...在命令行上執(zhí)行。
modules有許多鉤子和可能性。請參考 Nuxt Internals 了解有關Nuxt內(nèi)部API的更多信息。
更多建議: