Nuxt3 的生命周期和钩子函数(五)

avatar
cmdragon 破虚
image image

扫码关注或者微信搜一搜:编程智域 前端至全栈交流与成长

钩子:build:done

参数:nuxtApp

环境:Nuxt.js

描述:build:done是 Nuxt.js 的一个生命周期钩子,它在应用的打包构建过程完成后被调用。这个钩子允许开发者在构建过程结束后执行一些后续操作,比如清理临时文件、生成额外的资源或者通知外部服务构建完成。

详细解释与用法:

  • 参数说明:nuxtApp参数是 Nuxt 应用实例的引用,它提供了对 Nuxt 应用的配置和内部状态的访问。
  • 使用场景:通常用于执行构建后的清理工作,或者对构建结果进行最后的修改。
  • 调用时机:在 Nuxt 的构建过程完全结束后,即所有文件都被编译和优化之后。

案例Demo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.hook('build:done', async (builder) => {
// 示例:构建完成后,打印构建信息
console.log('构建完成!构建信息如下:');
console.log(builder.stats);

// 示例:清理构建目录中的临时文件
await cleanUpTemporaryFiles();

// 示例:发送构建完成的通知
await notifyBuildCompletion();
});

async function cleanUpTemporaryFiles() {
// 这里是清理临时文件的逻辑
// 例如使用 Node.js 的 fs 模块来删除文件
const fs = require('fs');
const path = require('path');
const tempFilePath = path.join(__dirname, 'temp-file.txt');

if (fs.existsSync(tempFilePath)) {
fs.unlinkSync(tempFilePath);
console.log('临时文件已清理');
}
}

async function notifyBuildCompletion() {
// 这里是通知构建完成的逻辑
// 例如发送 HTTP 请求到某个服务
const axios = require('axios');
await axios.post('https://example.com/build-completed', {
message: '构建完成'
});
console.log('构建完成通知已发送');
}
});

在这个案例中,build:done钩子被用来打印构建信息、清理临时文件,以及向外部服务发送构建完成的通知。这些操作有助于确保构建过程的完整性和后续的自动化流程。

钩子:build:manifest

参数:manifest

环境:Vite 或 Webpack (用于服务端渲染的框架)

描述:build:manifest是 Vite 或 Webpack 在构建过程中生成清单(manifest.json)时调用的钩子。清单文件通常包含了应用中所有静态资源的哈希值,以便浏览器缓存管理和服务器预加载。在
Nuxt.js 中,通过这个钩子,开发者可以自定义 Nitro(Vite 的预渲染服务)在 HTML 中渲染的<link>标签,以及影响资源的缓存策略。

详细解释与用法:

  • 参数说明:manifest是一个对象,包含了当前构建的清单内容,包括文件名、哈希值、版本等信息。
  • 使用场景:可以根据需要修改清单,比如添加或删除特定资源,或者更改资源的缓存策略。
  • 示例用法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.hook('build:manifest', async (manifest) => {
// 示例:修改清单中的资源哈希值
manifest['assets/images/my-image.png'].hash = 'new-hash-for-image';

// 示例:添加自定义的清单项
manifest['custom-manifest'] = {
url: '/custom-manifest.json',
revision: manifest.revision,
hash: 'custom-manifest-hash'
};

// 示例:处理 Nitro 预渲染的 `<link>` 标签
if (nuxtApp.isServer) {
const html = nuxtApp.renderToString();
const modifiedHtml = html.replace(
'<link rel="preload" href="/manifest.json">',
'<link rel="preload" href="/custom-manifest.json">'
);
nuxtApp.render(modifiedHtml);
}
});
});

在这个案例中,build:manifest钩子被用来:

  1. 修改my-image.png的哈希值,这可能会影响浏览器缓存。
  2. 添加一个自定义的清单项,如custom-manifest.json
  3. 如果是在服务器端渲染(SSR)环境中,替换 Nitro 预渲染时使用的清单文件路径。

请注意,Vite 和 Webpack 的具体用法可能略有不同,但基本原理相似,都是在构建阶段对清单进行定制。

钩子:builder:generateApp

参数:options

环境:Nuxt.js 用于生成静态站点或预构建应用

描述:builder:generateApp是 Nuxt.js 在执行nuxt generatenuxt build --generate
命令,即生成应用程序(如静态站点)之前调用的钩子。这个钩子允许开发者在生成过程开始时对生成的文件结构、内容或配置进行定制。

详细解释与用法:

  • 参数说明:options是一个对象,包含了生成应用时的配置和环境信息,如输出目录、模式(spa、ssr)、路由等。

  • 应用场景:

    • 可以修改输出目录或文件名,如重命名文件、创建子目录结构。
    • 可以根据生成环境(如开发、生产)动态调整内容或配置。
    • 可能会用到options.context,它提供了生成过程中的上下文信息,如当前路由、页面数据等。

示例用法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.hook('builder:generateApp', async (options) => {
// 示例:修改输出目录
options.outputDir = 'custom-output';

// 示例:根据环境添加不同的内容
if (options.mode === 'spa') {
options.content.push({
path: 'custom-spa-page.html',
template: '<h1>Custom SPA Page</h1>'
});
} else {
options.pages['/custom-server-page.vue'] = {
template: '<h1>Custom Server Page</h1>'
};
}

// 示例:使用 context 获取当前路由信息
const currentRoute = options.context.route;
if (currentRoute.name === 'my-custom-route') {
// 添加或修改特定路由的页面内容
}
});
});

在这个案例中,builder:generateApp钩子被用来:

  1. 修改生成的输出目录。
  2. 根据应用模式(SPA 或 SSR)动态添加或修改生成的内容。
  3. 利用context获取当前路由信息,可能用于根据路由条件调整生成的页面。

请确保在实际使用时,遵循 Nuxt.js 的最佳实践和API规范。

钩子:builder:watch

参数:event, path

环境:Nuxt.js 开发环境

描述:builder:watch是 Nuxt.js
在开发环境中使用的钩子,当文件系统监视器检测到项目中的文件或目录发生变化时,此钩子会被调用。这个钩子允许开发者在文件变化时执行自定义逻辑,例如清除缓存、触发自定义构建步骤等。

详细解释与用法:

  • 参数说明:

    • event:一个字符串,表示文件变化的类型,通常是add,change, 或unlink(删除)。
    • path:一个字符串,表示发生变化文件的路径。
  • 应用场景:

    • 当文件被修改时,清除某些缓存或临时文件。
    • 当文件被添加或删除时,触发某些自定义的构建或编译过程。

示例用法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.hook('builder:watch', (event, path) => {
// 当文件发生变化时执行的操作
if (event === 'change') {
console.log(`文件 ${path} 发生了变化,需要执行某些操作。`);
// 例如,清除缓存
// nuxtApp.cache.verify();
} else if (event === 'add') {
console.log(`文件 ${path} 被添加了。`);
// 触发自定义构建步骤
// customBuildStep(path);
} else if (event === 'unlink') {
console.log(`文件 ${path} 被删除了。`);
// 可能需要清理一些与该文件相关的资源
// cleanUpResources(path);
}
});
});

在这个案例中,builder:watch钩子被用来:

  1. 监听文件变化事件,并根据事件类型打印消息。
  2. 根据文件变化类型执行不同的操作,例如清除缓存、触发自定义构建步骤或清理资源。

请注意,在实际使用中,应谨慎使用此钩子,因为过多的自定义操作可能会影响开发服务器的性能。

钩子:pages:extend

参数:pages

环境:Nuxt.js 应用开发环境

描述:pages:extend是 Nuxt.js 提供的一个页面路由处理钩子,它在页面路由解析完成之后调用。这个钩子允许开发者在路由加载和配置完成后,动态修改或扩展页面路由。

详细解释与用法:

  • 参数说明:

    • pages:一个对象,包含了当前应用的所有页面路由配置,每个路由项包含路径(path)、组件(component)、元信息(meta)等属性。
  • 应用场景:

    • 动态添加或修改路由,如根据用户权限或环境配置不同的页面。
    • 根据路由路径动态设置页面的特性,如设置SEO元信息、加载时的预加载行为等。

示例用法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.hook('pages:extend', (pages) => {
// 遍历所有页面
pages.forEach((page) => {
if (page.path === '/admin') {
// 如果路径是 '/admin',添加管理员权限检查
page.meta.auth = ['admin'];
} else if (process.env.NODE_ENV === 'production') {
// 在生产环境中,对所有非 '/admin' 的页面添加预加载
page.preload = true;
}
});
});
});

在这个案例中,pages:extend钩子被用来:

  1. 遍历所有页面路由,检查路径是否为 ‘/admin’,如果是则添加meta.auth属性,表示需要管理员权限访问。
  2. 在生产环境中,对所有非 ‘/admin’ 的页面设置preloadtrue,表示在页面首次加载时预加载资源。

请注意,修改后的路由配置不会影响已经注册的页面,只会对新添加或修改的路由生效。在实际使用时,要确保对路由的修改不会破坏原有的功能。

钩子:server:devHandler:handler

参数:handler

环境:Nuxt.js 服务器端开发环境 (使用 Nitro 或者其他本地开发服务器)

描述:server:devHandler:handler是 Nuxt.js 的一个服务器端开发中间件处理钩子,它在注册开发服务器的中间件时被调用。这个钩子允许开发者自定义开发服务器的行为,特别是在处理请求和响应时。

详细解释与用法:

  • 参数说明:

    • handler:一个函数,通常接收一个req(请求对象)和res(响应对象)作为参数,可以用来处理请求,执行自定义逻辑,然后返回响应。
  • 应用场景:

    • 添加或修改开发服务器的请求处理逻辑,如添加日志记录、错误处理、性能分析等。
    • 在开发环境中实现特殊的路由或功能,如模拟 API 接口或处理特定的开发环境请求。

示例用法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.hook('server:devHandler:handler', (req, res, next) => {
// 在每次请求开始时添加日志
console.log(`Received request: ${req.url}`);

// 在处理请求前执行自定义逻辑
if (req.url === '/api/v1/development') {
// 如果是开发环境的特定API请求,模拟数据
const simulatedData = { key: 'development-data' };
res.json(simulatedData);
} else {
next(); // 继续执行默认的请求处理
}
});
});

在这个案例中,server:devHandler:handler钩子被用来:

  1. 在每次请求开始时,记录请求的URL到控制台。
  2. 检查请求URL,如果是 /api/v1/development,则返回模拟的数据,而不是实际的API请求。

请注意,这个钩子仅在开发环境中生效,且主要用于开发过程中的调试和定制,生产环境通常不需要使用。

往期文章归档: