Last active
July 21, 2022 04:11
-
-
Save devinrhode2/e033cf8ec4653cfb70d34389db86cb72 to your computer and use it in GitHub Desktop.
next.config.js typed with jsdoc, and shared modules. Next 12 + webpack 5. See prior revisions for next 11 support.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const { safeEnv } = require('./src/env') | |
// Note: NextConfig type allows any keys, so we are plucking the specific keys we want to type-check. | |
/** | |
* @type {Pick< | |
* import('next').NextConfig, | |
* | 'webpack' | |
* | 'env' | |
* >} | |
*/ | |
const nextConfig = { | |
/** | |
* @type {( | |
* config: import('webpack').Configuration, | |
* context: { | |
* dev: boolean | |
* webpack: import('webpack') | |
* } | |
* ) => import('webpack').Configuration} | |
*/ | |
webpack: (config, { dev, webpack }) => { | |
// ... | |
return config | |
}, | |
env: safeEnv, | |
} | |
module.exports = nextConfig |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @type {(rawEnv: { | |
* readonly [x: string]: string | undefined | |
* }) => (varName: string) => string} | |
*/ | |
module.exports = (rawEnv) => (varName) => { | |
const envVar = rawEnv[varName] | |
if (!envVar) { | |
console.log('environment variables:', process.env) | |
if (envVar === undefined) { | |
throw new Error( | |
[ | |
`environment variable ${varName} is undefined.`, | |
rawEnv.CI | |
? `It may not be getting passed to "yarn build:ci" in azure-pipelines.yml` | |
: `Add it to your .env.local file`, | |
].join('\n'), | |
) | |
} | |
if (envVar === '') { | |
throw new Error( | |
[ | |
`environment variable ${varName} is an empty string.`, | |
rawEnv.CI | |
? `Check Azure Pipeline Variables Library for "Development" Environment` | |
: `Please put some value into your .env.local file`, | |
].join('\n'), | |
) | |
} | |
throw new Error( | |
`environment variable ${varName} is unknown falsey value: ${envVar}`, | |
) | |
} | |
return envVar | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// .js since this is used in next.config.js | |
// Fingers crossed Next will support next.config.TS soon: https://github.com/vercel/next.js/issues/5318 | |
const createGetEnvVar = require('./createGetEnvVar') | |
// @ts-expect-error - this is the only code allowed to reference `process.env` | |
const getEnvVar = createGetEnvVar(process.env) | |
// Using object instead of array, for jsdoc. | |
// MANUALLY sync `src/env.js` and azure-pipelines.yml (az webapp config, build:ci, envLocal) | |
// Only vars prefixed with `NEXT_PUBLIC_` will be exposed to browser. Rest are for server side use. | |
module.exports = { | |
// Just type `safeEnv<TAB>` and viola! | |
// 1. Without this line, hovering over `safeEnv` will show just `import safeEnv` :) | |
// By namespacing, we get fuller hover annotation | |
// 2. Using name `safeEnv` allows you to type just `saveEnv<TAB>` and auto-import correct module. | |
// Typing just `env<TAB>` will give you `import env from 'yargs'` :) | |
// Filename does not match export name, because you have to choose between default export, and this named export. | |
safeEnv: { | |
/** Ex: `'myapp staging'` - create unique name for your local configs: "devin-jan-14" */ | |
APPLICATION_TITLE: getEnvVar('APPLICATION_TITLE'), | |
// ... | |
}, | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
declare namespace NodeJS { | |
interface Process { | |
/** @deprecated use `safeEnv` instead */ | |
env: "Use `safeEnv` from 'src/env' instead." | |
// Upon typing `process.env.foo` you will get this type error: | |
// "Property 'foo' does not exist on type '"Use `safeEnv` from 'src/env' instead."'.ts(2339)" | |
// Ideally we use no-process-env eslint rule, | |
// but we need support for custom message: https://github.com/mysticatea/eslint-plugin-node/issues/318 | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Show hidden characters
{ | |
"compilerOptions": { | |
"module": "esnext", | |
"target": "es2017", | |
"lib": ["dom", "dom.iterable", "esnext"], | |
"jsx": "preserve", | |
"allowJs": true, | |
"checkJs": true, | |
"skipLibCheck": true, | |
"strict": true, | |
"forceConsistentCasingInFileNames": true, | |
"noEmit": true, | |
"esModuleInterop": true, | |
"moduleResolution": "node", | |
"resolveJsonModule": true, | |
"isolatedModules": true | |
}, | |
"typeRoots": ["./src/global-types", "./node_modules/@types"], | |
"include": [ | |
"next-env.d.ts", | |
"**/*.ts", | |
"**/*.tsx", | |
"**/*.js", | |
"**/.*rc.js", | |
"**/*.jsx" | |
], | |
"exclude": [ | |
"node_modules", | |
".next", | |
"out", | |
"public", | |
"coverage" | |
] | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment