webpack html 模板插值,vue-ssr问题

本文总结了Vue服务端渲染(SSR)的关键要点,包括版本一致性、生命周期特性、模板插值、全局环境变量避免使用、状态单例问题规避、异步组件使用、状态处理方式、热加载实现以及Webpack打包注意事项。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

405ad901e9b6?utm_campaign=maleskine...&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

image.png

vue ssr的问题总结

vue与vue-server-renderer的版本必须一致,否则会报错:

405ad901e9b6?utm_campaign=maleskine...&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

2.模板中必须要加入

该注释是vue-ssr的默认内容注入入口,相关源码如下:

405ad901e9b6?utm_campaign=maleskine...&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

image.png

默认是使用该注释作为注入入口,如果没有添加该注释,就会报错 'Content placeholder not found in template'

而且做了兼容,如果没有找到标签,就会找到

标签,如果还是没找到,就会用 所在位置

3.生命周期

由于没有动态更新,所有的生命周期钩子函数中,只有 beforeCreate 和 created 会在服务器端渲染(SSR)过程中被调用。这就是说任何其他生命周期钩子函数中的代码(例如 beforeMount 或 mounted),只会在客户端执行。

此外还需要注意的是,你应该避免在 beforeCreate 和 created 生命周期时产生全局副作用的代码,例如在其中使用 setInterval 设置 timer。在纯客户端(client-side only)的代码中,我们可以设置一个 timer,然后在 beforeDestroy或 destroyed 生命周期时将其销毁。但是,由于在 SSR 期间并不会调用销毁钩子函数,所以 timer 将永远保留下来。为了避免这种情况,请将副作用代码移动到 beforeMount 或 mounted 生命周期中。

4.模板插值

模板还支持简单插值。给定如下模板:

{{ title }}

{{{ meta }}}

我们可以通过传入一个"渲染上下文对象",作为 renderToString 函数的第二个参数,来提供插值数据:

const context = {

title: 'hello',

meta: `

`

}

renderer.renderToString(app, context, (err, html) => {

// page title will be "Hello"

// with meta tags injected

})

5.不可使用全局环境变量

因为代码会运行在node环境中,所以注意不要使用window或者document等依赖浏览器环境的环境变量

6.避免状态单例

当编写纯客户端(client-only)代码时,我们习惯于每次在新的上下文>中对代码进行取值。但是,Node.js 服务器是一个长期运行的进程。>当我们的代码进入该进程时,它将进行一次取值并留存在内存中。这

意味着如果创建一个单例对象,它将在每个传入的请求之间共享。

如果我们在多个请求之间使用一个共享的实例,很容易导致交叉请求状态污染(cross-request state pollution)。

因此,我们不应该直接创建一个应用程序实例,而是应该暴露一个可以重复执行的工厂函数,为每个请求创建新的应用程序实例:

// app.js

const Vue = require('vue')

module.exports = function createApp (context) {

return new Vue({

data: {

url: context.url

},

template: `

访问的 URL 是: {{ url }}
`

})

}

并且我们的服务器代码现在变为:

// server.js

const createApp = require('./app')

server.get('*', (req, res) => {

const context = { url: req.url }

const app = createApp(context)

renderer.renderToString(app, (err, html) => {

// 处理错误……

res.end(html)

})

})

同样的规则也适用于 router、store 和 event bus 实例。你不应该直接从模块导出并将其导入到应用程序中,而是需要在 createApp 中创建一个新的实例,并从根 Vue 实例注入。

7.renderToString的注意点

如果在renderer创建的时候就传入了template,如下:

var renderer = serverRender.createRenderer({

template: require('fs').readFileSync(path.resolve(__dirname, '../index.ssr.html'), 'utf-8')

})

8.异步加载组件

在 Vue 2.5 以下的版本中,服务端渲染时异步组件只能用在路由组件上。然而在 2.5+ 的版本中,得益于核心算法的升级,异步组件现在可以在应用中的任何地方使用。

需要注意的是,你任然需要在挂载 app 之前调用 router.onReady,因为路由器必须要提前解析路由配置中的异步组件,才能正确地调用组件中可能存在的路由钩子。

9.状态处理

获取的数据需要位于视图组件之外,即放置在专门的数据预取存储容器(data store)或"状态容器(state container))"中。首先,在服务器端,我们可以在渲染之前预取数据,并将数据填充到 store 中。此外,我们将在 HTML 中序列化(serialize)和内联预置(inline)状态。这样,在挂载(mount)到客户端应用程序之前,可以直接从 store 获取到内联预置(inline)状态。

10.ssr的热加载

vue-server-renderer 提供一个名为 createBundleRenderer 的 API,用于处理此问题,通过使用 webpack 的自定义插件,server bundle 将生成为可传递到 bundle renderer 的特殊 JSON 文件。所创建的 bundle renderer,用法和普通 renderer 相同,但是 bundle renderer 提供以下优点:

内置的 source map 支持(在 webpack 配置中使用 devtool: 'source-map')

在开发环境甚至部署过程中热重载(通过读取更新后的 bundle,然后重新创建 renderer 实例)

关键 CSS(critical CSS) 注入(在使用 *.vue 文件时):自动内联在渲染过程中用到的组件所需的CSS。更多细节请查看 CSS 章节。

使用 clientManifest 进行资源注入:自动推断出最佳的预加载(preload)和预取(prefetch)指令,以及初始渲染所需的代码分割 chunk。

11.Webpack中打包的注意点:

有些属性需要指定: 如target为node,libraryTarget为commonjs2等

在源码中对应,(因为在源码中会检查这些项目)

405ad901e9b6?utm_campaign=maleskine...&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

image.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值