I implemented a hook useEnv
that manages environment variables in client components and I’m trying to add unit test with Jest, but I’m facing this issue :
> [email protected] test
> jest src/hooks/__tests__/use-env.spec.ts
FAIL src/hooks/__tests__/use-env.spec.ts
● Test suite failed to run
src/hooks/use-env.ts:10:51 - error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'es2020', 'es2022', 'esnext', 'system', 'node16', or 'nodenext'.
10 const envVars = Object.keys(isFrameworkVite ? import.meta.env : process.env)
~~~~~~~~~~~
Test Suites: 1 failed, 1 total
Tests: 0 total
Snapshots: 0 total
Time: 1.193 s
Ran all test suites matching /src/hooks/__tests__/use-env.spec.ts/i.
(node:81266) [DEP0040] DeprecationWarning: The `punycode` module is deprecated. Please use a userland alternative instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
useEnv
:
import { NEXT_DEFAULT_ENV_VARS, VITE_DEFAULT_ENV_VARS } from '../constants/env'
import { rehookConfig } from '../rehook.config'
import { useEffect, useState } from 'react'
const { ignoreDefaultEnv, framework } = rehookConfig
const isFrameworkVite = framework === 'VITE' // Otherwise it is NEXTJS
export const useEnv = () => {
const envVars = Object.keys(isFrameworkVite ? import.meta.env : process.env)
const [variables, setVariables] = useState<string[]>(envVars)
const ignoreDefaultVariables = () => {
let ignoredVariables
if (ignoreDefaultEnv) {
ignoredVariables = variables.filter(variable =>
isFrameworkVite ? !VITE_DEFAULT_ENV_VARS.includes(variable) : !NEXT_DEFAULT_ENV_VARS.includes(variable),
)
setVariables(ignoredVariables)
}
}
const renameVariable = (oldVar: string, newVar: string) => {
const index = variables.indexOf(oldVar)
if (index !== -1) {
const updatedEnv = [...variables]
updatedEnv[index] = newVar
setVariables(updatedEnv)
}
}
const updateVariable = (currentVarVar: string, newValue: string) => {
if (variables.includes(currentVarVar)) {
setVariables(prevEnv => ({
...prevEnv,
[currentVarVar]: newValue,
}))
}
}
const removeVariable = (currentVar: string) => {
if (variables.includes(currentVar)) {
const filteredVars = variables.filter(value => value !== currentVar)
setVariables(filteredVars)
}
}
const saveVariable = (variable: string, value: string) => {
localStorage.setItem(variable, value)
}
const deleteVariable = (variable: string) => {
if (localStorage.getItem(variable)) {
localStorage.removeItem(variable)
}
}
useEffect(() => {
ignoreDefaultVariables()
}, [])
return { variables, renameVariable, updateVariable, saveVariable, removeVariable, deleteVariable }
}
env.spec.ts
:
import { useEnv } from '../use-env'
import { renderHook } from '@testing-library/react'
describe('use-env', () => {
it('should return at least one variable', () => {
const { result } = renderHook(() => useEnv())
expect(result.current.variables.length).toBeGreaterThan(0)
})
})
tsconfig.json
:
{
"compilerOptions": {
"esModuleInterop": true,
"target": "ES2020",
"useDefineForClassFields": true,
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"module": "ESNext",
"skipLibCheck": true,
/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx",
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true
},
"include": ["src"],
"references": [{ "path": "./tsconfig.node.json" }]
}
jest.config
:
import type { Config } from 'jest'
const config: Config = {
verbose: true,
testEnvironment: 'jsdom',
preset: 'ts-jest',
setupFilesAfterEnv: ['./jest.setup.ts'],
}
export default config
vite.config.ts
:
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react-swc";
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
});
CodeSandbox