@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.
publicfolder. Anything in there is copied as-is to thedistfolder