Commit d56552cb authored by Xunnamius (Markov)'s avatar Xunnamius (Markov)

minimum viable

parent dd5768b2
......@@ -27,7 +27,7 @@
},
"rules": {
"flowtype/space-after-type-colon": "off",
"no-console": "warn",
"no-console": "off",
"no-unused-vars": "warn"
}
}
......@@ -11,5 +11,8 @@
[options]
suppress_comment= \\(.\\|\n\\)*\\flow-disable-line
esproposal.optional_chaining=enable
module.name_mapper='^universe$' -> '<PROJECT_ROOT>/src'
module.name_mapper='^universe\/\(.*\)$' -> '<PROJECT_ROOT>/src/\1'
module.name_mapper='^components\/\(.*\)$' -> '<PROJECT_ROOT>/src/components/\1'
[strict]
node_modules/
build/
node_modules/
.next
.env
.vscode/launch.json
*.pem
package-lock.json
{
"extends": "stylelint-config-standard",
"rules": {
"number-leading-zero": "never"
"number-leading-zero": "always",
"indentation": 4
}
}
{
"files.exclude": {
"build": true,
"flow-typed": true
},
"cSpell.words": [
......
# nextjs-react-webpack-gulp-babel
(todo: talk about ANALYZE_WEBPACK_BUNDLES)
(todo: adding a new `components` subdir)
(todo: universe, components, dist, test-nc and test-ib, etc)
(todo: start with list-tasks)
This is one of those [boilerplate](https://git.xunn.io/boilerplate) futuristic web dev environments your parents warned you about.
<!-- TOC -->
......
......@@ -3,19 +3,27 @@ const sourceMapValue = 'inline';
// ? Next.js-specific Babel settings
const devNextBabelPreset = ['next/babel', {
'preset-env': {},
'preset-env': {
// ! MUST BE FALSE (see: https://nextjs.org/docs/#customizing-babel-config)
modules: false
},
'transform-runtime': {},
'styled-jsx': {},
'class-properties': {}
}];
// ? Transpile targets for jest tests
const testTargets = 'last 2 chrome versions';
module.exports = {
plugins: [
'@babel/plugin-proposal-class-properties',
'@babel/plugin-proposal-export-default-from',
'@babel/plugin-proposal-numeric-separator',
'@babel/plugin-proposal-throw-expressions',
'@babel/plugin-proposal-nullish-coalescing-operator',
'@babel/plugin-proposal-json-strings',
// * https://babeljs.io/blog/2018/09/17/decorators
['@babel/plugin-proposal-decorators', { 'decoratorsBeforeExport': true }],
'@babel/plugin-proposal-optional-chaining'
],
presets: [
......@@ -24,7 +32,15 @@ module.exports = {
],
env: {
production: {},
debug: {},
debug: { /* defined elsewhere */ },
test: {
sourceMaps: sourceMapValue,
plugins: [sourceMapPlugin],
presets: [
['@babel/preset-env', { targets: testTargets }],
['@babel/preset-react', { development: true }]
]
},
development: {
// ? Handled by Next.js and Webpack
/* sourceMaps: sourceMapValue,
......
......@@ -23,6 +23,13 @@ import chalk from 'chalk'
require('dotenv').config();
const {
BUNDLE_ANALYZE
} = process.env;
if(typeof BUNDLE_ANALYZE !== 'string')
throw new TypeError('BUNDLE_ANALYZE is improperly defined. Did you copy dist.env -> .env ?');
sh.config.silent = true;
sh.config.fatal = true;
......@@ -30,6 +37,8 @@ const paths = {};
paths.flowTyped = 'flow-typed';
paths.flowTypedGitIgnore = `${paths.flowTyped}/.gitignore`;
paths.build = `build`;
paths.buildGitIgnore = `${paths.build}/.gitignore`;
paths.configs = 'config';
paths.packageJson = 'package.json';
paths.launchJson = '.vscode/launch.json';
......@@ -52,6 +61,8 @@ const CLI_BANNER = `/**
const readFileAsync = promisify(readFile);
// * CLEANTYPES
const cleanTypes = async () => {
......
/* @flow */
import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer'
import { readdirSync, lstatSync } from 'fs'
import path from 'path'
import withBundleAnalyzer from '@zeit/next-bundle-analyzer'
import styledJsxWebpack from 'styled-jsx/webpack'
require('dotenv').config();
const { ANALYZE_WEBPACK_BUNDLES } = process.env;
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 = {
components: `${__dirname}/components`,
universe: `${__dirname}/src/`,
components: `${__dirname}/src/components/`,
};
module.exports = (phase: string, { defaultConfig }: Object) => { // eslint-disable-line no-unused-vars
return {
webpack: (config: Object, { isServer }: Object) => {
if(ANALYZE_WEBPACK_BUNDLES) {
config.plugins.push(new BundleAnalyzerPlugin({
analyzerMode: 'server',
analyzerPort: isServer ? 8888 : 8889,
openAnalyzer: true
}))
return withBundleAnalyzer({
// ? Renames the build dir "build" instead of ".next"
distDir: 'build',
analyzeServer: ['server', 'both'].includes(BUNDLE_ANALYZE),
analyzeBrowser: ['browser', 'both'].includes(BUNDLE_ANALYZE),
bundleAnalyzerConfig: {
server: {
analyzerMode: 'static',
reportFilename: 'bundle-analysis-server.html'
},
browser: {
analyzerMode: 'static',
reportFilename: 'bundle-analysis-client.html'
}
},
// ? Webpack configuration
// ! Note that the webpack configuration is executed twice: once
// ! server-side and once client-side!
webpack: (config: Object, { isServer, defaultLoaders }: Object) => {
config.module.rules.push({
test: /\.css$/,
use: [
defaultLoaders.babel,
{
loader: styledJsxWebpack.loader,
options: {
type: 'scoped'
}
}
]
});
// config.entry = './src/index.js';
// config.output = {
// path: __dirname + '/dist',
// publicPath: '/',
// filename: 'bundle.js'
// };
// config.devServer = {
// contentBase: './dist'
// };
// config.module.rules.push({
// test: /\.js$/,
// exclude: /node_modules/,
// use: {
// loader: 'babel-loader'
// }
// });
readdirSync(paths.components)
.map(dir => [ path.resolve(paths.components, dir), dir ])
.filter(([ dirpath ]) => lstatSync(dirpath).isDirectory())
.forEach(([ dirpath, dirname ]) => config.resolve.alias[dirname] = dirpath);
// ? These are aliases that can be used during JS import calls
// ! Note that you must also change these same aliases in .flowconfig
// ! Note that you must also change these same aliases in package.json (jest)
config.resolve.alias = Object.assign({}, config.resolve.alias, {
universe$: paths.universe,
components$: paths.components,
universe: paths.universe,
components: paths.components
});
return config;
},
......@@ -59,5 +74,5 @@ module.exports = (phase: string, { defaultConfig }: Object) => { // eslint-disab
publicRuntimeConfig: {
// ...
}
}
});
};
# If non-empty, webpack-bundle-analyzer will be injected
ANALYZE_WEBPACK_BUNDLES=
# If !none, webpack's bundle(s) will be analyzed and report files generated
#BUNDLE_ANALYZE=server
#BUNDLE_ANALYZE=client
#BUNDLE_ANALYZE=both
BUNDLE_ANALYZE=none
# Shopify store api configuration variables are stored here
This diff is collapsed.
module.exports = require('babel-jest').createTransformer(require('./babel.config'));
This diff is collapsed.
......@@ -8,72 +8,107 @@
"version": "0.0.1",
"scripts": {
"init": "npx gulp eject",
"dev": "npx next",
"build": "npx next build",
"start": "npx next start",
"test": "npx jest",
"install-types": "npx flow-typed install",
"clean-types": "npx gulp cleanTypes",
"regenerate": "npx gulp regenerate",
"generate": "BABEL_ENV=generator npx babel config --out-dir .",
"debug-remote": "node --inspect-brk='0.0.0.0:7777'",
"debug-remote-gulp": "node --inspect-brk='0.0.0.0:7777' ./node_modules/.bin/gulp",
"debug-remote-jest": "node --inspect-brk='0.0.0.0:7777' ./node_modules/.bin/jest --runInBand",
"debug-remote-next": "next --inspect-brk='0.0.0.0:7777'",
"dev": "next",
"build": "next build",
"start": "next start"
"test-ib": "npx jest --runInBand",
"test-nc": "npx jest --no-cache",
"clean-types": "npx gulp cleanTypes",
"generate": "BABEL_ENV=generator npx babel config --out-dir .",
"regenerate": "npx gulp regenerate",
"bump-major": "npx bump --major --tag --commit --lock --all",
"bump-minor": "npx bump --minor --tag --commit --lock --all",
"bump-patch": "npx bump --patch --tag --commit --lock --all",
"list-tasks": "npm run && echo 'Compiling gulp task list...' && npx gulp --tasks",
"preversion": "npm run test-ib",
"version": "git add --all"
},
"author": "Xunnamius",
"license": "ISC",
"jest": {
"testEnvironment": "node"
"testEnvironment": "jsdom",
"verbose": true,
"transform": {
"^.+\\.js$": "<rootDir>/jest.preprocess.js"
},
"moduleNameMapper": {
"^universe$": "<rootDir>/src",
"^universe/(.*)$": "<rootDir>/src/$1",
"^components/(.*)$": "<rootDir>/src/components/$1"
},
"testPathIgnorePatterns": [
"/node_modules/"
]
},
"dependencies": {
"@babel/core": "^7.1.0",
"@babel/plugin-proposal-class-properties": "^7.1.0",
"@babel/plugin-proposal-export-default-from": "^7.0.0",
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.0.0",
"@babel/plugin-proposal-numeric-separator": "^7.0.0",
"@babel/plugin-proposal-optional-chaining": "^7.0.0",
"@babel/plugin-proposal-throw-expressions": "^7.0.0",
"@babel/preset-env": "^7.1.0",
"@babel/core": "^7.2.2",
"@babel/plugin-proposal-class-properties": "^7.2.3",
"@babel/plugin-proposal-decorators": "^7.2.3",
"@babel/plugin-proposal-export-default-from": "^7.2.0",
"@babel/plugin-proposal-json-strings": "^7.2.0",
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.2.0",
"@babel/plugin-proposal-numeric-separator": "^7.2.0",
"@babel/plugin-proposal-optional-chaining": "^7.2.0",
"@babel/plugin-proposal-throw-expressions": "^7.2.0",
"@babel/preset-env": "^7.2.3",
"@babel/preset-flow": "^7.0.0",
"@babel/preset-react": "^7.0.0",
"ajv": "^6.5.3",
"autobind-decorator": "^2.4.0",
"babel-core": "^7.0.0-bridge.0",
"bulma": "^0.7.1",
"dotenv": "^6.0.0",
"immutable": "^3.8.2",
"next": "^7.0.0-canary.14",
"react": "^16.5.1",
"react-dom": "^16.5.1"
"bulma": "^0.7.2",
"dotenv": "^6.2.0",
"immutable": "^4.0.0-rc.12",
"next": "^7.0.2",
"react": "^16.7.0",
"react-dom": "^16.7.0",
"redux": "^4.0.1",
"styled-jsx": "^3.1.3",
"webpack-bundle-analyzer": "^3.0.3"
},
"devDependencies": {
"@babel/cli": "^7.1.0",
"babel-eslint": "^9.0.0",
"@babel/cli": "^7.2.3",
"@zeit/next-bundle-analyzer": "^0.1.2",
"babel-eslint": "^10.0.1",
"babel-jest": "^23.6.0",
"babel-loader": "^8.0.2",
"babel-loader": "^8.0.4",
"babel-plugin-source-map-support": "^2.0.1",
"chalk": "^2.4.1",
"clean-webpack-plugin": "^1.0.0",
"copy-webpack-plugin": "^4.6.0",
"css-loader": "^2.1.0",
"del": "^3.0.0",
"eslint": "^5.6.0",
"eslint-plugin-flowtype": "^2.50.0",
"eslint-plugin-react": "^7.11.1",
"fancy-log": "^1.3.2",
"flow-bin": "^0.81.0",
"eslint": "^5.11.1",
"eslint-plugin-flowtype": "^3.2.0",
"eslint-plugin-react": "^7.12.0",
"fancy-log": "^1.3.3",
"file-loader": "^3.0.1",
"flow-bin": "^0.89.0",
"flow-typed": "^2.5.1",
"gulp": "^4.0.0",
"gulp-tap": "^1.0.1",
"inquirer": "^6.2.0",
"gulp-zip": "^4.2.0",
"html-loader": "^0.5.5",
"html-webpack-plugin": "^3.2.0",
"inquirer": "^6.2.1",
"jest": "^23.6.0",
"jsdoc": "^3.5.5",
"jsdoc-babel": "^0.5.0",
"parse-gitignore": "^1.0.1",
"replace-in-file": "^3.4.2",
"shelljs": "^0.8.2",
"shelljs": "^0.8.3",
"source-map": "^0.7.3",
"source-map-support": "^0.5.9",
"stylelint": "^9.5.0",
"stream-array": "^1.1.2",
"style-loader": "^0.23.1",
"stylelint": "^9.9.0",
"stylelint-config-standard": "^18.2.0",
"webpack-bundle-analyzer": "^3.0.2"
},
"os": [
"!win32"
]
"version-bump-prompt": "^4.2.2",
"vinyl-fs": "^3.0.3",
"write-file-webpack-plugin": "^4.5.0"
}
}
......@@ -2,7 +2,7 @@
import * as React from 'react'
import Link from 'next/link'
import Header from '../components/view/header'
import Header from 'components/view/header'
export default class About extends React.PureComponent<{||}> {
render() {
......
......@@ -2,7 +2,7 @@
import * as React from 'react'
import Link from 'next/link'
import Header from '../components/view/header'
import Header from 'components/view/header'
export default class Index extends React.PureComponent<{||}> {
render() {
......
/* @flow */
import * as React from "react";
import {render} from "react-dom";
import * as React from 'react';
import {render} from 'react-dom';
class App extends React.PureComponent<{||}> {
render() {
return (
<div>
<h1>Hello Parcel</h1>
<h1>Hello, Webpack!</h1>
</div>
);
}
}
let root: ?Element = document.getElementById("app");
let root: ?Element = document.getElementById('app');
if(!root)
throw 'root (Element) cannot be null';
......
......@@ -2,6 +2,7 @@
import * as React from 'react'
import Link from 'next/link'
import style from './style.css'
export default class Header extends React.PureComponent<{||}> {
render() {
......@@ -11,28 +12,10 @@ export default class Header extends React.PureComponent<{||}> {
<Link href="/"><a>Home</a></Link>
<Link href="/about"><a>About</a></Link>
</header>
<style jsx>{`
header {
width: 100%;
height: 50px;
padding-top: 25px;
background-color: rgb(115, 115, 225);
text-align: center;
text-transform: uppercase;
}
header a {
color: white;
font-weight: bold;
padding: 20px;
text-decoration: none;
}
header a:hover {
opacity: 0.75;
}
`}</style>
<style jsx>{style}</style>
</div>
);
}
}
export { Header };
header {
width: 100%;
height: 50px;
padding-top: 25px;
background-color: rgb(115, 115, 225);
text-align: center;
text-transform: uppercase;
}
header a {
color: white;
font-weight: bold;
padding: 20px;
text-decoration: none;
}
header a:hover {
opacity: 0.75;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment