Skip to content

Commit 1e7fa2c

Browse files
committed
fix: fix css output location for relative baseUrl + more details in docs
1 parent ca1630d commit 1e7fa2c

File tree

6 files changed

+37
-40
lines changed

6 files changed

+37
-40
lines changed

docs/config/README.md

+12-8
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,19 @@ module.exports = {
3434
- Type: `string`
3535
- Default: `'/'`
3636

37-
The base URL your application will be deployed at. 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 `baseUrl` to `'/my-app/'`.
37+
The base URL your application bundle will be deployed at. This is the equivalent of webpack's `output.publicPath`, but Vue CLI also needs this value for other purposes, so you should **always use `baseUrl` instead of modifying webpack `output.publicPath`**.
3838

39-
Setting this value correctly is necessary for your static assets to be loaded properly in production.
39+
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 `baseUrl` to `'/my-app/'`.
40+
41+
The value can also be set to an empty string (`''`) or a relative path (`./`) so that all assets are linked using relative paths. This allows the built bundle to be deployed under any public path, or used in a file system based environment like a Cordova hybrid app.
42+
43+
::: warning Limitations of relative baseUrl
44+
Relative `baseUrl` has some limitations and should be avoided when:
45+
46+
- You are using HTML5 `history.pushState` routing;
47+
48+
- You are using the `pages` option to build a multi-paged app.
49+
:::
4050

4151
This value is also respected during development. If you want your dev server to be served at root instead, you can use a conditional value:
4252

@@ -48,12 +58,6 @@ module.exports = {
4858
}
4959
```
5060

51-
The value can also be set to an empty string (`''`) so that all assets are linked using relative paths, so that the bundle can be used in a file system based environment like a Cordova hybrid app. **Note that this will force the generated CSS files to always be placed at the root of the output directory to ensure urls in your CSS work correctly.**
52-
53-
::: tip
54-
Always use `baseUrl` instead of modifying webpack `output.publicPath`.
55-
:::
56-
5761
### outputDir
5862

5963
- Type: `string`

docs/guide/deployment.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ If you are developing your frontend app separately from your backend - i.e. your
88

99
### Previewing Locally
1010

11-
The `dist` directory is meant to be served by an HTTP server, so it will not work if you open `dist/index.html` directly over `file://` protocol. The easiest way to preview your production build locally is using a Node.js static file server, for example [serve](https://github.com/zeit/serve):
11+
The `dist` directory is meant to be served by an HTTP server (unless you've configured `baseUrl` to be a relative value), so it will not work if you open `dist/index.html` directly over `file://` protocol. The easiest way to preview your production build locally is using a Node.js static file server, for example [serve](https://github.com/zeit/serve):
1212

1313
``` bash
1414
npm install -g serve

docs/zh/config/README.md

+12-8
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,19 @@ module.exports = {
3232
- Type: `string`
3333
- Default: `'/'`
3434

35-
部署应用时的基本 URL。默认情况下,Vue CLI 会假设你的应用是被部署在一个域名的根路径上,例如 `https://www.my-app.com/`。如果应用被部署在一个子路径上,你就需要用这个选项指定这个子路径。例如,如果你的应用被部署在 `https://www.my-app.com/my-app/`,则设置 `baseUrl` `/my-app/`
35+
部署应用时的基本 URL。用法和 webpack 本身的 `output.publicPath` 一致,但是 Vue CLI 在一些其他地方也需要用到这个值,所以**请始终使用 `baseUrl` 而不要直接修改 webpack 的 `output.publicPath`**
3636

37-
你必须正确地设置这个值以使生产环境中静态资源加载正确。
37+
默认情况下,Vue CLI 会假设你的应用是被部署在一个域名的根路径上,例如 `https://www.my-app.com/`。如果应用被部署在一个子路径上,你就需要用这个选项指定这个子路径。例如,如果你的应用被部署在 `https://www.my-app.com/my-app/`,则设置 `baseUrl``/my-app/`
38+
39+
这个值也可以被设置为空字符串 (`''`) 或是相对路径 (`'./'`),这样所有的资源都会被链接为相对路径,这样打出来的包可以被部署在任意路径,也可以用在类似 Cordova hybrid 应用的文件系统中。
40+
41+
::: warning 相对 baseUrl 的限制
42+
相对路径的 `baseUrl` 有一些使用上的限制。在以下情况下,应当避免使用相对 `baseUrl`:
43+
44+
- 当使用基于 HTML5 `history.pushState` 的路由时;
45+
46+
- 当使用 `pages` 选项构建多页面应用时。
47+
:::
3848

3949
这个值在开发环境下同样生效。如果你想把开发服务器架设在根路径,你可以使用一个条件式的值:
4050

@@ -46,12 +56,6 @@ module.exports = {
4656
}
4757
```
4858

49-
这个值也可以被设置为空字符串 (`''`) 这样所有的资源都会被链接为相对路径,这样打出来的包可以用在类似 Cordova hybrid 应用的文件系统中。**注意:生成的 CSS 文件要始终放在输出路径的根部,以确保 CSS 中的 URL 正常工作。**
50-
51-
::: tip 提示
52-
请始终使用 `baseUrl` 而不要修改 webpack 的 `output.publicPath`
53-
:::
54-
5559
### outputDir
5660

5761
- Type: `string`

packages/@vue/cli-service/lib/commands/build/index.js

-12
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,6 @@ async function build (args, api, options) {
175175
}
176176

177177
return new Promise((resolve, reject) => {
178-
const isFreshBuild = !fs.existsSync(api.resolve('node_modules/.cache'))
179178
webpack(webpackConfig, (err, stats) => {
180179
stopSpinner(false)
181180
if (err) {
@@ -199,17 +198,6 @@ async function build (args, api, options) {
199198
} else {
200199
done(`Build complete. Watching for changes...`)
201200
}
202-
if (
203-
options.baseUrl === '/' &&
204-
// only log the tips if this is the first build
205-
isFreshBuild
206-
) {
207-
console.log(
208-
chalk.gray(`Tip: the directory is meant to be served by an HTTP server, and will not work if\n` +
209-
`you open it directly over file:// protocol. To preview it locally, use an HTTP\n` +
210-
`server like the ${chalk.yellow(`serve`)} package on npm.\n`)
211-
)
212-
}
213201
}
214202
}
215203

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

+12-2
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,21 @@ module.exports = (api, options) => {
2525
const shouldExtract = extract !== false && !shadowMode
2626
const filename = getAssetPath(
2727
options,
28-
`css/[name]${options.filenameHashing ? '.[contenthash:8]' : ''}.css`,
29-
true /* placeAtRootIfRelative */
28+
`css/[name]${options.filenameHashing ? '.[contenthash:8]' : ''}.css`
3029
)
3130
const extractOptions = Object.assign({
3231
filename,
3332
chunkFilename: filename
3433
}, extract && typeof extract === 'object' ? extract : {})
3534

35+
// use relative publicPath in extracted CSS based on extract location
36+
const cssPublicPath = '../'.repeat(
37+
extractOptions.filename
38+
.replace(/^\.[\/\\]/, '')
39+
.split(/[\/\\]/g)
40+
.length - 1
41+
)
42+
3643
// check if the project has a valid postcss config
3744
// if it doesn't, don't use postcss-loader for direct style imports
3845
// because otherwise it would throw error when attempting to load postcss config
@@ -68,6 +75,9 @@ module.exports = (api, options) => {
6875
rule
6976
.use('extract-css-loader')
7077
.loader(require('mini-css-extract-plugin').loader)
78+
.options({
79+
publicPath: cssPublicPath
80+
})
7181
} else {
7282
rule
7383
.use('vue-style-loader')

packages/@vue/cli-service/lib/util/getAssetPath.js

-9
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,6 @@
11
const path = require('path')
22

33
module.exports = function getAssetPath (options, filePath, placeAtRootIfRelative) {
4-
// if the user is using a relative URL, place js & css at dist root to ensure
5-
// relative paths work properly
6-
if (
7-
placeAtRootIfRelative &&
8-
!(/^https?:/.test(options.baseUrl)) &&
9-
options.baseUrl.charAt(0) !== '/'
10-
) {
11-
return filePath.replace(/^\w+\//, '')
12-
}
134
return options.assetsDir
145
? path.posix.join(options.assetsDir, filePath)
156
: filePath

0 commit comments

Comments
 (0)