Skip to content

Commit 721bd19

Browse files
authored
Add env variables support (#22)
1 parent 774b297 commit 721bd19

File tree

6 files changed

+70
-7
lines changed

6 files changed

+70
-7
lines changed

.changeset/stupid-shrimps-greet.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@fransvilhelm/wp-bundler': minor
3+
---
4+
5+
Add env variable support similar to CRA

README.md

+37
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ browsers as well.
2626
- [External dependencies](#external-dependencies)
2727
- [Translations](#translations)
2828
- [PHP and Twig translations](#php-and-twig-translations)
29+
- [Environment variables](#environment-variables)
30+
- [Other injected variables](#other-injected-variables)
31+
- [Other `.env` files](#other-env-files)
2932
- [Other WordPress focused bundlers](#other-wordpress-focused-bundlers)
3033
- [Roadmap](#roadmap)
3134
- [LICENSE](#license)
@@ -280,6 +283,40 @@ means you are no longer need to use `wp-cli i18n make-pot/make-json` to extract
280283

281284
`.mo` files will also me compiled from all your `.po` files.
282285

286+
## Environment variables
287+
288+
You can define environment variables in a `.env` file located in the root of you project, right by you `package.json`
289+
file. `wp-bundler` will inject any env variable defined in those that starts with `WP_`.
290+
291+
- `WP_API_KEY` => injected
292+
- `API_KEY` => not injected
293+
294+
Then in your application code you can access those by reading `process.env.WP_API_KEY` (or whatever the variable was
295+
called).
296+
297+
The variables defined in `.env` will not override any environment variables already set.
298+
299+
### Other injected variables
300+
301+
Except environment variable prefixed with `WP_` `wp-bundler` will also inject the following variables:
302+
303+
- `process.env.NODE_ENV`: `'production'` during build, `'development'` in watch mode
304+
- `__DEV__`: `false` during build, `true` in watch mode
305+
- `__PROD__`: `true` during build, `false` in watch mode
306+
307+
### Other `.env` files
308+
309+
Except the `.env` file you can use a few other `.env` files to inject variables from. The list below defines which files
310+
are read during which script. Files to the left have more priority than files to the right. Meaning that variables
311+
coming from a file to the left will override a variable coming from a file to the right.
312+
313+
- `wp-bundler` (or `--mode prod`): `.env.production.local` > `.env.local` > `.env.production` > `.env`
314+
- `wp-bundler --watch` (or `--mode dev`): `.env.development.local` > `.env.local` > `.env.development` > `.env`
315+
316+
With this structure you could have a `.env` file tracked by `git` and then allow developers to override these defaults
317+
with their own `.env.local` files, which should not be checked into `git`. This is the same mechanism as
318+
[`create-react-app` uses](https://create-react-app.dev/docs/adding-custom-environment-variables/#adding-development-environment-variables-in-env).
319+
283320
## Other WordPress focused bundlers
284321

285322
The following projects might interest you if `wp-bundler` doesn't meet your requirements.

example/src/app.tsx

+2
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,5 @@ ReactDOM.render(
1919
</React.Suspense>,
2020
document.getElementById('root'),
2121
);
22+
23+
console.log(process.env.WP_TEST);

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@
6464
"@xstate/react": "^1.6.1",
6565
"autoprefixer": "^10.3.7",
6666
"babel-eslint": "^10.1.0",
67+
"dotenv": "^10.0.0",
6768
"eslint": "^7.32.0",
6869
"eslint-config-react-app": "^6.0.0",
6970
"eslint-plugin-flowtype": "^6.1.0",

src/plugins/define.ts

+20-7
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,28 @@
1+
import * as dotenv from 'dotenv';
2+
import * as fs from 'fs';
13
import { BundlerPlugin } from '../types';
24

3-
export const define: BundlerPlugin = ({ mode }) => ({
5+
export const define: BundlerPlugin = ({ mode, project }) => ({
46
name: 'wp-bundler-define',
57
setup(build) {
6-
const options = build.initialOptions;
7-
options.define = options.define || {};
8+
build.initialOptions.define = build.initialOptions.define ?? {};
89

9-
options.define['process.env.NODE_ENV'] =
10-
mode === 'prod' ? JSON.stringify('production') : JSON.stringify('development');
10+
let NODE_ENV = mode === 'dev' ? 'development' : 'production';
11+
build.initialOptions.define['process.env.NODE_ENV'] = JSON.stringify(NODE_ENV);
12+
build.initialOptions.define['__DEV__'] = JSON.stringify(mode === 'dev');
13+
build.initialOptions.define['__PROD__'] = JSON.stringify(mode === 'prod');
1114

12-
options.define['__DEV__'] = JSON.stringify(mode === 'dev');
13-
options.define['__PROD__'] = JSON.stringify(mode === 'prod');
15+
let envFiles = [`.env.${NODE_ENV}.local`, '.env.local', `.env.${NODE_ENV}`, '.env'];
16+
17+
for (let file of envFiles) {
18+
if (fs.existsSync(file)) dotenv.config({ path: project.paths.absolute(file) });
19+
}
20+
21+
let WP_ = /^WP_/i;
22+
for (let key of Object.keys(process.env)) {
23+
if (WP_.test(key)) {
24+
build.initialOptions.define[`process.env.${key}`] = JSON.stringify(process.env[key]);
25+
}
26+
}
1427
},
1528
});

yarn.lock

+5
Original file line numberDiff line numberDiff line change
@@ -2261,6 +2261,11 @@ domexception@^2.0.1:
22612261
dependencies:
22622262
webidl-conversions "^5.0.0"
22632263

2264+
dotenv@^10.0.0:
2265+
version "10.0.0"
2266+
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-10.0.0.tgz#3d4227b8fb95f81096cdd2b66653fb2c7085ba81"
2267+
integrity sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==
2268+
22642269
dotenv@^8.1.0:
22652270
version "8.6.0"
22662271
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.6.0.tgz#061af664d19f7f4d8fc6e4ff9b584ce237adcb8b"

0 commit comments

Comments
 (0)