Obiwahn
Obiwahn

Reputation: 3087

How can I display the current app version from package.json to the user using Vite?

With create-react-app one could use process.env.REACT_APP_VERSION for this.

Is there an equivalent in Vite?

Upvotes: 68

Views: 53053

Answers (11)

Andrei Calinescu
Andrei Calinescu

Reputation: 311

A previous answer suggests to add VITE_VERSION=${npm_package_version} to your .env. If you work by yourself or in a small team and you have an established way to manage .env files I think this is the best option. This didn't work in my case because my team pulls .env files from Vercel and as far as I know, Vercel variables are all saved as strings, not shell commands with variables. My team wants to reduce human interaction required to set up the local environment, so this solution doesn't work for us.

Other answers either didn't work for me or had potential security issues by exposing package.json to the client. I'm posting my solution in case it helps others with a similar config. I'm not sure if it's the most elegant solution but it works well in all environments and seems to avoid the problem of exposing package.json to the client.

Here's my config, besides the obvious (using Vite):

  • using yarn
  • React app
  • deploying with Vercel

Here's what I added to package.json:

  1. In the scripts section add script named "version" with the value "echo $npm_package_version". This will output the package version. More info in NPM docs
  2. In the scripts section do this for every command that includes vite:
    • immediately before the vite command in the script, create a variable prefixed with VITE_ (Vite docs: only VITE_ prefixed variables are exposed to client source code) and assign it the value output by the version script you just created. For example:
      • "dev": "vite --port=4000", becomes:
      • "dev": "VITE_APP_VERSION=$(yarn run version) vite --port=4000"

Here's the result

{
  "name": "your-package-name",
  "version": "0.1.0",
  ....
  "scripts": {
    ...
    "version": "echo $npm_package_version",
    "dev": "VITE_APP_VERSION=$(yarn run version) vite --port=4000",
    "build": "tsc && VITE_APP_VERSION=$(yarn run version) vite build",
    "preview": "VITE_APP_VERSION=$(yarn run version) vite preview",
    ...
  }
}

Then, you can access the package version in your app using import.meta.env.VITE_APP_VERSION.

For example:

console.log(import.meta.env.VITE_APP_VERSION)   // 0.1.0

This worked for me in local and Vercel deployments using Yarn. Hope it helps!

Upvotes: 0

Waket Zheng
Waket Zheng

Reputation: 6351

This worked for me:

import { version } from '@/../package.json'

The @ was define in vite.config.ts

export default defineConfig({
  // ...
  resolve: {
    // ...
    alias: {
      '@': resolve(__dirname, 'src'),
    },
  },
}

Upvotes: 4

Christhofer Natalius
Christhofer Natalius

Reputation: 3398

You can use define in vite.config.js. Read about it here

vite.config.js

export default {
    plugins: [vue()],
    define: {
        '__APP_VERSION__': JSON.stringify(process.env.npm_package_version),
    }
}

MyComponent.vue

<script setup>
// can't be used directly on the template
const version = __APP_VERSION__
</script>
<template>
    <div>{{ version }}</div>
</template>

You should be able to change '__APP_VERSION__' as long as it doesn't conflict with javascript syntax or other variables.

Typescript

Taken directly from Vite Docs

For TypeScript users, make sure to add the type declarations in the env.d.ts or vite-env.d.ts file to get type checks and Intellisense.

vite-env.d.ts

declare const __APP_VERSION__: string

Upvotes: 78

Jeroen Wienk
Jeroen Wienk

Reputation: 2030

Specifying VITE_VERSION=${npm_package_version} in .env works for me. The version is available under import.meta.env.VITE_VERSION. Tested on vite version 4.4.5.

Upvotes: 2

a0m0rajab
a0m0rajab

Reputation: 455

React, Vite, Typescript

I have used this with React, typescript and vite.

Here is what worked for me and why:

first step: add version

Added the version to: vite.config.ts

export default defineConfig({
  define: {
    `config.version`: JSON.stringify('my-custom-name')
  }
})

declared the config file on .d.ts

This will prevent the typescript from creating an issue for not declaring global config.

On this file: src/vite-env.d.ts Added the next line

declare var config: any;

used the variable.

I used the variable inside the react function as any normal variable:

const { version } = config;

I used this on the open sauced project at this PR: https://github.com/open-sauced/ai/pull/141/files in case if you want to check the relevant code.

It would be helpful to reference the next questions as well:

Angular error TS2304: Cannot find name 'config'

Create a global variable in TypeScript

Upvotes: 1

Kolya_YA
Kolya_YA

Reputation: 431

Simplest solution

// .env
VITE_REACT_APP_VERSION=$npm_package_version
// App.jsx
...
console.log('ver. ', import.meta.env.VITE_REACT_APP_VERSION)
...

Upvotes: 25

Michael
Michael

Reputation: 291

Vite 4, React, Typescript setup

This worked for me.

I imported package.json in vite.config.ts and defined a PACKAGE_VERSION environment variable.

import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import packageJson from './package.json';

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [react()],
  define:  {
    'import.meta.env.PACKAGE_VERSION': JSON.stringify(packageJson.version)
  }
})

I added "resolveJsonModule": true to the compiler options of tsconfig.node.json.
I added "./package.json" to the include array of tsconfig.node.json

{
  "compilerOptions": {
    "composite": true,
    "module": "ESNext",
    "moduleResolution": "Node",
    "allowSyntheticDefaultImports": true,
    "resolveJsonModule": true
  },
  "include": ["vite.config.ts", "./package.json"]
}

In order to make intellisense work for PACKAGE_VERSION, I added it to vite-env.d.ts

interface ImportMetaEnv {
    readonly PACKAGE_VERSION: string;
    // more env variables...
}
  
interface ImportMeta {
    readonly env: ImportMetaEnv
}

I could use {import.meta.env.PACKAGE_VERSION} anywhere in my react app to show the package version.

Upvotes: 29

daniel p
daniel p

Reputation: 969

In case anyone is interested, this automatically increases the version in package.json and makes it available to the application.

import { defineConfig } from 'vite';
const increasePackageVersion = () => {
    try {
        const fs = require('fs');
        const path = require('path');
        const packageFilePath = path.join(__dirname, 'package.json');
        const packageJson = JSON.parse(fs.readFileSync(packageFilePath, 'utf8'));
        packageJson.version = packageJson.version.replace(/(\d+)$/, (match, p1) => {
            return parseInt(p1) + 1;
        }
        );
        fs.writeFileSync(packageFilePath, JSON.stringify(packageJson, null, 2));
        console.log('New version is', packageJson.version);
    } catch (error) {
        console.log('Error in increasePackageVersion', error);
    }

};

export default defineConfig({
    build: {
        lib: {
            entry: 'src/main.js',
            formats: ['es']
        }
    },
    plugins: [
    increasePackageVersion()],
    define: {
        '__APP_VERSION__': JSON.stringify(process.env.npm_package_version),
    }
});
console.log(__APP_VERSION__);

Upvotes: 4

Jamie
Jamie

Reputation: 4335

For React & TypeScript users:

Add a define to your vite.config.ts:

import react from '@vitejs/plugin-react';
import { defineConfig } from 'vite';

export default defineConfig({
  plugins: [react()],
  define: {
    APP_VERSION: JSON.stringify(process.env.npm_package_version),
  },
});

If you haven't got one already, define a vite-env.d.ts or env.d.ts and add a declare:

declare const APP_VERSION: string;

You'll now be able to use the variable APP_VERSION anywhere in your code & Vite will substitute it at compile time.

Note: You may need to restart your TS server for the declaration to be picked up by intellisense:

VSCode MacOS: + + P > Restart TS Server

VSCode Windows: ctrl + + P > Restart TS Server

Upvotes: 73

Pallav Chanana
Pallav Chanana

Reputation: 667

Below Answer includes

  1. Secure Way of Importing Vue version.

  2. Incrementing semantic versions using npm commands

Secure and Semantic Way of Versioning using npm and env

Upvotes: 0

Adarsh Madrecha
Adarsh Madrecha

Reputation: 7916

If you don't want to use define, there is a vite plugin for just this.

https://www.npmjs.com/package/vite-plugin-package-version

// vite.config.js
import loadVersion from 'vite-plugin-package-version';

export default {
  plugins: [loadVersion()],
};

Will inject import.meta.env.PACKAGE_VERSION with the version specified in your package.json.

Upvotes: 9

Related Questions