fix: fix css output location for relative baseUrl + more details in docs

This commit is contained in:
Evan You
2018-08-15 15:42:27 -04:00
parent ca1630d396
commit 1e7fa2cf46
6 changed files with 37 additions and 40 deletions

View File

@@ -34,9 +34,19 @@ module.exports = {
- Type: `string`
- Default: `'/'`
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/'`.
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`**.
Setting this value correctly is necessary for your static assets to be loaded properly in production.
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/'`.
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.
::: warning Limitations of relative baseUrl
Relative `baseUrl` has some limitations and should be avoided when:
- You are using HTML5 `history.pushState` routing;
- You are using the `pages` option to build a multi-paged app.
:::
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:
@@ -48,12 +58,6 @@ module.exports = {
}
```
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.**
::: tip
Always use `baseUrl` instead of modifying webpack `output.publicPath`.
:::
### outputDir
- Type: `string`

View File

@@ -8,7 +8,7 @@ If you are developing your frontend app separately from your backend - i.e. your
### Previewing Locally
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):
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):
``` bash
npm install -g serve

View File

@@ -32,9 +32,19 @@ module.exports = {
- Type: `string`
- Default: `'/'`
部署应用时的基本 URL。默认情况下Vue CLI 会假设你的应用是被部署在一个域名的根路径上,例如 `https://www.my-app.com/`。如果应用被部署在一个子路径上,你就需要用这个选项指定这个子路径。例如,如果你的应用被部署在 `https://www.my-app.com/my-app/`,则设置 `baseUrl` 为 `/my-app/`
部署应用时的基本 URL。用法和 webpack 本身的 `output.publicPath` 一致,但是 Vue CLI 在一些其他地方也需要用到这个值,所以**请始终使用 `baseUrl` 而不要直接修改 webpack 的 `output.publicPath`**
你必须正确地设置这个值以使生产环境中静态资源加载正确
默认情况下Vue CLI 会假设你的应用是被部署在一个域名的根路径上,例如 `https://www.my-app.com/`。如果应用被部署在一个子路径上,你就需要用这个选项指定这个子路径。例如,如果你的应用被部署在 `https://www.my-app.com/my-app/`,则设置 `baseUrl` 为 `/my-app/`
这个值也可以被设置为空字符串 (`''`) 或是相对路径 (`'./'`),这样所有的资源都会被链接为相对路径,这样打出来的包可以被部署在任意路径,也可以用在类似 Cordova hybrid 应用的文件系统中。
::: warning 相对 baseUrl 的限制
相对路径的 `baseUrl` 有一些使用上的限制。在以下情况下,应当避免使用相对 `baseUrl`:
- 当使用基于 HTML5 `history.pushState` 的路由时;
- 当使用 `pages` 选项构建多页面应用时。
:::
这个值在开发环境下同样生效。如果你想把开发服务器架设在根路径,你可以使用一个条件式的值:
@@ -46,12 +56,6 @@ module.exports = {
}
```
这个值也可以被设置为空字符串 (`''`) 这样所有的资源都会被链接为相对路径,这样打出来的包可以用在类似 Cordova hybrid 应用的文件系统中。**注意:生成的 CSS 文件要始终放在输出路径的根部,以确保 CSS 中的 URL 正常工作。**
::: tip 提示
请始终使用 `baseUrl` 而不要修改 webpack 的 `output.publicPath`。
:::
### outputDir
- Type: `string`

View File

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

View File

@@ -25,14 +25,21 @@ module.exports = (api, options) => {
const shouldExtract = extract !== false && !shadowMode
const filename = getAssetPath(
options,
`css/[name]${options.filenameHashing ? '.[contenthash:8]' : ''}.css`,
true /* placeAtRootIfRelative */
`css/[name]${options.filenameHashing ? '.[contenthash:8]' : ''}.css`
)
const extractOptions = Object.assign({
filename,
chunkFilename: filename
}, extract && typeof extract === 'object' ? extract : {})
// use relative publicPath in extracted CSS based on extract location
const cssPublicPath = '../'.repeat(
extractOptions.filename
.replace(/^\.[\/\\]/, '')
.split(/[\/\\]/g)
.length - 1
)
// check if the project has a valid postcss config
// if it doesn't, don't use postcss-loader for direct style imports
// because otherwise it would throw error when attempting to load postcss config
@@ -68,6 +75,9 @@ module.exports = (api, options) => {
rule
.use('extract-css-loader')
.loader(require('mini-css-extract-plugin').loader)
.options({
publicPath: cssPublicPath
})
} else {
rule
.use('vue-style-loader')

View File

@@ -1,15 +1,6 @@
const path = require('path')
module.exports = function getAssetPath (options, filePath, placeAtRootIfRelative) {
// if the user is using a relative URL, place js & css at dist root to ensure
// relative paths work properly
if (
placeAtRootIfRelative &&
!(/^https?:/.test(options.baseUrl)) &&
options.baseUrl.charAt(0) !== '/'
) {
return filePath.replace(/^\w+\//, '')
}
return options.assetsDir
? path.posix.join(options.assetsDir, filePath)
: filePath