Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: rewrite tests to use webpack compiler, drop node 8 #360

Merged
merged 25 commits into from
Mar 5, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ jobs:
runs-on: ubuntu-18.04
strategy:
matrix:
node: [ '8', '10', '12', '14' ]
node: [ '10', '12', '14' ]
steps:
- name: 🛑 Cancel Previous Runs
uses: styfle/[email protected]
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# Tests
test/output

# Logs
logs
*.log
Expand Down
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,14 @@ Add `.env` to your `.gitignore` file

Due to the fact that we use `webpack.DefinePlugin` under the hood, we cannot support destructing as that breaks how this plugin is meant to be used. Because of this, please reference your variables without destructing. For more information about this, please review the issue [here](https://github.com/mrsteele/dotenv-webpack/issues/70).

## `process.env` stubbing / replacing

`process.env` is not polyfilled in Webpack 5+, leading to errors in environments where `process` is `null` (browsers).

We automatically replace any remaining `process.env`s in these environments with `"MISSING_ENV_VAR"` to avoid these errors.

If you are running into issues where you or another package you use interfaces with `process.env`, it might be best to set `ignoreStubs: true` and make sure you always reference variables that exist within your code (See [this issue](https://github.com/mrsteele/dotenv-webpack/issues/271) for more information).

## Properties

Use the following properties to configure your instance.
Expand All @@ -106,6 +114,7 @@ Use the following properties to configure your instance.
* **silent** (`false`) - If true, all warnings will be suppressed.
* **expand** (`false`) - Allows your variables to be "expanded" for reusability within your `.env` file.
* **defaults** (`false`) - Adds support for `dotenv-defaults`. If set to `true`, uses `./.env.defaults`. If a string, uses that location for a defaults file. Read more at [npm](https://www.npmjs.com/package/dotenv-defaults).
* **ignoreStub** (`false`) - Override the automatic check whether to stub `process.env`. [Read more here](#user-content-processenv-stubbing--replacing).

The following example shows how to set any/all arguments.

Expand Down
34 changes: 34 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 9 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@
},
"jest": {
"coverageDirectory": "./coverage/",
"collectCoverage": true
"collectCoverage": true,
"watchPathIgnorePatterns": [
"output/.*?"
]
},
"keywords": [
"dotenv",
Expand All @@ -41,8 +44,11 @@
"url": "https://github.com/mrsteele/dotenv-webpack/issues"
},
"homepage": "https://github.com/mrsteele/dotenv-webpack#readme",
"engines": {
"node": ">=10"
},
"peerDependencies": {
"webpack": "^1 || ^2 || ^3 || ^4 || ^5"
"webpack": "^4 || ^5"
},
"dependencies": {
"dotenv-defaults": "^2.0.1"
Expand All @@ -52,6 +58,7 @@
"@babel/core": "^7.13.8",
"@babel/preset-env": "^7.13.9",
"@babel/register": "^7.13.8",
"fs-extra": "^9.1.0",
"husky": "^5.1.3",
"jest": "^25.5.4",
"jsdoc": "^3.6.6",
Expand Down
66 changes: 47 additions & 19 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ const interpolate = (env, vars) => {
return env
}

const isMainThreadElectron = (target) =>
target.startsWith('electron') && target.endsWith('main')

class Dotenv {
/**
* The dotenv-webpack plugin.
Expand All @@ -30,21 +33,19 @@ class Dotenv {
this.config = Object.assign({}, {
path: './.env'
}, config)

this.checkDeprecation()

return new DefinePlugin(this.formatData(this.gatherVariables()))
}

checkDeprecation () {
const { sample, safe, silent } = this.config
// Catch older packages, but hold their hand (just for a bit)
if (sample) {
if (safe) {
this.config.safe = sample
}
this.warn('dotenv-webpack: "options.sample" is a deprecated property. Please update your configuration to use "options.safe" instead.', silent)
}
apply (compiler) {
const variables = this.gatherVariables()
const target = compiler.options.target ?? 'web'
const version = compiler.webpack.version
const data = this.formatData({
variables,
target,
version
})

new DefinePlugin(data).apply(compiler)
}

gatherVariables () {
Expand Down Expand Up @@ -121,10 +122,10 @@ class Dotenv {
return ''
}

formatData (vars = {}) {
formatData ({ variables = {}, target, version }) {
const { expand } = this.config
const formatted = Object.keys(vars).reduce((obj, key) => {
const v = vars[key]
const formatted = Object.keys(variables).reduce((obj, key) => {
const v = variables[key]
const vKey = `process.env.${key}`
let vValue
if (expand) {
Expand All @@ -133,7 +134,7 @@ class Dotenv {
} else if (v.indexOf('\\$') > 0) {
vValue = v.replace(/\\\$/g, '$')
} else {
vValue = interpolate(v, vars)
vValue = interpolate(v, variables)
}
} else {
vValue = v
Expand All @@ -144,12 +145,39 @@ class Dotenv {
return obj
}, {})

// fix in case of missing
formatted['process.env'] = '{}'
// We have to stub any remaining `process.env`s due to Webpack 5 not polyfilling it anymore
// https://github.com/mrsteele/dotenv-webpack/issues/240#issuecomment-710231534
// However, if someone targets Node or Electron `process.env` still exists, and should therefore be kept
// https://webpack.js.org/configuration/target
if (this.shouldStub({ target, version })) {
// Results in `"MISSING_ENV_VAR".NAME` which is valid JS
formatted['process.env'] = '"MISSING_ENV_VAR"'
beeequeue marked this conversation as resolved.
Show resolved Hide resolved
}

return formatted
}

shouldStub ({ target: targetInput, version }) {
if (!version.startsWith('5')) {
return false
}

const targets = Array.isArray(targetInput) ? targetInput : [targetInput]

return targets.every(
target =>
// If we're not configured to never stub
this.config.ignoreStub !== true &&
// And
(
// We are configured to always stub
this.config.ignoreStub === false ||
// Or if we should according to the target
(!target.includes('node') && !isMainThreadElectron(target))
)
)
}

/**
* Load a file.
* @param {String} config.file - The file to load.
Expand Down
28 changes: 28 additions & 0 deletions test/fixtures/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/* eslint-disable no-unused-vars */

// Basic
const TEST = process.env.TEST
const TEST2 = process.env.TEST2

// System
const PATH = process.env.PATH

// Expanded
const NODE_ENV = process.env.NODE_ENV
const BASIC = process.env.BASIC
const BASIC_EXPAND = process.env.BASIC_EXPAND
const MACHINE = process.env.MACHINE
const MACHINE_EXPAND = process.env.MACHINE_EXPAND
const UNDEFINED_EXPAND = process.env.UNDEFINED_EXPAND
const ESCAPED_EXPAND = process.env.ESCAPED_EXPAND
const MONGOLAB_DATABASE = process.env.MONGOLAB_DATABASE
const MONGOLAB_USER = process.env.MONGOLAB_USER
const MONGOLAB_PASSWORD = process.env.MONGOLAB_PASSWORD
const MONGOLAB_DOMAIN = process.env.MONGOLAB_DOMAIN
const MONGOLAB_PORT = process.env.MONGOLAB_PORT
const MONGOLAB_URI = process.env.MONGOLAB_URI
const MONGOLAB_USER_RECURSIVELY = process.env.MONGOLAB_USER_RECURSIVELY
const MONGOLAB_URI_RECURSIVELY = process.env.MONGOLAB_URI_RECURSIVELY
const WITHOUT_CURLY_BRACES_URI = process.env.WITHOUT_CURLY_BRACES_URI
const WITHOUT_CURLY_BRACES_USER_RECURSIVELY = process.env.WITHOUT_CURLY_BRACES_USER_RECURSIVELY
const WITHOUT_CURLY_BRACES_URI_RECURSIVELY = process.env.WITHOUT_CURLY_BRACES_URI_RECURSIVELY
Loading