feat: expose env variables as root level in index.html template

This commit is contained in:
Evan You
2018-05-08 16:40:20 -04:00
parent 2dcdeddde4
commit 4c5784da73
4 changed files with 43 additions and 10 deletions
+14
View File
@@ -58,6 +58,20 @@ In addition to `VUE_APP_*` variables, there are also two special variables that
- `NODE_ENV` - this will be one of `"development"`, `"production"` or `"test"` depending on the [mode](#modes) the app is running in.
- `BASE_URL` - this corresponds to the `baseUrl` option in `vue.config.js` and is the base path your app is deployed at.
### Env Variables in Index HTML
All resolved env variables will be available inside `public/index.html` via [lodash template interpolation](https://lodash.com/docs/4.17.5#template):
- `<%= VAR %>` for unescaped interpolation;
- `<%- VAR %>` for HTML-escaped interpolationl;
- `<% expression %>` for JavaScript control flows.
For example, to reference static assets copied from the root of `public`, you will need to use the `BASE_URL` variable:
``` html
<link rel="shortcut icon" href="<%= BASE_URL %>favicon.ico">
```
### Local Only Variables
Sometimes you might have env variables that should not be committed into the codebase, especially if your project is hosted in a public repository. In that case you should use an `.env.local` file instead. Local env files are ignored in `.gitignore` by default.
@@ -30,6 +30,9 @@ test('build', async () => {
// should preload css
expect(index).toMatch(/<link [^>]+app[^>]+\.css rel=preload>/)
// should reference favicon with correct base URL
expect(index).toMatch(/<link rel=icon href=\/favicon.ico>/)
const port = await portfinder.getPortPromise()
server = createServer({ root: path.join(project.dir, 'dist') })
@@ -4,7 +4,7 @@
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="shortcut icon" href="<%%= webpackConfig.output.publicPath %%>favicon.ico">
<link rel="icon" href="<%%= BASE_URL %%>favicon.ico">
<title><%= rootOptions.projectName %></title>
</head>
<body>
+25 -9
View File
@@ -8,18 +8,34 @@ module.exports = (api, options) => {
}
// HTML plugin
const fs = require('fs')
const htmlPath = api.resolve('public/index.html')
const resolveClientEnv = require('../util/resolveClientEnv')
const htmlOptions = {
templateParameters: (compilation, assets, pluginOptions) => {
// enhance html-webpack-plugin's built in template params
let stats
return Object.assign({
// make stats lazy as it is expensive
get webpack () {
return stats || (stats = compilation.getStats().toJson())
},
compilation: compilation,
webpackConfig: compilation.options,
htmlWebpackPlugin: {
files: assets,
options: pluginOptions
}
}, resolveClientEnv(options.baseUrl, true /* raw */))
}
}
// only set template path if index.html exists
const htmlPath = api.resolve('public/index.html')
if (require('fs').existsSync(htmlPath)) {
htmlOptions.template = htmlPath
}
webpackConfig
.plugin('html')
.use(require('html-webpack-plugin'), [
Object.assign(
fs.existsSync(htmlPath) ? { template: htmlPath } : {},
// expose client env to html template
{ env: resolveClientEnv(options.baseUrl, true /* raw */) }
)
])
.use(require('html-webpack-plugin'), [htmlOptions])
// inject preload/prefetch to HTML
const PreloadPlugin = require('preload-webpack-plugin')