使用Vue SSR渲染页面时的动态publicPath

时间:2018-09-12 21:44:45

标签: vue.js webpack vue-ssr

我们很高兴Vue及其服务器端渲染模块Vue SSR的用户。我的项目的要求之一是我们能够在运行时动态调整Webpack的publicPath,以便我们可以从不同的CDN获取资产(我们有两个,一个用于测试,一个用于产品)。

我们可以使用__webpack_public_path__ free variable在客户端轻松完成此操作,对于注入<head>的资产URL,您还可以覆盖publicPath within the SSR client manifest

但是,我们仍然存在直接存在于模板中并由SSR呈现的资产URL的问题。例如,假设标签中是否包含以下图片:

<img src="~@/test.png" />

我们的目标是,在服务器和客户端上,我们都可以将该URL调整为可以通过publicPath进行前缀的方式。 vue-ssr-server-manifest.json生成后,似乎没有一种动态更新publicPath的方法,生成的URL最终会变成/static/test.png之类的相对名称,或者是我们最初在Webpack配置中引用的内容。 / p>

根据我们的项目约束,不可能重建我们的SSR包,因此我们需要在运行时执行此操作。我们尝试将占位符值添加为我们的publicPath,例如__CUSTOM_WEBPACK_PUBLIC_PATH__,并在运行时将其替换在服务器捆绑包中,但是由于publicPath也嵌入在其他Webpack生成的文件中,因此最终效果不佳。

想知道是否有更干净的方法可以直接通过Vue SSR实现我们所需的功能,或者这是我们在运行时无法配置的。感谢您的阅读!

4 个答案:

答案 0 :(得分:1)

我们在Web应用程序中也遇到了类似类型的问题。顺便说一句,我们为vue实现了CDN插件。

export const CDNPlugin = {
  install(Vue, { CDN, assetsManifest }) {
    Vue.prototype.$cdn = {
      ...CDN,
      asset(name) {
        return `${CDN.baseUrl}${assetsManifest[name]}`;
      },
      resource(filepath) {
        return `${CDN.baseUrl}/resources/${filepath}`;
      }
    };
  }
};

同时安装您的ssr和csr文件此插件。

Vue.use(CDNPlugin, {
  CDN: { baseUrl: 'https://my.static.cdn.com' },
  assetsManifest: yourAssetManifestObject,
});

vue模板中该CDN插件的用法如下

<img :src="$cdn.asset('relative/path/to/asset/style.css')">

如果您认为这有所帮助,那么我可以分享更多有关我们实施的信息。

答案 1 :(得分:0)

在这里进行了后续跟踪,但是我们最终解决了这个问题。

我们发现,在Node.js流程中全局设置__webpack_public_path__确实会导致将正确的公共路径应用于服务器捆绑中的资产。

一旦窗口(例如,客户端)和节点进程(例如,服务器端)都同时存在全局变量,一切就会按我们希望的那样开始工作。

答案 2 :(得分:0)

我花了一整天的时间试图弄清楚这一点。最后,我用了这个:

https://github.com/agoldis/webpack-require-from

像护身符,客户端和服务器一样工作。请注意,您需要在节点/服务器中的某个位置设置global.MY_BASE_URL,并且需要在HTML中的某个位置注入window.MY_BASE_URL。然后只需配置webpack。

plugins.push(new WebpackRequireFrom({{variableName:'MY_BASE_URL'}}));

答案 3 :(得分:0)

类似的问题发生在我的项目中,最后我解决了。

Ryan的回答确实有帮助,但是我想澄清一件事。 __webpack_public_path__是webpack捆绑代码中的LOCAL变量,这意味着__webpack_public_path__global.__webpack_public_path__是不同的。您需要做类似的事情

__webpack_public_path__ = process.env.ASSET_PATH;

指定公共路径(https://webpack.js.org/guides/public-path/#on-the-fly FYI)。

最后,请确保您的process.env.ASSET_PATH没有未定义,也许您必须在服务器代码中将其手动设置为global

global.process.env.ASSET_PATH = process.env.ASSET_PATH;