返回介绍

开场白

开始使用

API

配置

部署

其他

模块

发布于 2019-12-01 05:33:28 字数 9563 浏览 1105 评论 0 收藏 0

模块是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

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

// REQUIRED if publishing as an npm package
// 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

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

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

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

异步模块

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

使用 async/await

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

使用回调

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库以避免重复,并添加一个选项来禁用模块中的CSS库。请参见下面的示例。

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

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

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()
      })
    }
  })
}

注册自定义 loaders

我们可以使用this.extendBuildnuxt.config.js中执行与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')
  })
}

在指定钩子上运行任务

您的模块可能只需要在特定条件下执行操作,而不仅仅是在Nuxt初始化期间。我们可以使用强大的Tapable插件来执行特定事件的任务。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

实验性的

v2.4.0 开始,您可以通过Nuxt模块的包(package)添加自定义nuxt命令。为此,您必须NuxtCommand在定义命令时遵循API规则。假设放置的一个简单示例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)
  }
})

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

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

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

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

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

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文