Skip to content

Commit b9ecb90

Browse files
committed
feat: support specifying index output path via indexPath option
1 parent e7602ab commit b9ecb90

File tree

3 files changed

+36
-8
lines changed

3 files changed

+36
-8
lines changed

docs/config/README.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,12 +70,19 @@ module.exports = {
7070
- Type: `string`
7171
- Default: `''`
7272

73-
A directory to nest generated static assets (js, css, img, fonts) under.
73+
A directory (relative to `outputDir`) to nest generated static assets (js, css, img, fonts) under.
7474

7575
::: tip
7676
`assetsDir` is ignored when overwriting the filename or chunkFilename from the generated assets.
7777
:::
7878

79+
### indexPath
80+
81+
- Type: `string`
82+
- Default: `'index.html'`
83+
84+
Specify the output path for the generated `index.html` (relative to `outputDir`). Can also be an absolute path.
85+
7986
### pages
8087

8188
- Type: `Object`

packages/@vue/cli-service/lib/config/app.js

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,16 @@
22
const fs = require('fs')
33
const path = require('path')
44

5+
// ensure the filename passed to html-webpack-plugin is a relative path
6+
// because it cannot correctly handle absolute paths
7+
function ensureRelative (outputDir, _path) {
8+
if (path.isAbsolute(_path)) {
9+
return path.relative(outputDir, _path)
10+
} else {
11+
return _path
12+
}
13+
}
14+
515
module.exports = (api, options) => {
616
api.chainWebpack(webpackConfig => {
717
// only apply when there's no alternative target
@@ -11,6 +21,7 @@ module.exports = (api, options) => {
1121

1222
const isProd = process.env.NODE_ENV === 'production'
1323
const isLegacyBundle = process.env.VUE_CLI_MODERN_MODE && !process.env.VUE_CLI_MODERN_BUILD
24+
const outputDir = api.resolve(options.outputDir)
1425

1526
// code splitting
1627
if (isProd) {
@@ -56,6 +67,10 @@ module.exports = (api, options) => {
5667
}
5768
}
5869

70+
if (options.indexPath) {
71+
htmlOptions.filename = ensureRelative(outputDir, options.indexPath)
72+
}
73+
5974
if (isProd) {
6075
Object.assign(htmlOptions, {
6176
minify: {
@@ -151,7 +166,7 @@ module.exports = (api, options) => {
151166
const pageHtmlOptions = Object.assign({}, htmlOptions, {
152167
chunks: chunks || ['chunk-vendors', 'chunk-common', name],
153168
template: fs.existsSync(template) ? template : (fs.existsSync(htmlPath) ? htmlPath : defaultHtmlPath),
154-
filename,
169+
filename: ensureRelative(outputDir, filename),
155170
title
156171
})
157172

@@ -162,9 +177,10 @@ module.exports = (api, options) => {
162177

163178
if (!isLegacyBundle) {
164179
pages.forEach(name => {
165-
const {
166-
filename = `${name}.html`
167-
} = normalizePageConfig(multiPageConfig[name])
180+
const filename = ensureRelative(
181+
outputDir,
182+
normalizePageConfig(multiPageConfig[name]).filename || `${name}.html`
183+
)
168184
webpackConfig
169185
.plugin(`preload-${name}`)
170186
.use(PreloadPlugin, [{
@@ -192,12 +208,13 @@ module.exports = (api, options) => {
192208
}
193209

194210
// copy static assets in public/
195-
if (!isLegacyBundle && fs.existsSync(api.resolve('public'))) {
211+
const publicDir = api.resolve('public')
212+
if (!isLegacyBundle && fs.existsSync(publicDir)) {
196213
webpackConfig
197214
.plugin('copy')
198215
.use(require('copy-webpack-plugin'), [[{
199-
from: api.resolve('public'),
200-
to: api.resolve(options.outputDir),
216+
from: publicDir,
217+
to: outputDir,
201218
ignore: ['index.html', '.DS_Store']
202219
}]])
203220
}

packages/@vue/cli-service/lib/options.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ const schema = createSchema(joi => joi.object({
44
baseUrl: joi.string().allow(''),
55
outputDir: joi.string(),
66
assetsDir: joi.string(),
7+
indexPath: joi.string(),
78
runtimeCompiler: joi.boolean(),
89
transpileDependencies: joi.array(),
910
productionSourceMap: joi.boolean(),
@@ -55,6 +56,9 @@ exports.defaults = () => ({
5556
// where to put static assets (js/css/img/font/...)
5657
assetsDir: '',
5758

59+
// filename for index.html (relative to outputDir)
60+
indexPath: 'index.html',
61+
5862
// boolean, use full build?
5963
runtimeCompiler: false,
6064

0 commit comments

Comments
 (0)