@Phil's answer is simple and perfect if you have an invariant web.config
file that does not need any variable expansion. However, if you'd like to generate a web.config
file that includes, for example, an Rewrite rule with the BASE_URL
, the following will work:
In vue.config.js
:
"use strict";
// Do NOT use the HtmlWebpackPlugin name to avoid a collision with standard Vue usage of the html-webpack-plugin
// NOTE also this uses the vue-cli-service dependency path for html-webpack-plugin
// Beware if the require() path is incorrect, it may fail silently, thus ignoring vue.config.js (per (per https://github.com/vuejs/vue-cli/issues/5442)
const HtmlWebpackPlugin2 = require('@vue/cli-service/node_modules/html-webpack-plugin');
module.exports = {
devServer: {
disableHostCheck: true,
},
transpileDependencies: ['vuetify'],
publicPath: process.env.NODE_ENV === 'production' ? process.env.BASE_URL : '/',
configureWebpack: {
plugins: [
new HtmlWebpackPlugin2({ // generate web.config
title: 'web_config',
template: 'src/web.config',
filename: 'web.config',
inject: false
})
]
}
}
A key element is to declare const HtmlWebpackPlugin2 = require('@vue/cli-service/node_modules/html-webpack-plugin');
using a name other than HtmlWebpackPlugin
to avoid clashing with the vue-cli-service
's use of HtmlWebpackPlugin
. Then, in the configureWebpack:
element, add the "new" HtmlWebpackPlugin2
plugin with the template
path to your web.config
template. The inject: false
option is also important to avoid injecting <head>
and <script>
tags into your web.config
XML.
As noted in the OP's question, to run under IIS, the web.config
file should include a rewrite rule that rewrites client-side routing paths to your virtual root (also described here). This can be accomplished with html-webpack-plugin
's variable expansion syntax <%= process.env.MY_VARIABLE_NAME %>
:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="SPA Routes" stopProcessing="true">
<!-- match everything by default -->
<match url=".*" />
<conditions logicalGrouping="MatchAll">
<!-- unless its a file -->
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<!-- or a directory -->
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
<!-- or is under the /api directory -->
<add input="{REQUEST_URI}" pattern="^/(api)" negate="true" />
<!-- list other routes or route prefixes here if you need to handle them server side -->
</conditions>
<!-- rewrite to application root -->
<action type="Rewrite" url="<%= process.env.BASE_URL %>" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
The BASE_URL
variable itself is defined in a .env.production
file in same folder as vue.config.js
as described here or here. It is a plain text file that contains simply:
BASE_URL="/my-vroot-name/"
With the above, your standard yarn build
command will perform variable substitution in your src\web.config
template and write the output to dist\web.config
.
When setting up your IIS virtual application, make sure your physical path points to the dist
folder, or adjust the BASE_URL
and HtmlWebpackPlugin2
output filename
paths as needed for your server environment.