• 模块
    • 介绍
    • Nuxt.js 模块列表
    • 基本模块
    • 异步模块
      • 使用 async/await
      • 返回 Promise
      • 使用回调
    • 常见模块
      • 优先级最高选项
      • 提供插件
      • 模板插件
      • 添加CSS库
      • Emit assets
      • 注册自定义 loaders
    • 在指定钩子上运行任务
    • Module package commands

    模块

    模块是Nuxt.js扩展,可以扩展其核心功能并添加无限的集成。

    介绍

    在使用Nuxt开发应用程序时,您很快就会发现框架的核心功能还不够。 Nuxt可以使用配置选项和插件进行扩展,但是在多个项目中维护这些自定义是繁琐、重复和耗时的。 另一方面,开箱即用支持每个项目的需求将使Nuxt非常复杂且难以使用。

    这就是Nuxt提供更高阶模块系统的原因,可以轻松扩展核心。 模块只是在引导Nuxt时按顺序调用的函数。 框架在加载之前等待每个模块完成。 如此,模块几乎可以自定义Nuxt的任何地方。 我们可以使用功能强大的 Hookable Nuxt.js系统来完成特定事件的任务。

    最重要的是, Nuxt模块可以合并到npm包中。 这使得它们易于跨项目开发重用并与Nuxt社区共享, 我们可以创建一个高质量的Nuxt附加组件生态系统。

    如果你:

    • 优秀团队的成员,需要快速引导新项目。
    • 厌倦了为集成Google Analytics等常见任务重新造轮子。
    • 是一个优秀的开源爱好者,希望轻松与社区分享您的工作。
    • 是一家重视质量可重用性企业公司的成员。
    • 通常是在短期限内完成,没有时间深入了解每个新库或集成的细节。
    • 厌倦了处理对低级接口的重大改变,并且需要能够正常工作的东西。

    Nuxt.js 模块列表

    Nuxt.js 团队提供 官方 模块:

    • @nuxt/http: 基于ky-universal的轻量级和通用的HTTP请求
    • @nuxtjs/axios: 安全和使用简单Axios与Nuxt.js集成用来请求HTTP
    • @nuxtjs/pwa: 使用经过严格测试,更新且稳定的PWA解决方案来增强Nuxt
    • @nuxtjs/auth: Nuxt.js的身份验证模块,提供不同的方案和验证策略 Nuxt.js社区制作的模块列表可在 https://github.com/topics/nuxt-module 中查询

    基本模块

    如上所述,模块只是简单的功能。它们可以打包为npm模块或直接包含在项目源代码中。

    modules/simple.js

    1. export default function SimpleModule (moduleOptions) {
    2. // Write your code here
    3. }
    4. // REQUIRED if publishing as an npm package
    5. // module.exports.meta = require('./package.json')

    moduleOptions

    这是用户使用modules数组传递对象,我们可以使用它来定制它的行为。

    this.options

    您可以使用此属性直接访问Nuxt选项。这是nuxt.config.js,其中包含所有默认选项,可用于模块之间的共享选项。

    this.nuxt

    这是对当前Nuxt实例的引用。 请参考 Nuxt class docs for available methods.

    this

    modules中的context, 请参考 ModuleContainer 来查看可用的方法。

    module.exports.meta

    如果要将模块发布为npm包,则需要配置此选项。Nuxt内部使用meta来更好地处理您的包。

    nuxt.config.js

    1. export default {
    2. modules: [
    3. // Simple usage
    4. '~/modules/simple'
    5. // Passing options
    6. ['~/modules/simple', { token: '123' }]
    7. ]
    8. }

    然后,我们告诉Nuxt为项目加载一些特定模块,并将可选参数作为选项。 请参考 模块配置 文档来查看更多!

    异步模块

    并非所有模块都会同步完成所有操作,例如:您可能希望开发一个需要获取某些API或执行异步IO的模块。为此,Nuxt支持在异步模块中返回Promise或调用回调。

    使用 async/await

    请注意,仅在Node.js > 7.2中支持使用async / await。 因此,如果您是模块开发人员,至少要警告用户使用它们时Node.js版本不能低于7.2。 对于大量异步模块或更好的传统支持,您可以使用bundler将其转换为兼容较旧的Node.js版本或Promise方法。

    1. import fse from 'fs-extra'
    2. export default async function asyncModule() {
    3. // You can do async works here using `async`/`await`
    4. let pages = await fse.readJson('./pages.json')
    5. }

    返回 Promise

    1. import axios from 'axios'
    2. export default function asyncModule() {
    3. return axios.get('https://jsonplaceholder.typicode.com/users')
    4. .then(res => res.data.map(user => '/users/' + user.username))
    5. .then(routes => {
    6. // Do something by extending Nuxt routes
    7. })
    8. }

    使用回调

    1. import axios from 'axios'
    2. export default function asyncModule(callback) {
    3. axios.get('https://jsonplaceholder.typicode.com/users')
    4. .then(res => res.data.map(user => '/users/' + user.username))
    5. .then(routes => {
    6. callback()
    7. })
    8. }

    常见模块

    优先级最高选项

    有时在nuxt.config.js中注册模块时可以使用顶级选项更方便,这允许我们组合多个选项源。

    nuxt.config.js

    1. export default {
    2. modules: [
    3. ['@nuxtjs/axios', { anotherOption: true }]
    4. ],
    5. // axios module is aware of this by using `this.options.axios`
    6. axios: {
    7. option1,
    8. option2
    9. }
    10. }

    module.js

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

    提供插件

    通常,模块在添加时需提供一个或多个插件。 例如:bootstrap-vue 模块需要将自己注册到Vue中。 为此我们可以使用 this.addPlugin 方法。

    plugin.js

    1. import Vue from 'vue'
    2. import BootstrapVue from 'bootstrap-vue/dist/bootstrap-vue.esm'
    3. Vue.use(BootstrapVue)

    module.js

    1. import path from 'path'
    2. export default function nuxtBootstrapVue (moduleOptions) {
    3. // Register `plugin.js` template
    4. this.addPlugin(path.resolve(__dirname, 'plugin.js'))
    5. }

    模板插件

    已注册的模板和插件可以利用lodash templates模板有条件地更改已注册插件的输出。

    plugin.js

    1. // Set Google Analytics UA
    2. ga('create', '<%= options.ua %>', 'auto')
    3. <% if (options.debug) { %>
    4. // Dev only code
    5. <% } %>

    module.js

    1. import path from 'path'
    2. export default function nuxtBootstrapVue (moduleOptions) {
    3. // Register `plugin.js` template
    4. this.addPlugin({
    5. src: path.resolve(__dirname, 'plugin.js'),
    6. options: {
    7. // Nuxt will replace `options.ua` with `123` when copying plugin to project
    8. ua: 123,
    9. // conditional parts with dev will be stripped from plugin code on production builds
    10. debug: this.options.dev
    11. }
    12. })
    13. }

    添加CSS库

    考虑是否存在CSS库以避免重复,并添加一个选项来禁用模块中的CSS库。请参见下面的示例。

    module.js

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

    Emit assets

    我们可以注册webpack插件用来在构建期间发出资源。

    module.js

    1. export default function (moduleOptions) {
    2. const info = 'Built by awesome module - 1.3 alpha on ' + Date.now()
    3. this.options.build.plugins.push({
    4. apply (compiler) {
    5. compiler.plugin('emit', (compilation, cb) => {
    6. // This will generate `.nuxt/dist/info.txt' with contents of info variable.
    7. // Source can be buffer too
    8. compilation.assets['info.txt'] = { source: () => info, size: () => info.length }
    9. cb()
    10. })
    11. }
    12. })
    13. }

    注册自定义 loaders

    我们可以使用this.extendBuildnuxt.config.js中执行与build.extend相同的操作。

    module.js

    1. export default function (moduleOptions) {
    2. this.extendBuild((config, { isClient, isServer }) => {
    3. // `.foo` Loader
    4. config.module.rules.push({
    5. test: /\.foo$/,
    6. use: [...]
    7. })
    8. // Customize existing loaders
    9. // Refer to source code for Nuxt internals:
    10. // https://github.com/nuxt/nuxt.js/tree/dev/packages/builder/src/webpack/base.js
    11. const barLoader = config.module.rules.find(rule => rule.loader === 'bar-loader')
    12. })
    13. }

    在指定钩子上运行任务

    您的模块可能只需要在特定条件下执行操作,而不仅仅是在Nuxt初始化期间。我们可以使用强大的Tapable插件来执行特定事件的任务。Nuxt将等待钩子返回Promise或被定义为async(异步)。

    1. export default function () {
    2. // Add hook for modules
    3. this.nuxt.hook('module', moduleContainer => {
    4. // This will be called when all modules finished loading
    5. })
    6. // Add hook for renderer
    7. this.nuxt.hook('renderer', renderer => {
    8. // This will be called when renderer was created
    9. })
    10. // Add hook for build
    11. this.nuxt.hook('build', async builder => {
    12. // This will be called once when builder created
    13. // We can even register internal hooks here
    14. builder.hook('compile', ({compiler}) => {
    15. // This will be run just before webpack compiler starts
    16. })
    17. })
    18. // Add hook for generate
    19. this.nuxt.hook('generate', async generator => {
    20. // This will be called when a Nuxt generate starts
    21. })
    22. }

    Module package commands

    实验性的

    v2.4.0 开始,您可以通过Nuxt模块的包(package)添加自定义nuxt命令。为此,您必须NuxtCommand在定义命令时遵循API规则。假设放置的一个简单示例my-module/bin/command.js如下所示:

    1. #!/usr/bin/env node
    2. const consola = require('consola')
    3. const { NuxtCommand } = require('@nuxt/cli')
    4. NuxtCommand.run({
    5. name: 'command',
    6. description: 'My Module Command',
    7. usage: 'command <foobar>',
    8. options: {
    9. foobar: {
    10. alias: 'fb',
    11. type: 'string',
    12. description: 'Simple test string'
    13. }
    14. },
    15. run(cmd) {
    16. consola.info(cmd.argv)
    17. }
    18. })

    这里有一些值得注意的事情。首先,注意调用/usr/bin/env来检索Node可执行文件。另请注意,ES模块语法不能用于命令,除非您手动合并esm到代码中。

    接下来,您将注意到如何使用NuxtCommand.run()指定命令的设置和行为。定义选项options,通过解析minimist。解析参数后,run()`将使用</code>NuxtCommand实例作为第一个参数自动调用。

    在上面的示例中,cmd.argv用于检索解析的命令行参数。有更多的方法和属性NuxtCommand —将提供有关它们的文档,因为此功能将进一步测试和改进。

    要使您的命令可以通过Nuxt CLI识别bin,请使用nuxt-module约定将其列在package.json的部分下,该约定module与您的包名称相关。使用此二进制文件,您可以根据argv需要进一步解析更多subcommands命令。

    1. {
    2. "bin": {
    3. "nuxt-foobar": "./bin/command.js"
    4. }
    5. }

    一旦安装了软件包(通过NPM或Yarn),您就可以nuxt foobar …在命令行上执行。

    modules有许多钩子和可能性。请参考 Nuxt Internals 了解有关Nuxt内部API的更多信息。