fliphub-monorepo
Version:
the builder of builders
729 lines (586 loc) • 19.8 kB
Markdown
[travis-image]: https://travis-ci.org/fliphub/fliphub.svg?branch=master
[travis-url]: https://travis-ci.org/fliphub/fliphub
[flipfam-image]: https://img.shields.io/badge/%F0%9F%8F%97%20%F0%9F%92%A0-flipfam-9659F7.svg
[flipfam-url]: https://www.npmjs.com/package/flipfam
[nsp-url]:https://nodesecurity.io/orgs/fliphub/projects/d37f0cc6-02ea-4f05-a8aa-3b6c1e08bd21
[nsp-image]: https://nodesecurity.io/orgs/fliphub/projects/d37f0cc6-02ea-4f05-a8aa-3b6c1e08bd21/badge
# 🏗💠 fliphub
[![Build Status][travis-image]](travis-url)
[![NPM version][npm-image]][npm-url]
[![fliphub][gitter-badge]][gitter-url]
[![Slack][slack-image]][slack-url]
[![flipfam][flipfam-image]][flipfam-url]
[![Dependencies][david-deps-img]][david-deps-url]
[![MIT License][license-image]][license-url]
[![Standard JS Style][standard-image]][standard-url]
[![NSP Status][nsp-image]][nsp-url]

[](http://makeapullrequest.com)
> the builder, of builders.
## all you need
enables configs that would take hundreds or thousands of lines, with just a few properties.
#### minimal
[see the example](example-minimal)
```js
import FlipHub from 'fliphub'
new FlipHub({entry: './src/index.js'}).build()
```
## usage
```bash
yarn add fliphub
npm i fliphub --save
```
```js
const log = require('fliphub')
```
#### all the apps
one app? two apps? 100 apps? fusebox, rollup, _and_ webpack? nodejs server, inferno, and react? existing configs? happy and no happy pack? at the same time? no sweat.
```js
const FlipHub = require('fliphub')
const apps = [
{
name: 'reacted',
config: './webpack.config.js'
flips: {to: 'fusebox'},
},
{
name: 'infernod',
entry: './src/index.js',
presets: ['inferno'],
html: './src/index.html',
happypack: true,
},
{
name: 'backend',
entry: './backend/src',
presets: ['node'],
},
]
FlipHub.init({apps}).build()
```
#### reusability?
```js
const { FlipHub } = require('fliphub')
const apps = [
{
name: 'reacted',
presets: ['react'],
},
{
name: 'infernod',
presets: ['inferno'],
},
]
FlipHub.init({
apps,
presets: {
front: {
entry: './src/index.js',
html: '#root',
fusebox: true,
},
},
}).build()
```
[they are configured for each environment by default](#-default settings)
[and can be customized for any config you want](#-flags)
[it can build itself with webpack, fusebox, or rollup, with the flip of an env flag][src-pkg-json]
## the problem
- [build systems are notorious for their difficulty][medium-webpack-difficulty].
- finding and setting up the right
- scripts
- plugins
- loaders
- configs
- requiring the dependencies
- bloating your config files
- making configs for
- development bundling
- production bundling
- production dev bundling
- test environments
- development servers
- production servers
- tedious, with a high barrier of entry
- time intensive; switching build systems for 1 app is grueling
- ... all of the above for _every application_
## the solution
- [with the flip of a flag](#flags), you can go from [webpack][webpack], to [fusebox][fusebox], or any other supported build system.
- [existing webpack configs](#compat) can be used and enhanced with ease.
- [create plugins](#create-your-own-plugins) to start converting your build system to another, flip the switch to keep compatibility without breaking everything,
# 🗝️ legend
- [middleware](#-middleware)
- [apps](#-apps)
- [commander](#-commander)
- [examples](#-examples)
- [terminology](#-terminology)
- [🏭 behind the scenes / internal](#-behind-the-scenes)
# 📘 examples
- [examples-minimal][examples-minimal]
- [examples-canadas][examples-canadas]
- [examples-monorepo][examples-monorepo]
- [examples-react][examples-react]
- [examples-react-and-alias][examples-react-and-alias]
- [examples-typescript][examples-typescript]
- [examples-node][examples-node]
- [examples-lint][examples-lint]
- [examples-compat][examples-compat] 🚧
- [examples-tests][examples-tests] 🚧
- [examples-webworker][examples-webworker] 🚧
- [examples-code-splitting][examples-code-splitting] 🚧
- [examples-es6-ts-config][examples-es6-ts-config] 🚧
[example-minimal]: example-minimal
[examples-compat]: https://github.com/fliphub/fliphub/tree/master/examples/compat
[examples-react]: https://github.com/fliphub/fliphub/tree/master/examples/react
[examples-react-and-alias]: https://github.com/fliphub/fliphub/tree/master/examples/react-and-alias
[examples-canadas]: https://github.com/fliphub/fliphub/tree/master/examples/canadas
[examples-lint]: https://github.com/fliphub/fliphub/tree/master/examples/lint
[examples-empty]: https://github.com/fliphub/fliphub/tree/master/examples/empty
[examples-monorepo]: https://github.com/fliphub/fliphub/tree/master/examples/monorepo
[examples-typescript]: https://github.com/fliphub/fliphub/tree/master/examples/typescript
[examples-webworker]: https://github.com/fliphub/fliphub/tree/master/examples/webworker
[examples-tests]: https://github.com/fliphub/fliphub/tree/master/examples/tests
[examples-code-splitting]: https://github.com/fliphub/fliphub/tree/master/examples/code-splitting
[examples-es6-ts-config]: https://github.com/fliphub/fliphub/tree/master/examples/es6-ts-config
[examples-node]: https://github.com/fliphub/fliphub/tree/master/examples/node
# 🔌 middleware
------------------
### add your own middleware
- you can add your own middleware before building apps
- the name of the middleware maps in as a hook for the properties on the app
- optional index property to insert middleware at any position
- [middleware interface][flow-middleware]
#### example
```js
fliphub.addMiddlewares({
index: 999, // optional
name: 'propertyOnApp',
inject(app, helpers) {
helpers.log.text('❗ middleware for `.propertyOnApp`!')
return app
},
})
```
## 🐛 debugging
- ⚙ with full options for debugging everything in the flipping process, debugging is a breeze.
- see [debugging - deep](#deep-debugging) for all of the options
## 🏹 aliasing
### problems
- relatively importing files is a major pain `../../../../../utils`
- when refactoring, relative imports requires updating all files affected
- manually resolving paths to root
- bloats the code
- adds knowledge about the structure to files that should not need it, such as presentation layer / ui components
- [multiple versions of any npm packages][shrinkwrap]
- [multiple react refs][react-refs-error] when multiple versions of react are loaded
- dependencies have different versions of the same dependency
- servers such as heroku keep caches where there are multiple versions
### solutions
- using aliases, you can force a single version of a dependency
- write your aliases relatively to your [home](#home)
### 🔗 resources
- [🗼 babel aliases][babel-module-resolver]
- [🕸 webpack aliases][webpack-alias]
- [💣 fusebox aliases][fusebox-alias]
- ✔️💣🕸
## 🍰 presets
### add your own presets
```js
.extendPresets({
'inferno': {
loaders: ['styleloader'],
alias: ['moose', 'igloo', 'inferno'],
html: '#root',
},
})
```
### built in presets
- [built in presets][src-presets]
## 🍦 default settings
- [see the code][src-defaults]
### default defaults
```
{
env: {
production: {
uglify: true,
defineProduction: true,
run: false,
compile: true,
useSourceMaps: false,
sourceMapTool: 'hidden',
},
development: {
noEmitErrors: true,
},
}
}
```
### adding your own defaults
this would make it so if `fusebox` [flag](#flags) are true, it would add the fusebox property to any app that has passed [filters](#filters) and is being built.
```js
fliphub.addDefaults({
flags: {
// this can also be a objects,
// or an array of strings
// or a string
names: [{flag: 'fusebox', type: 'bool', default: false}],
cb: ({fusebox}) => {
return {fusebox}
},
},
})
```
### ⚠
- ✔️💣🕸
- needs docs
- [todo-presets][todo-presets]
## params
- converts shorthand code to webpack configs
- [read the code][src-params]
- ✔️💣🕸
## 💣🛅 fusebox
- converts webpack configs to fusebox configs
- [read the code][src-fusebox-middleware]
- ✔️💣
- [todo-build-systems][todo-build-systems]
- needs to pass in more of the config
## ☺️️🛅 happypack
- [happypack][happypack]
- ✔️🕸
### defaults
```js
happypack: {
cache: false,
threads: 4,
include: [
'./',
],
}
```
```js
{
_noop: true,
clean: false, // bool, or array<string>
}
```
## 🗺 sourcemaps
- ✔️💣🕸
### defaults
```js
env: {
development: {
useSourceMaps: true,
sourceMapTool: '#source-map',
}
production: {
useSourceMaps: true,
sourceMapTool: 'hidden',
},
}
```
## ⚖️ loaders
- ✔️💣🕸
- .loaderOptions
### defaults
```js
loaders: {
'babel': {},
'json': {},
},
```
## 🚩 flags
flags can be used to find global variables passed around for configuration
from [globals][node-global]
### defaults
```js
flags: {
names: [
{flag: 'compile'},
{flag: 'exec'},
{flag: 'run'},
{flag: 'test'},
],
cb: ({compile, exec, run, test}) => {
var decorated = {compile, exec, run, test}
if (test) {
if (decorated.presets) {
decorated.presets.push('test')
decorated.presets.push('mocha')
}
else decorated.presets = ['test', 'mocha']
}
// helpers.log.verbose(decorated)
return decorated
},
}
```
### examples
```js
flags: [
{
names: ['html'],
cb({html}) {
if (!html) return {}
var template = `./back/verbose/${html}.html`
return {html: [{template}]}
},
},
{
names: [{flag: 'run', type: 'bool', default: false}],
cb({run}) {
return {run}
},
},
],
```
### resources
- [yargs][yargs]
- [node-flag][node-flag]
- ✔️💣🕸
### ⚠
- needs ungreedy search
- [todo-flags][todo-flags]
## ♼ environment
is an extension of [flags](#flags) as a middleware using flags
### defaults
```js
env: {
production: {
uglify: true,
defineProduction: true,
run: false,
compile: true,
sourceMaps: false,
sourceMapTool: 'hidden',
},
development: {
noEmitErrors: true,
},
}
```
## ☕🏳️ filters
white [flags](#flags) are used to filter which apps are run for different [operations](#app-operations)
apps, and app operations can be filtered based on flags either per app, or for all apps.
[see the examples](#examples)
## configOut
- writes the generated config to a file, for use with [babel-module-resolver][babel-module-resolver]
- ✔️💣🕸
## polyfills
- can be used currently only for polyfilling window when you `.exec` in [app operations](#app-operations)
### ⚠
- ✔️🕸
- needs docs
- [todo-polyfill][todo-polyfill]
## externals
- allows you to exclude paths from a bundle
- ✔️💣🕸
- [webpack externals][webpack-externals]
- [fuse exclude][fuse-arithmetic]
## tests
- run tests in mocha
- run tests in karma
- ^ while running dev servers at the same time
### ⚠
- ✔️💣🕸
- needs docs
- needs links to code
- needs links to karma and mocha
- [todo-tests][todo-tests]
# 👑⚔️ commander
### resources
- [commanderjs][commanderjs]
### ⚠
- needs docs
- needs lots of work
- [todo-commander][todo-commander]
# apps
- multiple apps [flow-app][flow-app]
### app-operations
- 🏃🏸 running
- 🔮🌐 automatic safety in ports
- ⌛ compiling
- 👂 compileEnd
- 💀 executing
- 👻 mediator
- ⛴ releasing scripts
- 📦🏗 package builder
- pipeline
- task running
- 💚📜 scripts created for ci environments
- 🔮📜 scripts for all environments and servers created and added to your packages
- 📦⬇ keep your dependencies at root to [avoid symlinks][com-avoid-symlinks] and [massive package sizes][com-massive-package-sizes]
### ⚠
- needs docs
# 🕳 digging deeper
## 🖇 helpers
## 🐛 deep-debugging
inside of every workflow, there is [fliplog][fliplog-url]
### defaults
```js
debug: {
missingMiddleware: false,
missingLoaders: true,
devServer: true,
middleware: true,
loaders: false,
verbose: false,
built: false,
decorated: true,
time: true,
filter: true,
defaults: false,
happypack: false,
presets: false,
out: true,
order: false,
params: false,
alias: true,
fuse: true,
exec: true,
flags: true,
testOutput: true,
}
```
## 📒 files
[flipfile][flipfile-url]
## 🌐 port
used for finding available ports if preferred ones are not available
## html
## example
```js
{
flags: {
// selector=your-custom-root-react-id
// htmlfile='./src/index.html'
// htmlfiles=['./src/index.html', './src/page2.html']
// template=[{template: './src/index.html'}]
names: [
'selector',
'htmlfile',
'template',
{flag: 'htmlfiles', type: 'array'},
],
cb: ({selector, htmlfile, template, htmlfiles}) => {
if (selector) return {html: `#${selector}`}
if (htmlfile) return {html: htmlfile}
if (htmlfiles) return {html: [htmlfiles]}
if (template) return {html: template}
},
},
}
```
### ⚠
- ✔️🕸
- needs docs
- needs more fusebox support, only supports html file
## 📚🚧 (need docs)
- HMR
- include
- builderInstance
- init
- instructions
- tasks
- copy
- define
- uglify
- analyze
- clean
- provide
## 🏭 behind the scenes
## core
## middleware
- flattening
## builders
## core
## 🖇 helpers
reference & context
## 📅 plans
- [board](https://github.com/fliphub/fliphub/issues#boards?repos=82865013)
# 🏗 build systems / builders
- [webpack][webpack-url]
- [fusebox][fusebox-url]
- [rollup][rollup-url]
- [another bundler? request it][new-issue-url]
[new-issue-url]: https://github.com/fliphub/fliplog/issues/new
[fliplog-url]: https://www.npmjs.com/package/fliplog
[flipfile-url]: https://www.npmjs.com/package/flipfile
[src-pkg-json]: https://github.com/fliphub/fliphub/tree/master/package.json
[src-params]: https://github.com/fliphub/fliphub/tree/master/src/middleware/defaults.js
[src-fusebox-middleware]: https://github.com/fliphub/fliphub/tree/master/src/middleware/builders/fusebox.js
[src-presets]: https://github.com/fliphub/fliphub/tree/master/src/middleware/presets.js
[src-defaults]: https://github.com/fliphub/fliphub/tree/master/src/middleware/defaults.js
[flow-middleware]: https://github.com/fliphub/fliphub/tree/master/flow/MiddlewareInterface
[flow-app]: https://github.com/fliphub/fliphub/tree/master/flow/MiddlewareInterface
[todo-flags]: https://github.com/fliphub/fliphub/tree/master/docs/todos/middleware/flags.md
[todo-aliasing]: https://github.com/fliphub/fliphub/tree/master/docs/todos/middleware/aliasing.md
[todo-compat]: https://github.com/fliphub/fliphub/tree/master/docs/todos/middleware/compat.md
[todo-HMR]: https://github.com/fliphub/fliphub/tree/master/docs/todos/middleware/HMR.md
[todo-loaders]: https://github.com/fliphub/fliphub/tree/master/docs/todos/middleware/loaders.md
[todo-middleware]: https://github.com/fliphub/fliphub/tree/master/docs/todos/middleware/middleware.md
[todo-polyfill]: https://github.com/fliphub/fliphub/tree/master/docs/todos/middleware/polyfill.md
[todo-presets]: https://github.com/fliphub/fliphub/tree/master/docs/todos/middleware/presets.md
[todo-tasks]: https://github.com/fliphub/fliphub/tree/master/docs/todos/middleware/tasks.md
[todo-architecture]: https://github.com/fliphub/fliphub/tree/master/docs/todos/architecture.md
[todo-build-systems]: https://github.com/fliphub/fliphub/tree/master/docs/todos/build-systems.md
[todo-commander]: https://github.com/fliphub/fliphub/tree/master/docs/todos/commander.md
[todo-core]: https://github.com/fliphub/fliphub/tree/master/docs/todos/core.md
[todo-docs]: https://github.com/fliphub/fliphub/tree/master/docs/todos/docs.md
[todo-examples]: https://github.com/fliphub/fliphub/tree/master/docs/todos/examples.md
[todo-helpers]: https://github.com/fliphub/fliphub/tree/master/docs/todos/helpers.md
[todo-later-soon-next]: https://github.com/fliphub/fliphub/tree/master/docs/todos/later-soon-next.md
[todo-perf]: https://github.com/fliphub/fliphub/tree/master/docs/todos/perf.md
[todo-tests]: https://github.com/fliphub/fliphub/tree/master/docs/todos/tests.md
[npm-image]: https://img.shields.io/npm/v/fliphub.svg
[npm-url]: https://npmjs.org/package/fliphub
[david-deps-img]: https://david-dm.org/fliphub/fliphub.svg
[david-deps-url]: https://david-dm.org/fliphub/fliphub
[emoji-commits]: https://github.com/aretecode/emoji-commits/
[chalk]: https://github.com/chalk/chalk
[react-refs-error]: https://facebook.github.io/react/docs/error-decoder.html?invariant=119
[shrinkwrap]: https://docs.npmjs.com/cli/shrinkwrap
[babel-setup]: https://babeljs.io/docs/setup/
[babel-module-resolver]: https://github.com/tleunen/babel-plugin-module-resolver
[babel-loader-builder]: https://github.com/aretecode/babel-loader-builder
[babel-monorepo]: [https://github.com/babel/babel/blob/master/doc/design/monorepo.md]
[babel-make]: [https://github.com/babel/babel/blob/master/Makefile]
[webpack]: https://webpack.js.org/
[webpack-alias]: https://webpack.js.org/configuration/resolve/
[webpack-root]: https://webpack.js.org/guides/migrating/#resolve-root-resolve-fallback-resolve-modulesdirectories
[medium-webpack-difficulty]: https://medium.com/@dtothefp/why-can-t-anyone-write-a-simple-webpack-tutorial-d0b075db35ed#.b57i57t24
[webpack-externals]: https://webpack.js.org/configuration/externals/#components/sidebar/sidebar.jsx
[happypack]: https://github.com/amireh/happypack
[webpack-plugin-uglify]: https://webpack.js.org/guides/migrating/#uglifyjsplugin-minimize-loaders
[fusebox]: http://fuse-box.org/
[fusebox-alias]: http://fuse-box.org/#alias
[fusebox-homedir]: http://fuse-box.org/#home-directory
[fuse-arithmetic]: http://fuse-box.org/#arithmetic-instructions
[sigh]: https://github.com/sighjs/sigh
[fly]: https://github.com/flyjs/fly
[brunch]: http://brunch.io/
[broccili]: [http://broccolijs.com/]
[gearjs]: [http://gearjs.org/]
[yeoman]: [http://yeoman.io/]
[make]: [https://github.com/mklabs/make]
[documentationjs]: [http://documentation.js.org/]
[ninjabuild]: [https://ninja-build.org/manual.html]
[meteor-scripts]: [https://github.com/meteor/meteor/tree/devel/scripts]
[facebook-gulp]: [https://github.com/facebook/react/blob/master/gulpfile.js]
[facebook-scripts]: [https://github.com/facebook/react/tree/master/scripts]
[commanderjs]: https://github.com/tj/commander.js/
[node-global]: https://nodejs.org/api/globals.html
[node-process-env]: https://nodejs.org/api/process.html#process_process_env
[node-util-format]: https://nodejs.org/api/util.html#util_util_format_format
[nodejs-tosource]: https://github.com/marcello3d/node-tosource
[yargs]: https://www.npmjs.com/package/yargs
[node-flag]: https://www.npmjs.com/package/node-flag
[standard-image]: https://img.shields.io/badge/%F0%9F%91%95%20code%20style-standard%2Bes6+-blue.svg
[standard-url]: https://github.com/aretecode/eslint-config-aretecode
[license-image]: http://img.shields.io/badge/license-MIT-blue.svg?style=flat
[license-url]: https://spdx.org/licenses/MIT
[slack-url]: https://now-examples-slackin-mquyzyrecx.now.sh/
[slack-image]: https://now-examples-slackin-mquyzyrecx.now.sh/badge.svg
[com-avoid-symlinks]: @TODO
[com-massive-package-sizes]: @TODO
[gitter-badge]: https://img.shields.io/gitter/room/fliphub/pink.svg
[gitter-url]: https://gitter.im/fliphub/Lobby