Skip to content

Commit a1067ed

Browse files
authored
Merge pull request #2 from expatfile/development
chore: 🔖 release stable version
2 parents a459b85 + 195a171 commit a1067ed

10 files changed

+167
-84
lines changed

.eslintrc.js

+22-22
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,49 @@
11
module.exports = {
22
root: true,
3-
parser: "@typescript-eslint/parser",
3+
parser: '@typescript-eslint/parser',
44
extends: [
5-
"airbnb-base",
6-
"plugin:@typescript-eslint/recommended",
7-
"prettier",
8-
"plugin:prettier/recommended",
5+
'airbnb-base',
6+
'plugin:@typescript-eslint/recommended',
7+
'prettier',
8+
'plugin:prettier/recommended',
99
],
1010
parserOptions: {
1111
ecmaVersion: 2020,
12-
sourceType: "module",
12+
sourceType: 'module',
1313
},
1414
env: {
1515
node: true,
1616
jest: true,
1717
},
1818
rules: {
19-
"eol-last": ["error", "always"],
20-
"no-plusplus": ["error", { allowForLoopAfterthoughts: true }],
21-
"import/extensions": ["off"],
22-
"import/prefer-default-export": ["off"],
23-
"simple-import-sort/imports": "warn",
24-
"simple-import-sort/exports": "warn",
25-
"@typescript-eslint/no-empty-interface": ["off"],
26-
"@typescript-eslint/explicit-function-return-type": ["off"],
19+
'eol-last': ['error', 'always'],
20+
'no-plusplus': ['error', { allowForLoopAfterthoughts: true }],
21+
'import/extensions': ['off'],
22+
'import/prefer-default-export': ['off'],
23+
'simple-import-sort/imports': 'warn',
24+
'simple-import-sort/exports': 'warn',
25+
'@typescript-eslint/no-empty-interface': ['off'],
26+
'@typescript-eslint/explicit-function-return-type': ['off'],
2727
},
2828
overrides: [
2929
{
30-
files: ["src/__mocks__/.*", "**/*.spec.ts"],
30+
files: ['src/__mocks__/.*', '**/*.spec.ts'],
3131
rules: {
32-
"import/no-extraneous-dependencies": [
33-
"error",
32+
'import/no-extraneous-dependencies': [
33+
'error',
3434
{ devDependencies: true },
3535
],
36-
"@typescript-eslint/no-empty-function": ["off"],
37-
"@typescript-eslint/no-non-null-assertion": ["off"],
36+
'@typescript-eslint/no-empty-function': ['off'],
37+
'@typescript-eslint/no-non-null-assertion': ['off'],
3838
},
3939
},
4040
],
4141
settings: {
42-
"import/resolver": {
42+
'import/resolver': {
4343
node: {
44-
extensions: [".js", ".ts"],
44+
extensions: ['.js', '.ts'],
4545
},
4646
},
4747
},
48-
plugins: ["simple-import-sort"],
48+
plugins: ['simple-import-sort'],
4949
};

.releaserc.yaml

+26-26
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,29 @@
11
branches:
2-
- main
3-
- name: development
4-
prerelease: alpha
5-
channel: alpha
2+
- main
3+
- name: development
4+
prerelease: alpha
5+
channel: alpha
66

77
plugins:
8-
- - "@semantic-release/commit-analyzer"
9-
- preset: angular
10-
releaseRules:
11-
- scope: no-release
12-
release: false
13-
- type: build
14-
release: patch
15-
- type: chore
16-
release: patch
17-
- type: ci
18-
release: false
19-
- type: docs
20-
release: false
21-
- type: style
22-
release: patch
23-
- type: refactor
24-
release: patch
25-
- type: test
26-
release: patch
27-
- - "@semantic-release/release-notes-generator"
28-
- - "@semantic-release/npm"
29-
- - "@semantic-release/github"
8+
- - "@semantic-release/commit-analyzer"
9+
- preset: angular
10+
releaseRules:
11+
- scope: no-release
12+
release: false
13+
- type: build
14+
release: patch
15+
- type: chore
16+
release: patch
17+
- type: ci
18+
release: false
19+
- type: docs
20+
release: false
21+
- type: style
22+
release: patch
23+
- type: refactor
24+
release: patch
25+
- type: test
26+
release: patch
27+
- - "@semantic-release/release-notes-generator"
28+
- - "@semantic-release/npm"
29+
- - "@semantic-release/github"

README.md

+69-26
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,34 @@
11
# next-runtime-env - Runtime Environment Configuration
22

3-
[![codecov](https://codecov.io/gh/expatfile/next-runtime-env/branch/main/graph/badge.svg?token=mbGgsweFuP)](https://codecov.io/gh/expatfile/next-runtime-env)
3+
![GitHub branch checks state][build-url] [![codecov][cov-img]][cov-url]
44

55
Populates your environment at **run-time** rather than **build-time**.
66

77
- Isomorphic - Server, browser and middleware compatible.
88
- Supports static site generation.
9-
- Supports `.env`, just like [Next.js](https://nextjs.org/docs/basic-features/environment-variables).
9+
- Supports `.env`, just like [Next.js][nextjs-env-vars].
1010

11-
Runtime environment variables are used in common best-practice patterns for building modern apps deployed via Docker. A big selling point of using Docker to begin with is to be able to build one image and have it work everywhere - dev, test, staging, production, etc - and having to "bake" in environment-specific configuration at build-time is antithetical to that goal. `next-runtime-env` aims to remove this hurdle by adding support for runtime environment variables to Next.js without sacrificing static site generation support.
11+
Runtime environment variables are used in common best-practice patterns for
12+
building modern apps deployed via Docker. A big selling point of using Docker to
13+
begin with is to be able to build one image and have it work everywhere - dev,
14+
test, staging, production, etc - and having to "bake" in environment-specific
15+
configuration at build-time is antithetical to that goal. `next-runtime-env`
16+
aims to remove this hurdle by adding support for runtime environment variables
17+
to Next.js without sacrificing static site generation support.
1218

1319
### Getting started 🚀
1420

1521
1. Add the following lines to your `next.config.js`:
1622

1723
```js
18-
const {
19-
configureRuntimeEnv,
20-
} = require('next-runtime-env/build/configure-runtime-env');
24+
const { configureRuntimeEnv } = require('next-runtime-env/build/configure');
2125

2226
configureRuntimeEnv();
2327
```
2428

25-
This will generates a `__ENV.js` file that contains allow-listed environment variables that have a `NEXT_PUBLIC_` prefix.
29+
When the server starts this will generates a `__ENV.js` file in the `public`
30+
folder that contains allow-listed environment variables that have a
31+
`NEXT_PUBLIC_` prefix.
2632

2733
2. Add the following to the head section fo your `pages/_document.js`:
2834

@@ -35,43 +41,80 @@ Done!
3541

3642
### Usage 🧑‍💻
3743

38-
In the browser your variables will be available at `window.__ENV.NEXT_PUBLIC_FOO` and on the server `process.env.NEXT_PUBLIC_FOO`.
44+
In the browser your variables will be available at
45+
`window.__ENV.NEXT_PUBLIC_FOO` and on the server `process.env.NEXT_PUBLIC_FOO`.
3946

4047
#### Helper 😉
4148

4249
We have included a helper function to make retrieving a value easier:
4350

4451
```bash
4552
# .env
46-
NEXT_PUBLIC_NEXT="Next.js"
47-
NEXT_PUBLIC_CRA="Create React App"
48-
NEXT_PUBLIC_NOT_SECRET_CODE="1234"
53+
NEXT_PUBLIC_FOO="foo"
54+
BAR="bar"
55+
```
56+
57+
```jsx
58+
type Props = {
59+
bar: string,
60+
};
61+
62+
export default function SomePage({ bar }: Props) {
63+
return (
64+
<div>
65+
{window.__ENV.NEXT_PUBLIC_FOO} {bar}
66+
</div>
67+
);
68+
}
69+
70+
export const getStaticProps: GetStaticProps = async (context) => {
71+
return {
72+
props: {
73+
bar: process.env.BAR,
74+
},
75+
};
76+
};
4977
```
5078

5179
Becomes...
5280

5381
```jsx
5482
import { env } from 'next-runtime-env';
5583

56-
export default (props) => (
57-
<div>
58-
<small>
59-
Works in the browser: <b>{env('NEXT_PUBLIC_CRA')}</b>.
60-
</small>
61-
<small>
62-
Also works for server side rendering: <b>{env('NEXT_PUBLIC_NEXT')}</b>.
63-
</small>
64-
<form>
65-
<input type="hidden" defaultValue={env('NEXT_PUBLIC_NOT_SECRET_CODE')} />
66-
</form>
67-
</div>
68-
);
84+
type Props = {
85+
bar: string,
86+
};
87+
88+
export default function SomePage({ bar }: Props) {
89+
return (
90+
<div>
91+
{env('NEXT_PUBLIC_FOO')} {bar}
92+
</div>
93+
);
94+
}
95+
96+
export const getStaticProps: GetStaticProps = async (context) => {
97+
return {
98+
props: {
99+
bar: env('BAR'),
100+
},
101+
};
102+
};
69103
```
70104

71105
### Maintenance 👷
72106

73-
This package is maintained and used by [Expatfile.tax](https://expatfile.tax). The #1 US expat tax e-filing software. 🇺🇸
107+
This package is maintained and used by [Expatfile.tax][expatfile-site].
108+
The #1 US expat tax e-filing software. 🇺🇸
74109

75110
### Other work 📚
76111

77-
Big thanks to the [react-env](https://github.com/andrewmclagan/react-env) project, which inspired us. 🙏
112+
Big thanks to the [react-env][react-env-repo]
113+
project, which inspired us. 🙏
114+
115+
[build-url]: https://img.shields.io/github/checks-status/expatfile/next-runtime-env/main
116+
[cov-img]: https://codecov.io/gh/expatfile/next-runtime-env/branch/main/graph/badge.svg?token=mbGgsweFuP
117+
[cov-url]: https://codecov.io/gh/expatfile/next-runtime-env
118+
[nextjs-env-vars]: https://nextjs.org/docs/basic-features/environment-variables
119+
[react-env-repo]: https://github.com/andrewmclagan/react-env
120+
[expatfile-site]: https://expatfile.tax

package.json

+7-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,13 @@
1414
"audit-ci": "audit-ci",
1515
"semantic-release": "semantic-release"
1616
},
17-
"keywords": [],
17+
"keywords": [
18+
"nextjs",
19+
"runtime",
20+
"env",
21+
"runtime env",
22+
"next-runtime-env"
23+
],
1824
"author": "Expatfile.tax LLC",
1925
"license": "MIT",
2026
"repository": {

src/configure.spec.ts

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { configureRuntimeEnv } from './configure';
2+
import { getPublicEnv } from './helpers/get-public-env';
3+
import { writeBrowserEnv } from './helpers/write-browser-env';
4+
5+
jest.mock('./helpers/get-public-env', () => ({
6+
getPublicEnv: jest.fn(() => ({
7+
NEXT_PUBLIC_FOO: 'foo',
8+
})),
9+
}));
10+
jest.mock('./helpers/write-browser-env', () => ({
11+
writeBrowserEnv: jest.fn(),
12+
}));
13+
14+
// See: https://www.bam.tech/article/fix-jest-mock-cannot-access-before-initialization-error
15+
const mockGetPublicEnv = getPublicEnv as jest.MockedFunction<
16+
typeof getPublicEnv
17+
>;
18+
const mockWriteBrowserEnv = writeBrowserEnv as jest.MockedFunction<
19+
typeof writeBrowserEnv
20+
>;
21+
22+
describe('configureRuntimeEnv()', () => {
23+
it('should call the helper methods', () => {
24+
configureRuntimeEnv();
25+
26+
expect(mockGetPublicEnv).toHaveBeenCalledTimes(1);
27+
28+
expect(mockWriteBrowserEnv).toHaveBeenCalledTimes(1);
29+
expect(mockWriteBrowserEnv).toHaveBeenCalledWith({
30+
NEXT_PUBLIC_FOO: 'foo',
31+
});
32+
});
33+
});
File renamed without changes.

src/env.spec.ts

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { env } from './env';
22

3-
describe('env', () => {
3+
describe('env()', () => {
44
afterEach(() => {
55
delete process.env.FOO;
66

@@ -9,22 +9,22 @@ describe('env', () => {
99
});
1010

1111
it('should return a value from the server', () => {
12-
process.env.FOO = 'bar';
12+
process.env.FOO = 'foo';
1313

14-
expect(env('FOO')).toBe('bar');
14+
expect(env('FOO')).toBe('foo');
1515
});
1616

1717
it('should return a value from the browser', () => {
1818
Object.defineProperty(global, 'window', {
1919
value: {
2020
__ENV: {
21-
NEXT_PUBLIC_FOO: 'bar',
21+
NEXT_PUBLIC_FOO: 'foo',
2222
},
2323
},
2424
writable: true,
2525
});
2626

27-
expect(env('NEXT_PUBLIC_FOO')).toBe('bar');
27+
expect(env('NEXT_PUBLIC_FOO')).toBe('foo');
2828
});
2929

3030
it('should return undefined when variable does not exist on the server', () => {
@@ -35,7 +35,7 @@ describe('env', () => {
3535
Object.defineProperty(global, 'window', {
3636
value: {
3737
__ENV: {
38-
NEXT_PUBLIC_FOO: 'bar',
38+
NEXT_PUBLIC_FOO: 'foo',
3939
},
4040
},
4141
writable: true,

src/env.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import { isBrowser } from './utils/is-browser';
22

33
/**
4-
* Reads an environment variable from the server or the browser.
4+
* Reads a safe environment variable from the browser or any environment
5+
* variable from the server (process.env).
56
*/
67
export function env(key: string) {
78
if (isBrowser()) {

src/helpers/get-public-env.spec.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { getPublicEnv } from './get-public-env';
22

3-
describe('getPublicEnv', () => {
3+
describe('getPublicEnv()', () => {
44
afterEach(() => {
55
delete process.env.FOO;
66
delete process.env.BAR;

src/helpers/write-browser-env.spec.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ afterAll(() => {
2020
fs.rmdirSync(path);
2121
});
2222

23-
describe('writeBrowserEnv', () => {
23+
describe('writeBrowserEnv()', () => {
2424
afterEach(() => {
2525
fs.rmSync(file);
2626
});

0 commit comments

Comments
 (0)