在服务器端框架应用程序中嵌入 vue 应用程序,Vue 公共路径失败



TLDR - 在 Phoenix 应用程序中嵌入 vue 应用程序。 使用 vue cli 构建 vue 应用程序,并确保文件进入它们应该在 Pheonix 项目中的目录中。构建后,应用程序不起作用,因为资产文件路径与publicPath不匹配。

我构建我的 vue 应用程序来../../lib/exampleapp_web/templates/page.我需要使用自定义 html 模板来删除 vues<html><head><body>标签,因为 Pheonix 在现有布局模板中呈现此页面模板。

我的 vue.config.js 看起来像这样

vue.config.js

module.exports = {
outputDir: '../../lib/exampleapp_web/templates/page',
assetsDir: '../../../../assets/static',
indexPath: 'index.html.eex',
publicPath: './', // should make asset routes relative to route
chainWebpack: config => {
config.plugin('html').tap(args => {
return [{
template: "./public/index.html", // custom vue html template
minify: false, // so I can read it
inject: false // so html, head, body etc isn't injected
}]
})
}
}

构建时,渲染的资产路径是错误的(渲染的是 assetDir,而不是 publicPath 中指定的路径(:

<script src="../../../../assets/static/js/chunk-vendors.74d8847d.js"></script>

当我需要时:<script src="./js/chunk-vendors.74d8847d.js"></script>

所以为了纠正这个问题,我在我的 vue html 模板中做了一个字符串替换:

public/index.html

<!-- https://github.com/jaketrent/html-webpack-template/blob/86f285d5c790a6c15263f5cc50fd666d51f974fd/index.html -->
<% for (var css in htmlWebpackPlugin.files.css) { %>
<link href="<%= htmlWebpackPlugin.files.css[css].replace('./../../../assets/static/','/') %>" rel="stylesheet">
<% } %>
<div id="app"></div>
<% for (var chunk in htmlWebpackPlugin.files.chunks) { %>
<script src="<%= htmlWebpackPlugin.files.chunks[chunk].entry.replace('./../../../assets/static/','/') %>"></script>
<% } %>

这将呈现:

<link href="./css/chunk-vendors.257c6d34.css" rel="stylesheet">
<link href="./css/app.d5864d1f.css" rel="stylesheet">
<div id="app"></div>
<script src="./js/chunk-vendors.74d8847d.js"></script>
<script src="./js/app.b25a73d8.js"></script>

这行得通....只是感觉笨拙。每次都必须编辑模板以替换路径并不可行。有没有更好的方法?

我以为 publicPath 选项可以 https://cli.vuejs.org/config/#publicpath 做到这一点 - 它只是对我不起作用。

By default, Vue CLI assumes your app will be deployed at the root of a domain, e.g. https://www.my-app.com/. If your app is deployed at a sub-path, you will need to specify that sub-path using this option. For example, if your app is deployed at https://www.foobar.com/my-app/, set publicPath to '/my-app/'

找到了一个更好的解决方案 - 禁用 HTML 生成...它是一个静态文件,因此请将其设置为后端应用中的模板文件。构建 JS 和 CSS - 指定资产文件名,并将它们输出到您选择的文件夹。这个配置的大部分都是在一篇博客文章中找到的 - 但是,我不记得是哪一个......

vue.config.js

const assetsDir = './../../../assets/static'
// This config disables HTML, and builds static assets
// static assets are stuck in assetsDir.
// assetsDir does NOT filter down - hence we have to add it to each filename
// We give each file a name - this breaks cachebusting (if you use it)
// We create a static html file - which loads our paths
module.exports = {
assetsDir,
configureWebpack: {
output: {
filename: assetsDir + "/js/my-file.js",
chunkFilename: assetsDir + "/js/my-file-chunk.js"
}
},
chainWebpack: config => {
if (config.plugins.has("extract-css")) {
const extractCSSPlugin = config.plugin("extract-css");
extractCSSPlugin &&
extractCSSPlugin.tap(() => [
{
filename: assetsDir + "/css/my-file.css",
chunkFilename: assetsDir + "/css/my-file-chunk.css"
}
]);
}
config.plugins
.delete("html")
.delete("prefetch")
.delete("preload");
}
}

这样做的好处是 - 在构建时,您的文件会被转储到正确的目录中。您不必费力地构建 html 模板,因为您只需像往常一样构建服务器端模板即可。这适用于任何集成 - 不仅仅是凤凰城。

最新更新