...
 
Commits (2)
const restrictedGlobals = require('confusing-browser-globals');
module.exports = {
'parser': 'babel-eslint',
'plugins': [
'flowtype',
'react',
'jsx-a11y'
],
'extends': [
'eslint:recommended',
'plugin:flowtype/recommended',
'plugin:react/recommended',
'react-app',
'plugin:jsx-a11y/recommended'
],
'parserOptions': {
'ecmaVersion': 8,
'sourceType': 'module',
'ecmaFeatures': {
'impliedStrict': true,
'experimentalObjectRestSpread': true,
'jsx': true,
}
},
'env': {
'es6': true,
'node': true,
'jest': true,
'browser': true,
'webextensions': true,
},
'rules': {
'flowtype/space-after-type-colon': 'off',
'no-console': 'off',
'no-unused-vars': 'warn',
'no-restricted-globals': ['warn'].concat(restrictedGlobals),
}
};
{
"parser": "babel-eslint",
"plugins": [
"flowtype",
"react"
],
"extends": [
"eslint:recommended",
"plugin:flowtype/recommended",
"plugin:react/recommended"
],
"parserOptions": {
"ecmaVersion": 8,
"sourceType": "module",
"ecmaFeatures": {
"impliedStrict": true,
"experimentalObjectRestSpread": true,
"jsx": true
}
},
"env": {
"es6": true,
"node": true,
"jest": true,
"browser": true,
"webextensions": true
},
"rules": {
"flowtype/space-after-type-colon": "off",
"no-console": "off",
"no-unused-vars": "warn"
}
}
......@@ -4,6 +4,10 @@
(todo: adding a new `components` subdir)
(todo: universe, components, dist, test-nc and test-ib, etc)
(todo: start with list-tasks [but really start with npm install and npm init])
(todo: dev-utils dotenv.config vs devUtils.populateEnv)
(todo: redux, motion, formik)
(todo: flow; do not use any prop type anything at all ever)
(todo: recommended global plugins for IDE integrations on Windows/WSL)
This is one of those [boilerplate](https://git.xunn.io/boilerplate) futuristic web dev environments your parents warned you about.
......
// flow-disable-line
import { populateEnv } from './src/dev-utils'
populateEnv();
const sourceMapPlugin = 'babel-plugin-source-map-support';
const sourceMapValue = 'inline';
// ? Next.js-specific Babel settings
const devNextBabelPreset = ['next/babel', {
const nextBabelPreset = ['next/babel', {
'preset-env': {
// ? We want Create React App to be IE 9 compatible until React itself
// ? no longer works with IE 9
//// targets: 'last 2 chrome versions',
targets: {
ie: 9,
},
// ? If users import all core-js they're probably not concerned with
// ? bundle size. We shouldn't rely on magic to try and shrink it.
useBuiltIns: false,
// ? Do not transform modules to CJS
// ! MUST BE FALSE (see: https://nextjs.org/docs/#customizing-babel-config)
modules: false
modules: false,
// ? Exclude transforms that make all code slower
exclude: ['transform-typeof-symbol'],
},
'transform-runtime': {},
'styled-jsx': {},
'class-properties': {}
'class-properties': {
// ? Justification: https://tinyurl.com/yakv4ggx
loose: true
}
}];
// ? Transpile targets for jest tests
const testTargets = 'last 2 chrome versions';
const jestTestTargets = 'last 2 chrome versions';
module.exports = {
plugins: [
......@@ -24,20 +47,26 @@ module.exports = {
'@babel/plugin-proposal-json-strings',
// * https://babeljs.io/blog/2018/09/17/decorators
['@babel/plugin-proposal-decorators', { 'decoratorsBeforeExport': true }],
'@babel/plugin-proposal-optional-chaining'
'@babel/plugin-proposal-optional-chaining',
],
presets: [
['@babel/preset-flow'],
['@babel/preset-react']
],
// ? Subkeys under the "env" config key will augment the above configuration
// ? depending on the value of NODE_ENV and friends. Default is: development
env: {
production: {},
debug: { /* defined elsewhere */ },
production: {
// ? Handled by Next.js and Webpack
/* sourceMaps: sourceMapValue,
plugins: [sourceMapPlugin], */
presets: [nextBabelPreset]
},
test: {
sourceMaps: sourceMapValue,
plugins: [sourceMapPlugin],
presets: [
['@babel/preset-env', { targets: testTargets }],
['@babel/preset-env', { targets: jestTestTargets }],
['@babel/preset-react', { development: true }]
]
},
......@@ -45,7 +74,7 @@ module.exports = {
// ? Handled by Next.js and Webpack
/* sourceMaps: sourceMapValue,
plugins: [sourceMapPlugin], */
presets: [devNextBabelPreset]
presets: [nextBabelPreset]
},
generator: {
sourceMaps: sourceMapValue,
......@@ -58,7 +87,8 @@ module.exports = {
}
}]
]
}
},
debug: { /* defined elsewhere */ },
}
};
......
......@@ -21,18 +21,8 @@ import replaceInFile from 'replace-in-file'
import sh from 'shelljs'
import chalk from 'chalk'
require('dotenv').config();
const {
BUNDLE_ANALYZE
} = process.env;
// ? Add any sanity checks/sentinels to this function body
// ! The existence of any new constants added to dist.env should be checked here
const sanityCheck = () => {
if(typeof BUNDLE_ANALYZE !== 'string')
throw new TypeError('BUNDLE_ANALYZE is improperly defined. Did you copy dist.env -> .env ?');
};
// flow-disable-line
import { populateEnv } from './src/dev-utils'
sh.config.silent = true;
sh.config.fatal = true;
......@@ -68,7 +58,7 @@ const readFileAsync = promisify(readFile);
// * CLEANTYPES
const cleanTypes = async () => {
sanityCheck();
populateEnv();
const targets = parseGitIgnore(await readFileAsync(paths.flowTypedGitIgnore));
......@@ -85,7 +75,7 @@ cleanTypes.description = `Resets the ${paths.flowTyped} directory to a pristine
// ? compiled logic. If there is an error that prevents regeneration, you can
// ? run `npm run generate` then `npm run regenerate` instead.
const regenerate = () => {
sanityCheck();
populateEnv();
log(`Regenerating targets: "${paths.regenTargets.join('" "')}"`);
......
......@@ -2,26 +2,26 @@
import withBundleAnalyzer from '@zeit/next-bundle-analyzer'
import styledJsxWebpack from 'styled-jsx/webpack'
// flow-disable-line
import { populateEnv } from './src/dev-utils'
require('dotenv').config();
populateEnv();
const {
BUNDLE_ANALYZE
} = process.env;
if(typeof BUNDLE_ANALYZE !== 'string')
throw new TypeError('BUNDLE_ANALYZE is improperly defined. Did you copy dist.env -> .env ?');
const paths = {
universe: `${__dirname}/src/`,
components: `${__dirname}/src/components/`,
};
module.exports = (phase: string, { defaultConfig }: Object) => { // eslint-disable-line no-unused-vars
module.exports = (/* phase: string, { defaultConfig }: Object */) => {
return withBundleAnalyzer({
// ? Renames the build dir "build" instead of ".next"
distDir: 'build',
// ? Selectively enables bundle analysis. See dist.env or README for details
analyzeServer: ['server', 'both'].includes(BUNDLE_ANALYZE),
analyzeBrowser: ['browser', 'both'].includes(BUNDLE_ANALYZE),
bundleAnalyzerConfig: {
......@@ -38,7 +38,9 @@ module.exports = (phase: string, { defaultConfig }: Object) => { // eslint-disab
// ? Webpack configuration
// ! Note that the webpack configuration is executed twice: once
// ! server-side and once client-side!
webpack: (config: Object, { isServer, defaultLoaders }: Object) => {
webpack: (config: Object, { /* isServer, */ defaultLoaders }: Object) => {
// ? Anytime we import a file that ends in `.css`, run the special
// ? JSX loader so we can do cool css-in-js stuff
config.module.rules.push({
test: /\.css$/,
use: [
......
......@@ -4,4 +4,12 @@
#BUNDLE_ANALYZE=both
BUNDLE_ANALYZE=none
# This is the default NODE_ENV setting for the application. Recognized values:
# development
# test
# production
#
# This can be overwritten in the cli, i.e. `NODE_ENV=production npm run test-ib`
NODE_ENV=development
# Shopify store api configuration variables are stored here
This diff is collapsed.
This diff is collapsed.
/* @flow */
// * Due to this file being imported directly in node, Node-compliant ES6 must
// * be used, and node doesn't support import statements. Once Node catches up
// * with the times, all dirty ES5 artifacts like require() should be replaced
// * their superior language features
const pkg = require('../package.json');
const dotenv = require('dotenv');
const expectedEnvVariables = pkg.expectedEnvVariables || [];
if(!Array.isArray(expectedEnvVariables))
throw new Error('expectedEnvVariables in package.json must be an array');
const throwEnvError = variable => {
throw new Error(`${variable} is improperly defined. Did you copy dist.env -> .env ?`);
};
module.exports = {
populateEnv() {
const conf = dotenv.config();
// ? Parse the .env file at the project root or throw an error if it does
// ? not exist or if parsing fails for some other reason
if(!conf || !conf.parsed)
throw new Error('Failed to parse an .env configuration. Did you copy dist.env -> .env ?');
// ? Loop over the values in expectedEnvVariables from package.json to
// ? ensure they exist and are strings. If this is not the case, throw an
// ? error. There are two loops here to allow for "or syntax," i.e.
// ? var1|var2|var3 (see README)
expectedEnvVariables.forEach(variable =>
variable.split('|').every(subvar => typeof process.env[subvar] !== 'string') && throwEnvError(variable)
);
// ? Resolve the true node/application environment mode --> APP_ENV
// ? Recognized values: development, test, production
process.env.APP_ENV = process.env.NODE_ENV || process.env.BABEL_ENV || process.env.APP_ENV || 'unknown';
process.env.APP_ENV == 'unknown' && console.warn('WARNING: the application environment resolved to "unknown"!');
}
};