🙋 feature request!
First thing first: Thanks for the nice work ! :+1:
I have a use case where an anchor tag redirects to an external URL based on the environment (localhost:3333
if in DEV for instance and https://whatever.com
in PROD).
Therefore, it would be really convenient to be able to use the environment variables directly inside the index.html
without going through any javascript code.
Just like this : <a href=%MY_ENV_VARIABLE%>Ok</a>
The %
are used randomly just to show some kind of formatting to handle ENV variables at build time.
Maybe I have missed something but I was not able to find any kind of documentation or issues (open or close) dealing with this kind of things. Maybe I'm totally missing something but with this type of use cases, this feature would be very convenient.
+1
We would like to use different favicons to signify our dev environment versus our production environment so that when we have many tabs open, it's easy to pick out where you're looking. Having access to an env variable in the HTML would allow us to do this easily.
Would also be useful for additional script tags (service worker, Google analytics, etc) that you don't need when developing/designing your app; but obviously need when deployed.
I _think_ this could be resolved by allowing the entry point to be a template file like Handlebars, EJS, or Pug. Parcel automatically sets the NODE_ENV
to production
which could be passed to the template at build time.
Those of us coming from Webpack got used to html-webpack-plugin
, so it would be great to see Parcel incorporate similar functionality, while still maintaining the exceptional developer experience it offers over Webpack.
UPDATE:
This is actually already supported. I created a simple example using Pug. You do have to npm add -D pug
.
index.pug
doctype html
html(lang='en')
head
meta(charset='utf-8')
meta(name='viewport', content='width=device-width, initial-scale=1, shrink-to-fit=no')
title Parcel
body
if process.env.NODE_ENV === 'production'
h1 PRODUCTION
else
h1 DEVELOPMENT
Running parcel build index.pug
will generate the following index.html
:
dist/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Parcel</title>
</head>
<body>
<h1>PRODUCTION</h1>
</body>
</html>
Therefor, to resolve @GaelS 's issue, you could do something like this:
body
a(href=process.env.LINK_HREF) Ok
LINK_HREF='http://example.com' parcel build index.pug
<body>
<a href="http://example.com">Ok</a>
<body>
Pretty cool and still zero config :+1:
You can use <%= MY_ENV_VAR %>
syntax.
The example bellow uses VUE_APP_TITLE
variable that I set in my .env
files and BASE_URL
that's a system environment variable.
<head>
<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="icon" href="<%= BASE_URL %>favicon.ico">
<title><%= VUE_APP_TITLE %></title>
</head>
If you’re using something that runs JS (like react) as mentioned you can just reference process.env
in your code. However, I was able to get environment variables within my regular HTML files using PostHTML with the following steps:
Set some environment variables, e.g., I created .env.development
in the root of my project as such:
HOME_URL=/index.html
Add the posthtml-expressions library:
yarn add -D posthtml-expressions
Add a posthtml config file—important that it’s a JS file and not just JSON—posthtml.config.js
(the reason for using these as JS files is not really documented currently, but the ability to access process.env here is why I’m using it):
module.exports = {
plugins: {
"posthtml-expressions": {
locals: {
HOME_URL: process.env.HOME_URL
}
}
}
};
Update my HTML to use the posthtml-expressions syntax:
<a href="{{ HOME_URL || '/' }}">home</a>
In order to try it out in dev yarn start
and to build it for production yarn build
taking into account different environments, I have the following in my package.json
:
{
"scripts": {
"start": "yarn parcel src/*.html",
"build": "NODE_ENV=prod parcel build --public-url ./ src/index.html",
}
}
And voila, you have environment variables reflected in your HTML.
Also, one gotcha: I’m not seeing changes to .env triggering a re-build. You’ll have to edit something to trigger a re-build or stop parcel, rm -r .cache
, and then start parcel.
@breier in your example, are you using some extra asset-type handler to handle that ruby syntax <%= … %>
?
@mrcoles I've used vue-cli
to start a project using webpack
template. No additions.
This isn't something we'll support out of the box since it isn't standard HTML syntax. But you could easily use a PostHTML plugin for this, or another template language like Pug.
@mrcoles I've used
vue-cli
to start a project usingwebpack
template. No additions.
@breier Are you using the vue cli to have process.env available? If so, how? Thanks
is it HOME_URL or HOME_PATH?
@dandv, sorry that was a typo, I updated my comment so all HOME_PATH
references are HOME_URL
. Of course, feel free to use any variable names you want in your code :shipit:
@mrcoles I've used
vue-cli
to start a project usingwebpack
template. No additions.@breier Are you using the vue cli to have process.env available? If so, how? Thanks
Sorry for the really late reply, but for the record, here it is...
https://cli.vuejs.org/guide/mode-and-env.html#environment-variables
Note that only NODE_ENV, BASE_URL, and variables that start with VUE_APP_ will be statically embedded into the client bundle with webpack.DefinePlugin. It is to avoid accidentally exposing a private key on the machine that could have the same name.
Basically, any custom env var just have to start with VUE_APP_ in order to be auto loaded and assimilated.
I hope it helps someone ;)
@mrcoles, were you able to use NODE_ENV
though?
It seems to be set to production
regardless of what's used.
console.log(process.env.NODE_ENV)
module.expors = {};
$ npx parcel --version
2.0.0-nightly.462
$ NODE_ENV=test npx parcel build --no-cache index.html
console: production
â ¸ Building index.html...
If you’re using something that runs JS (like react) as mentioned you can just reference
process.env
in your code. However, I was able to get environment variables within my regular HTML files using PostHTML with the following steps:
3. Add a posthtml config file—important that it’s a JS file and not just JSON—posthtml.config.js
(the reason for using these as JS files is not really documented currently, but the ability to access process.env here is why I’m using it):
js module.exports = { plugins: { "posthtml-expressions": { locals: { HOME_URL: process.env.HOME_URL } } } };
Most helpful comment
If you’re using something that runs JS (like react) as mentioned you can just reference
process.env
in your code. However, I was able to get environment variables within my regular HTML files using PostHTML with the following steps:Set some environment variables, e.g., I created
.env.development
in the root of my project as such:Add the posthtml-expressions library:
Add a posthtml config file—important that it’s a JS file and not just JSON—
posthtml.config.js
(the reason for using these as JS files is not really documented currently, but the ability to access process.env here is why I’m using it):Update my HTML to use the posthtml-expressions syntax:
In order to try it out in dev
yarn start
and to build it for productionyarn build
taking into account different environments, I have the following in mypackage.json
:And voila, you have environment variables reflected in your HTML.
Also, one gotcha: I’m not seeing changes to .env triggering a re-build. You’ll have to edit something to trigger a re-build or stop parcel,
rm -r .cache
, and then start parcel.@breier in your example, are you using some extra asset-type handler to handle that ruby syntax
<%= … %>
?