You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
exportdefaultfunctionSimpleModule(moduleOptions){// Write your code here}// REQUIRED if publishing as an npm package// module.exports.meta = require('./package.json')
exportdefault{modules: [// Using package name"@nuxtjs/axios",// Relative to your project srcDir"~/modules/awesome.js",// Providing options["@nuxtjs/google-analytics",{ua: "X1234567"}],// Inline definitionfunction(){},],};
exportdefaultfunctionExampleModule(moduleOptions){console.log(moduleOptions.token);// '123'console.log(this.options.exampleMsg);// 'hello'this.nuxt.hook("ready",async(nuxt)=>{console.log("Nuxt is ready");});}// REQUIRED if publishing the module as npm packagemodule.exports.meta=require("./package.json");
异步模块
并非所有模块都会同步完成所有操作,例如:您可能希望开发一个需要获取某些 API 或执行异步 IO 的模块。为此,Nuxt 支持在异步模块中返回 Promise 或调用回调。
importfsefrom"fs-extra";exportdefaultasyncfunctionasyncModule(){// You can do async works here using `async`/`await`constpages=awaitfse.readJson("./pages.json");}
返回 Promise
importaxiosfrom"axios";exportdefaultfunctionasyncModule(){returnaxios.get("https://jsonplaceholder.typicode.com/users").then((res)=>res.data.map((user)=>`/users/${user.username}`)).then((routes)=>{// Do something by extending Nuxt routes});}
exportdefault{modules: [["@nuxtjs/axios",{anotherOption: true}]],// axios module is aware of this by using `this.options.axios`axios: {
option1,
option2,},};
// Set Google Analytics UAga('create','<%= options.ua %>','auto')<%if(options.debug){%>// Dev only code<%}%>
module.js
importpathfrom"path";exportdefaultfunctionnuxtBootstrapVue(moduleOptions){// Register `plugin.js` templatethis.addPlugin({src: path.resolve(__dirname,"plugin.js"),options: {// Nuxt will replace `options.ua` with `123` when copying plugin to projectua: 123,// conditional parts with dev will be stripped from plugin code on production buildsdebug: this.options.dev,},});}
exportdefaultfunction(moduleOptions){constinfo=`Built by awesome module - 1.3 alpha on ${Date.now()}`;this.options.build.plugins.push({apply(compiler){compiler.hooks.emit.tapAsync("emit",(compilation,cb)=>{// This will generate `.nuxt/dist/info.txt' with contents of info variable.// Source can be buffer toocompilation.assets["info.txt"]={source: ()=>info,size: ()=>info.length,};cb();});},});}
exportdefaultfunction(){// Add hook for modulesthis.nuxt.hook('modules:done',moduleContainer=>{// This will be called when all modules finished loading})// Add hook for rendererthis.nuxt.hook('render:before',renderer=>{// Called after the renderer was created})// Add hook for build:extendRoutesthis.nuxt.hook('build:extendRoutes',asyncroutes=>{// This will be called after routes created})// Add hook for build:compilethis.nuxt.hook('build:compile',async{compiler}=>{// This will be run just before webpack compiler starts})// Add hook for generatethis.nuxt.hook('generate:before',asyncgenerator=>{// This will be called before Nuxt generates your pages})}
上面仅列出了一部分 hooks,请参考 Nuxt Internals 了解有关 Nuxt 内部 API 的更多信息。
import{accessSync,constants,readFileSync,writeFileSync}from'fs'import{resolve}from'path'import{DIRECTORY_NAME,INJECT_SCRIPT_FILE_NAME,INJECT_STYLE_FILE_NAME,JSON_FILE_NAME,NOTIFICATION_ANCHOR_CLASS_NAME,generateJSONFileContent,generateJsFileContent,getFileHash,getVersion,get__Dirname}from'@plugin-web-update-notification/core'constpluginName='WebUpdateNotificationPlugin'/** * It injects the hash into the HTML, and injects the notification anchor and the stylesheet and the * script into the HTML * @param {string} html - The original HTML of the page * @param {string} version - The hash of the current commit * @param {Options} options - Options * @returns The html of the page with the injected script and css. */functioninjectPluginHtml(html='',version='',options={},{ cssFileHash ='', jsFileHash =''}){const{
customNotificationHTML,
hiddenDefaultNotification,
injectFileBase ='/'}=optionsconstversionScript=`<script>window.pluginWebUpdateNotice_version = '${version}';</script>`constcssLinkHtml=customNotificationHTML||hiddenDefaultNotification
? ''
: `<link rel="stylesheet" href="${injectFileBase}${DIRECTORY_NAME}/${INJECT_STYLE_FILE_NAME}.${cssFileHash}.css">`letres=htmlres=res.replace('<head>',`<head>${cssLinkHtml} <script src="${injectFileBase}${DIRECTORY_NAME}/${INJECT_SCRIPT_FILE_NAME}.${jsFileHash}.js"></script>${versionScript}`)if(!hiddenDefaultNotification){res=res.replace('</body>',`<div class="${NOTIFICATION_ANCHOR_CLASS_NAME}"></div></body>`)}returnres}exportdefaultfunctionWebUpdateNotificationPlugin(moduleOptions={}){// this 为 modules 中的 context// 所有的 nuxt 的配置项constoptions=this.options// 对当前 nuxt 实例的引用constnuxt=this.nuxt/** inject script file hash */letjsFileHash=''/** inject css file hash */letcssFileHash=''// 版本信息letversion=''// 留一个函数 shouldBeEnable 可以判断是否开启if(typeofmoduleOptions.shouldBeEnable==='function'){constenable=moduleOptions.shouldBeEnable(options)if(!enable){return}}// Emit assets: 注册 webpack 插件在构建期间发出资源options.build.plugins.push({apply(compiler){// 仅执行一次标识 (client 和 server 会分别走一次,不用再走服务端一次)if(compiler.options.name!=='client'){return}const{ publicPath }=compiler.options.outputif(moduleOptions.injectFileBase===undefined)moduleOptions.injectFileBase=typeofpublicPath==='string' ? publicPath : '/'const{ hiddenDefaultNotification, versionType, customVersion, silence }=moduleOptionsif(versionType==='custom')version=getVersion(versionType,customVersion)elseversion=getVersion(versionType)compiler.hooks.emit.tap(pluginName,(compilation)=>{// const outputPath = compiler.outputPathconstjsonFileContent=generateJSONFileContent(version,silence)// @ts-expect-errorcompilation.assets[`${DIRECTORY_NAME}/${JSON_FILE_NAME}.json`]={source: ()=>jsonFileContent,size: ()=>jsonFileContent.length}if(!hiddenDefaultNotification){constinjectStyleContent=readFileSync(`${get__Dirname()}/${INJECT_STYLE_FILE_NAME}.css`,'utf8')cssFileHash=getFileHash(injectStyleContent)// @ts-expect-errorcompilation.assets[`${DIRECTORY_NAME}/${INJECT_STYLE_FILE_NAME}.${cssFileHash}.css`]={source: ()=>injectStyleContent,size: ()=>injectStyleContent.length}}constfilePath=resolve(`${get__Dirname()}/${INJECT_SCRIPT_FILE_NAME}.js`)constinjectScriptContent=generateJsFileContent(readFileSync(filePath,'utf8').toString(),version,moduleOptions// 传入 module 的参数控制)jsFileHash=getFileHash(injectScriptContent)// @ts-expect-errorcompilation.assets[`${DIRECTORY_NAME}/${INJECT_SCRIPT_FILE_NAME}.${jsFileHash}.js`]={source: ()=>injectScriptContent,size: ()=>injectScriptContent.length}})}})// Hook on generation finishednuxt.hook('generate:done',async(generator)=>{consthtmlFilePath=resolve(generator.distPath,moduleOptions.indexHtmlFilePath||'./index.html'// 可以自定义写入要 inject 的 html 地址)try{accessSync(htmlFilePath,constants.F_OK)lethtml=readFileSync(htmlFilePath,'utf8')html=injectPluginHtml(html,version,moduleOptions,{
jsFileHash,
cssFileHash
})writeFileSync(htmlFilePath,html)}catch(error){console.error(error)console.error(`${pluginName} failed to inject the plugin into the HTML file. index.html(${htmlFilePath}) not found.`)}})}
Modules
模块是 Nuxt.js 扩展,可以扩展其核心功能并添加无限的集成。
在使用 Nuxt 开发应用程序时,您很快就会发现框架的核心功能还不够。 Nuxt 可以使用配置选项和插件进行扩展,但是在多个项目中维护这些自定义是繁琐、重复和耗时的。 另一方面,开箱即用支持每个项目的需求将使 Nuxt 非常复杂且难以使用。
这就是 Nuxt 提供高阶模块系统使得扩展核心成为可能的原因之一。模块是启动 Nuxt 时顺序调用的函数。框架等待每个模块完成后再继续。通过这种方式,模块几乎可以定制项目的任何方面。由于 Nuxt 的模块化设计(基于 webpack 的 Tapable ),模块可以轻松地为某些入口点(例如构建器初始化)注册钩子。模块还可以覆盖模板、配置 webpack 加载器、添加 CSS 库以及执行许多其他有用的任务。我们可以使用功能强大的 Hookable Nuxt.js 系统来完成特定事件的任务。
最重要的是,Nuxt 模块可以合并到 npm 包中。这使得跨项目重用并与社区共享成为可能,从而帮助创建高质量附加组件的生态系统。
如果你:
Nuxt.js 模块列表
Nuxt.js 团队提供 官方 模块:
Nuxt.js 社区制作的模块列表可在 https://github.com/topics/nuxt-module 中查询
基础模块
如下所示,一个模块只需要导出一个默认函数即可,当模块需要做一些异步操作时,可以返回 Promise 对象或者传入 callback 参数,此处推荐使用
async/await
直接返回 Promise 对象。modules/simple.js
在模块中,通常会使用到以下变量:
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
模块需要在 nuxt.config.js 中通过 modules 注册,对于 npm 安装的模块可以直接使用包名,对于项目代码中的模块,可以使用相对路径,使用
@
别名,将从项目srcDir
解析,我们还可以为模块提供额外的参数。编写自己的模块
模块就是函数。它们可以打包为 npm 模块或直接包含在项目源代码中。
异步模块
并非所有模块都会同步完成所有操作,例如:您可能希望开发一个需要获取某些 API 或执行异步 IO 的模块。为此,Nuxt 支持在异步模块中返回 Promise 或调用回调。
使用 async/await
返回 Promise
使用回调
常见模块
优先级最高选项
有时在
nuxt.config.js
中注册模块时可以使用顶级选项更方便,这允许我们组合多个选项源。nuxt.config.js
module.js
注册插件
通常,我们会在 nuxt.config.js 中配置 plugins 来注册插件,但如果我们想在模块中集成这部分功能,就需要用到
this.addPlugin
方法。vantLoadPlugin.js
vantLoadModule.js
模板插件
插件会在 @nuxt/builder 中通过 lodash template 方法进行模板编译,因此可以在注册插件时提供 options 做为模板编译参数使用,此时 addPlugin 参数对象 src 属性为插件地址。
plugin.js
module.js
注册 webpack loader
我们可以使用 this.extendBuild 在 nuxt.config.js 中执行与 build.extend 相同的操作。
注册 webpack 插件
我们可以注册 webpack 插件用来在构建期间发出资源。需要了解 webpack 构建原理以及插件开发。
上面的模块为 webpack 添加了一个新 plugin,监听了 compiler 的 emit hooks,在生成资源到 output 目录之前添加了一个新的输出资源 info.txt。
为构建提供扩展配置
我们可以使用
this.extendBuild
为客户端和服务端的构建配置进行手工的扩展处理,这与nuxt.config.js
中的build.extend
属性含义相同。该扩展方法会服务端和客户端打包构建分别被调用,该方法的参数如下:isDev
,isClient
,isServer
上面的模块为构建提供了扩展配置,在客户端时构建时,开发环境配置 source-map ,非开发环境配置 vue runtime 不参与打包。您还可以使用暴露的 webpack 对象进行更加高级的操作。
nuxt 生命周期注册钩子
this.nuxt
:这是对当前 Nuxt 实例的引用。我们可以在某些生命周期事件上注册钩子。就绪:Nuxt 已准备好工作(模块容器和渲染器已就绪)。
错误:调用钩子时出现未处理的错误。
关闭:Nuxt 实例正在正常关闭。
Listen:Nuxt 内部服务器开始监听。 (使用 nuxt start 或 nuxt dev)
this
:模块的上下文。所有模块都将在 ModuleContainer 实例的上下文中调用。请查看 ModuleContainer 类文档以获取可用的方法。
在指定钩子上执行任务
您的模块可能只需要在特定条件下执行操作,而不仅仅是在 Nuxt 初始化期间。我们可以使用Hookable Nuxt.js 系统来完成特定事件的任务。Nuxt 将等待钩子返回
Promise
或被定义为async
(异步)。上面仅列出了一部分 hooks,请参考 Nuxt Internals 了解有关 Nuxt 内部 API 的更多信息。
Nuxt 的 hooks 功能来自 hable 模块,Nuxt 类本身继承了 hable,所以在模块中可以使用 this.nuxt 注册和调用。
来个实战
根治 ———— nuxt 项目遇到的,网页重新部署,通知用户。
nuxt.config.js
webUpdateNotification.js
调试
教你调试 nuxt modules。
由于文档并不能全面了解 Nuxt 构建过程,所以很多时候需要查看 Nuxt 源码,这里提供些小技巧给大家。
我们可以在项目目录中执行 nuxt 命令,其实是因为npm install nuxt 过程中在 ~/node_modules/.bin 下添加了 nuxt 启动文件,内容如下所示:
~/node_modules/.bin/nuxt
可以看到最终执行了 /../nuxt/bin/nuxt.js
~/node_modules/nuxt/bin/nuxt.js
又调用了 @nuxt/cli ,查看 @nuxt/cli package.json 中 main 属性可知,入口文件为 ./dist/cli.js。结合 cli.js 中的逻辑可以确定,nuxt 入口文件就在这里,根据 nuxt 命令参数的不同,会分别调用 ./cli-dev.js 和 ./cli-generate.js
虽然确定了入口文件,但仅通过 console 的方式很难调试代码,还好 vscode 内置了调试功能,可以方便的调试 JS 代码。
参考
这里还有更多关于 nuxt
The text was updated successfully, but these errors were encountered: