Summary - Incorporating a Vue app into a Phoenix app. Constructing the Vue app with vue cli and ensuring the files are placed correctly within the Phoenix project directories. After building, there is an issue where the asset file paths do not align with the publicPath setting.
I have developed my vue app to be located at
../../lib/exampleapp_web/templates/page
. To accommodate this design, I am using a custom html template to eliminate Vue's default <html>
,<head>
, and <body>
tags, as the Phoenix application already has a layout template that includes these.
The configuration in my vue.config.js file is as follows:
vue.config.js
module.exports = {
outputDir: '../../lib/exampleapp_web/templates/page',
assetsDir: '../../../../assets/static',
indexPath: 'index.html.eex',
publicPath: './', // adjusting the asset routes to be relative
chainWebpack: config => {
config.plugin('html').tap(args => {
return [{
template: "./public/index.html", // utilizing a custom Vue HTML template
minify: false, // for easy comprehension
inject: false // avoids injecting HTML elements like head, body, etc.
}]
})
}
}
However, upon building the app, the rendered asset paths appear incorrect due to mismatched URLs. For example:
<script src="../../../../assets/static/js/chunk-vendors.74d8847d.js"></script>
But what I actually need is:
<script src="./js/chunk-vendors.74d8847d.js"></script>
To address this issue, I am performing a string replacement within the Vue HTML template:
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>
<% } %>
This adjustment results in the correct rendering of asset paths:
<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>
Although this solution works, it feels cumbersome to manually edit the template each time to replace the paths. Is there a more efficient approach?
I initially thought the publicPath option would resolve this (https://cli.vuejs.org/config/#publicpath), but unfortunately, it does not seem to be effective in my case.
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/'