diff --git a/.babelrc.js b/.babelrc.js new file mode 100644 index 0000000..301ed62 --- /dev/null +++ b/.babelrc.js @@ -0,0 +1,12 @@ +const { BABEL_ENV, NODE_ENV } = process.env +const modules = BABEL_ENV === 'cjs' || NODE_ENV === 'test' ? 'commonjs' : false +const loose = true + +module.exports = { + presets: [ + ['@babel/env', { + loose, + modules, + }], + ], +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f06235c --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +node_modules +dist diff --git a/.lintstagedrc b/.lintstagedrc new file mode 100644 index 0000000..f5bcf6d --- /dev/null +++ b/.lintstagedrc @@ -0,0 +1,10 @@ +{ + "{src,__tests__}/**/*.js": [ + "prettier --single-quote --no-semi --trailing-comma=all --write", + "git add" + ], + "*.md": [ + "prettier --single-quote --no-semi --trailing-comma=all --write", + "git add" + ] +} diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000..43c97e7 --- /dev/null +++ b/.npmrc @@ -0,0 +1 @@ +package-lock=false diff --git a/README.md b/README.md new file mode 100644 index 0000000..47a45b3 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +# rollup-plugin-dotenv diff --git a/package.json b/package.json new file mode 100644 index 0000000..6a68385 --- /dev/null +++ b/package.json @@ -0,0 +1,45 @@ +{ + "name": "rollup-plugin-dotenv", + "version": "0.0.0", + "description": "", + "main": "dist/rollup-plugin-dotenv.js", + "files": [ + "dist" + ], + "scripts": { + "precommit": "lint-staged", + "prebuild": "rimraf dist", + "build": "rollup -c", + "prepare": "npm run build" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/Andarist/rollup-plugin-dotenv.git" + }, + "keywords": [ + "rollup", + "dotenv" + ], + "author": "Mateusz BurzyƄski (https://github.com/Andarist)", + "license": "MIT", + "bugs": { + "url": "https://github.com/Andarist/rollup-plugin-dotenv/issues" + }, + "homepage": "https://github.com/Andarist/rollup-plugin-dotenv#readme", + "devDependencies": { + "@babel/core": "7.0.0-beta.51", + "@babel/plugin-proposal-object-rest-spread": "7.0.0-beta.51", + "@babel/preset-env": "7.0.0-beta.51", + "builtin-modules": "^3.0.0", + "husky": "^0.14.3", + "lint-staged": "^7.0.0", + "prettier": "^1.13.5", + "rimraf": "^2.6.2", + "rollup": "^0.60.7", + "rollup-plugin-babel": "4.0.0-beta.5" + }, + "dependencies": { + "dotenv": "^6.0.0", + "rollup-plugin-replace": "^2.0.0" + } +} diff --git a/rollup.config.js b/rollup.config.js new file mode 100644 index 0000000..8ea246e --- /dev/null +++ b/rollup.config.js @@ -0,0 +1,22 @@ +import babel from 'rollup-plugin-babel' +import builtinModules from 'builtin-modules' +import pkg from './package.json' + +const makeExternalPredicate = externalsArr => { + if (externalsArr.length === 0) { + return () => false + } + const externalPattern = new RegExp(`^(${ externalsArr.join('|') })($|/)`) + return id => externalPattern.test(id) +} + +export default { + input: 'src/index.js', + output: { file: pkg.main, format: 'cjs' }, + external: makeExternalPredicate([ + ...builtinModules, + ...Object.keys(pkg.dependencies || {}), + ...Object.keys(pkg.peerDependencies || {}), + ]), + plugins: [babel()], +} diff --git a/src/index.js b/src/index.js new file mode 100644 index 0000000..525f7ad --- /dev/null +++ b/src/index.js @@ -0,0 +1,46 @@ +import fs from 'fs' +import path from 'path' +import dotenv from 'dotenv' +import replace from 'rollup-plugin-replace' +import { mapKeys, mapValues, pick, pipe, shallowMergeAll } from './utils' + +const withDefaults = ({ cwd = '.', envKey = 'NODE_ENV' } = {}) => ({ + cwd: path.resolve(process.cwd(), cwd), + envKey, +}) + +export default function dotenvPlugin(inputOptions) { + const { cwd, envKey } = withDefaults(inputOptions) + + return { + ...replace( + pipe( + priorities => + [...priorities] + .reverse() + .map(dotenvFile => path.join(cwd, dotenvFile)) + .filter(fs.existsSync) + .map(dotenvFile => fs.readFileSync(dotenvFile)) + .map(dotenv.parse), + shallowMergeAll, + envVars => + shallowMergeAll([ + envVars, + pick( + Object.keys(envVars).filter( + key => process.env[key] !== undefined, + ), + process.env, + ), + ]), + envVars => mapKeys(key => `process.env.${key}`, envVars), + envVars => mapValues(value => JSON.stringify(value), envVars), + )([ + `.env.${process.env[envKey]}.local`, + `.env.${process.env[envKey]}`, + '.env', + ]), + ), + name: 'dotenv', + } +} diff --git a/src/utils.js b/src/utils.js new file mode 100644 index 0000000..0be41c5 --- /dev/null +++ b/src/utils.js @@ -0,0 +1,22 @@ +export const mapKeys = (mapper, obj) => + Object.keys(obj).reduce((acc, key) => { + acc[mapper(key)] = obj[key] + return acc + }, {}) + +export const mapValues = (mapper, obj) => + Object.keys(obj).reduce((acc, key) => { + acc[key] = mapper(obj[key]) + return acc + }, {}) + +export const pick = (props, obj) => + props.reduce((acc, prop) => { + acc[prop] = obj[prop] + return acc + }, {}) + +export const pipe = (...funcs) => + funcs.reduceRight((piped, next) => (...args) => piped(next(...args))) + +export const shallowMergeAll = objs => Object.assign(...objs)