Why is runtimeConfig doesn't see environment variables in Nuxt 3? - vue.js

I do yarn build without the .env file
Add the .env file to the project
I do yarn start.
Print the useRuntimeConfig().public.baseURL to the console and get undefined.
Why is runtime not tracking my environment variables?
.env
NUXT_PUBLIC_BASE_URL=https://example.com/api/v1
nuxt.config.js
export default defineNuxtConfig({
runtimeConfig: {
public: {
baseUrl: ''
}
},
plugins/app.js
export default defineNuxtPlugin(() => {
console.log('baseURL', useRuntimeConfig().public.baseURL
})

From the documentation page:
However, after your server is built, you are responsible for setting environment variables when you run the server. Your .env file will not be read at this point. How you do this is different for every environment. On a Linux server, you could pass the environment variables as arguments using the terminal DATABASE_HOST=mydatabaseconnectionstring node .output/server/index.mjs. Or you could source your env file using source .env && node .output/server/index.mjs.
Note that for a purely static site, it is not possible to set runtime configuration config after your project is prerendered.
So, source .env && yarn start should do it.

You might check the version of nuxt.
If it's the bridge version, runtimeConfig cannot work.
Cause I use #nuxt/bridge, not work.
and then it worked on the 3.0.0-rc.3 version. I've tried.

baseUrl: process.env.NUXT_PUBLIC_BASE_URL
try it that way. what you do is setting it explicitly to a empty string.

Related

Liberary dotenv-webpack doesn't work with vue 3 and webpack-cli

I'm using Vue 3 and Webpack 5 and wanted to install dotenv-webpack, but I can't get it to work.
Here's full code: https://github.com/golebiewska-n/webpack5-vue3
Setup:
package.json script I'm using to launch the app
webpack-cli serve
webpack.config.js
const Dotenv = require('dotenv-webpack')
...
module.exports = (env) => {
return {
...
plugins: [
...
new Dotenv()
]
}
}
.env (added in the root folder of my app)
VUE_APP_VAR=123
main.js
console.log(process.env)
and output in console is: "MISSING_ENV_VAR"
I tried removing new webpack.DefinePlugin({...}) from plugins in webpack config, but it didn't help.
In fact you successfully loaded the .env file with dotenv-webpack and the VUE_APP_VAR is accessible. It is just you cannot use the entire process.env object as dotenv-webpack does not allow it showing you MISSING_ENV_VAR instead.
If you chnange line 12 in your src\Layout.vue as follows:
- return process.env
+ return process.env.VUE_APP_VAR
you get your 123 value of the variable in your Vue app.
The reason is at the time of building your application with webpack dotenv-webpack replaces the explicit string process.env.SOME_EXPLICIT_VARIABLE_NAME_HERE existing in your code with the actual value of SOME_EXPLICIT_VARIABLE_NAME_HERE if that exist in the Webpack JS environment's actual process.env object.
This means you never get the entire process.env object accessible in your webpack bundle, and the bundle does not comprise the variable names like VUE_APP_VAR=123. This is the goal of dotenv-webpack.
You can get some more details in my answer here.
PS: DefinePlugin, being returned in the build config, could override process.env. It does so in Vue CLI (which is hardly justifiable). So its effect there sould be neutralized manually for dotenv-webpack to work within Vue CLI (v4 and v5) applications as expected.

vue as nx plugin and using environment variables (nx-plus/vue)

I've migrated vue app to nx, all is fine now except of one thing - previously, .env file was used in both dev and production environments, during development as well as build, vue-cli-service took care of that. Now I struggle with app build - it doesn't seem to read .env file, or I just do it wrong.
I've tried to add dotenv-webpack and add it in the configure-webpack.js but during build none of the variables was accessible. Here is the file example:
//.env
SOME_API_URL=$API_URL
// config.ts
export const CONFIG = {
api_url = process.env.SOME_API_URL
}
// during build process.env is undefined
build command looks like this:
export API_URL='http://vue-app.com'; nx build frontend --skip-nx-cache
You would need to switch to Vite but we’ve had good success using this plugin for our applications: https://github.com/chf007/vite-plugin-nx-dotenv

VueJS place multiple .env in folder

Hello I'm using VueJS 2 and I have multiple .env in my project.
My app have .env for each company to select the company configuration (skin color / files...)
Actually I have all my .env in the root folder:
.env.company1-dev
.env.company1-staging
.env.company1-prod
.env.company2-dev
.env.company2-staging
.env.company2-prod
.env.company3-dev
.env.company3-staging
.env.company3-prod
So when I'll get 20 companies it will be confused on my root folder so it is possible to create a folder where I can place all my .env ?
The idea :
/environments/company1/
.env.dev
.env.staging
.env.prod
/environments/company2/
.env.dev
.env.staging
.env.prod
/environments/company3/
.env.dev
.env.staging
.env.prod
On your vue.config.js file you can add:
const dotenv = require("dotenv");
const path = require("path");
let envfile = ".env";
if (process.env.NODE_ENV) {
envfile += "." + process.env.NODE_ENV;
}
const result = dotenv.config({
path: path.resolve(`environments/${process.env.VUE_APP_COMPANY}`, envfile)
});
// optional: check for errors
if (result.error) {
throw result.error;
}
the before run you can set VUE_APP_COMPANY to a company name and run your app,
Note: It's important to put this code on vue.config.js and not in main.js because dotenv will use fs to read files.
References
https://github.com/motdotla/dotenv#path
https://github.com/vuejs/vue-cli/issues/787
https://cli.vuejs.org/guide/mode-and-env.html#environment-variables
The accepted answer we have also used in the past. But I found a better solution to handle different environments. Using the npm package dotenv-flow allows not only the use of different environments but has some more benefits like:
local overwriting of variables by using .env.local or .env.staging.local and so on
definition of defaults using .env.defaults
In combination we have set up our projects with this configuration:
.env
.env.defaults
.env.development
.env.production
.env.staging
.env.test
And the only thing you have to do in your vue.config.js, nuxt.config.js or other entry points is
require('dotenv-flow').config()
Reference: https://www.npmjs.com/package/dotenv-flow
The powershell solution
I was handling exactly the same problem. Accepted solution is kind of ok, but it did not solve all differences between companies. Also, if you are using npm, your scripts can look nasty. So if you have powershell, here is what I suggest - get rid of the .env files :)
You can keep your structure like you want in the question. Just convert the env files to ps1.
/build/company1/
build-dev.ps1
build-stage.ps1
build-prod.ps1
/build/company2/
build-dev.ps1
build-stage.ps1
build-prod.ps1
Inside each of those, you can fully customize all env variables, run build process and apply some advanced post-build logic (like careful auto-deploy, publishing, merging with api project, ..).
So for example company1\build-stage.ps1 can look like this:
# You can pass some arguments to the script
param (
[string]$appName = "company1"
)
# Set environment variables for vue pipeline
$env:VUE_APP_ENVIRONMENT = "company1-stage";
$env:NODE_ENV="development";
$env:VUE_APP_NAME=$appName;
$env:VUE_APP_API_BASE_URL="https://company1.stage.mycompany.com"
# Run the vue pipeline build
vue-cli-service build;
# Any additional logic e.g.
# Copy-Item -Path "./dist" -Destination "my-server/my-app" -Recurse¨
Last part is easy - just call it (manualy or from integration service like TeamCity). Or, you can put it inside package.json.
...
"scripts": {
"build-company1-stage": "#powershell -Command ./build/company1/build-stage.ps1 -appName Company-One",
}
...
The you can call whole build process just by calling
npm run build-company1-stage
Similary, you can create localhost, dev, prod, test and any other environment. Let the javascript handle the part of building the app itself. For other advanced work, use poweshell. I think that this solution gives you much more flexibility for configuration and build process.
P.S.
I know that this way I'm merging configuration and build process, but you can always extract the configuration outside the file if it gets bigger.

How to auto save compiled vue files when running npm run serve

With vue.js when setting up a project using vue CLI i can run
$ npm run serve
to compile the files and start a port at localhost:8080
My question is what can i do so that the generated that got rendered in the page be also saved to a directory in my development machine.
Just like auto-saving and modifying so that i can be able to use the file on another project which depends on the generated files all during development
Are you sure it's not already creating a bundle somewhere? In some kind of build or dist folder?
Inside the webpack config you can check what value is used for output.
I don't know if an easier solution exists. But what i would suggest is :
Set writeToDisk option true. This will make sure your bundle written in to disk. Link
Then add an after-emit hook to the webpack pipeline:
const exec = require('child_process').exec; // use exec to run shell command
module.exports = {
...
plugins: [
...
{
apply: (compiler) => {
compiler.hooks.afterEmit.tap('CopyOutputPlugin', (compilation) => {
exec('command to copy output folder to desired folder');
});
}
}
]
};
child_process documentation.

Vue.js: Passing environment variables to a vue.js application

I'm running a vue.js application in a Docker container. I have some configuration set via environment variables (e.g. API base url). I want to be able to use these variables in my application in browser. How can I pass them?
I tried to add these variables to one of the config/*.env.js files like that (config/dev.env.js):
module.exports = merge(prodEnv, {
NODE_ENV: '"development"',
backendBase: process.env.BACKEND_BASE
})
Then I run application using npm run dev but process.env object is always empty (NODE_ENV is also not available)
I came across the exact same problem recently. If you are running the dev server using a watcher I think it doesn't pick the config change up correctly. I stopped my dev server, rebuilt production as well (no idea if that helps but just in case) and then started the dev server up again and all was ok.
To access the above settings you should be able to use process.env in your code
console.log(process.env.NODE_ENV)
I think only variables prefixed with VUE_APP get packaged up by Vue.
From: https://cli.vuejs.org/guide/mode-and-env.html#environment-variables
Note that only variables that start with VUE_APP_ will be statically
embedded into the client bundle with webpack.DefinePlugin.
I tested locally.
.env in root:
APP_TEST=foo
VUE_APP_TEST=bar
In main.js:
// imports and other stuff
new Vue({
render: h => h(App),
}).$mount('#app');
console.log(process.env.APP_TEST, 'APP_TEST');
console.log(process.env.VUE_APP_TEST, 'VUE_APP_TEST');
Output:
undefined APP_TEST
bar VUE_APP_TEST
You'll need to run another build if you make changes to your envvars.