diff --git a/packages/playgrodd-bundler-webpack/package.json b/packages/playgrodd-bundler-webpack/package.json new file mode 100644 index 000000000..0edb4d576 --- /dev/null +++ b/packages/playgrodd-bundler-webpack/package.json @@ -0,0 +1,41 @@ +{ + "name": "playgrodd-bundler-webpack", + "version": "0.0.1", + "main": "./dist/index.js", + "typings": "./dist/index.d.ts", + "source": "src/index.ts", + "license": "MIT", + "scripts": { + "clean": "trash dist", + "compile": "tsc -p tsconfig.json", + "dev": "run-s clean && run-s \"compile -w\"", + "build": "run-s clean && run-s compile", + "fix": "run-s fix:*", + "fix:prettier": "prettier \"src/**/*.{ts,tsx}\" --write", + "fix:tslint": "tslint --fix --project ." + }, + "dependencies": { + "@babel/core": "^7.0.0-beta.44", + "@babel/runtime": "^7.0.0-beta.44", + "babel-polyfill": "^7.0.0-beta.3", + "babel-loader": "^8.0.0-beta.1", + "babel-preset-react-app": "^4.0.0-next.b2fd8db8", + "deepmerge": "^2.1.0", + "html-webpack-plugin": "^3.2.0", + "load-cfg": "^0.0.1", + "playgrodd-core": "^0.0.1", + "react-dev-utils": "^5.0.1", + "react-hot-loader": "^4.0.1", + "thread-loader": "^1.1.5", + "webpack": "^4.5.0", + "webpack-dev-middleware": "^3.1.2", + "webpack-dev-server": "^3.1.3" + }, + "devDependencies": { + "@types/deepmerge": "^2.1.0", + "@types/html-webpack-plugin": "^2.30.3", + "@types/node": "9.6.4", + "@types/webpack": "^4.1.3", + "@types/webpack-dev-server": "^2.9.4" + } +} diff --git a/packages/playgrodd-core/src/bundlers/webpack/config-devserver.ts b/packages/playgrodd-bundler-webpack/src/config-devserver.ts similarity index 84% rename from packages/playgrodd-core/src/bundlers/webpack/config-devserver.ts rename to packages/playgrodd-bundler-webpack/src/config-devserver.ts index 839de37d2..15c5d2162 100644 --- a/packages/playgrodd-core/src/bundlers/webpack/config-devserver.ts +++ b/packages/playgrodd-bundler-webpack/src/config-devserver.ts @@ -1,12 +1,14 @@ import { Application } from 'express' import * as errorOverlayMiddleware from 'react-dev-utils/errorOverlayMiddleware' -import * as paths from '../../config/paths' - export const PROTOCOL = process.env.HTTPS === 'true' ? 'https' : 'http' export const HOST = process.env.HOST || '0.0.0.0' -export const devServerConfig = () => ({ +export interface IDevServerConfigParams { + paths: any +} + +export const devServerConfig = ({ paths }: IDevServerConfigParams) => ({ compress: true, clientLogLevel: 'none', contentBase: paths.PLAYGRODD, diff --git a/packages/playgrodd-core/src/bundlers/webpack/config-dev.ts b/packages/playgrodd-bundler-webpack/src/config.dev.ts similarity index 62% rename from packages/playgrodd-core/src/bundlers/webpack/config-dev.ts rename to packages/playgrodd-bundler-webpack/src/config.dev.ts index 3f1822b79..eff8d037c 100644 --- a/packages/playgrodd-core/src/bundlers/webpack/config-dev.ts +++ b/packages/playgrodd-bundler-webpack/src/config.dev.ts @@ -1,38 +1,19 @@ import * as path from 'path' -import { Loader, Configuration } from 'webpack' +import { Configuration } from 'webpack' import * as webpack from 'webpack' import * as HtmlWebpackPlugin from 'html-webpack-plugin' import * as webpackDevServerUtils from 'react-dev-utils/WebpackDevServerUtils' import * as WebpackDevServer from 'webpack-dev-server' -import * as merge from 'deepmerge' -import { load } from 'load-cfg' - -import * as paths from '../../config/paths' -import { Entry } from '../../Entry' +import { IBundlerFactoryParams as Args, Entry } from 'playgrodd-core' import { devServerConfig } from './config-devserver' +import * as loaders from './loaders' const HOST = process.env.HOST || '0.0.0.0' -const babelLoader = (): Loader => { - const babelrc = load('babel', null) - const options = merge(babelrc, { - babelrc: false, - cacheDirectory: true, - presets: [ - require.resolve('@babel/preset-env'), - require.resolve('@babel/preset-react'), - ], - plugins: [require.resolve('react-hot-loader/babel')], - }) - - return { - options, - loader: require.resolve('babel-loader'), - } -} - -export const config = (entries: Entry[]): Configuration => ({ +export const config = ({ paths }: Args) => ( + entries: Entry[] +): Configuration => ({ mode: 'development', context: paths.ROOT, devtool: '#source-map', @@ -54,15 +35,19 @@ export const config = (entries: Entry[]): Configuration => ({ module: { rules: [ { - test: /\.(js|jsx)$/, - exclude: /node_modules/, - include: [paths.ROOT], - use: babelLoader(), + oneOf: [ + { + test: /\.(js|jsx|mjs)$/, + exclude: /node_modules/, + include: [paths.ROOT], + use: [require.resolve('thread-loader'), loaders.babel], + }, + ], }, ], }, resolve: { - extensions: ['.js', '.jsx', '.ts', '.tsx', '.json'], + extensions: ['.web.js', '.mjs', '.js', '.json', '.web.jsx', '.jsx'], modules: [paths.ROOT, 'node_modules'], alias: { '@babel/runtime': path.dirname( @@ -84,7 +69,7 @@ export const config = (entries: Entry[]): Configuration => ({ ], }) -export const setup = (port: number) => (config: Configuration) => { +export const setup = ({ paths, port }: Args) => (config: Configuration) => { const appName = require(paths.PACKAGE_JSON).name const protocol = process.env.HTTPS === 'true' ? 'https' : 'http' const urls = webpackDevServerUtils.prepareUrls(protocol, HOST, port) @@ -98,5 +83,5 @@ export const setup = (port: number) => (config: Configuration) => { ) } -export const server = (compiler: any): WebpackDevServer => - new WebpackDevServer(compiler, devServerConfig()) +export const server = (args: Args) => (compiler: any): WebpackDevServer => + new WebpackDevServer(compiler, devServerConfig(args)) diff --git a/packages/playgrodd-bundler-webpack/src/index.ts b/packages/playgrodd-bundler-webpack/src/index.ts new file mode 100644 index 000000000..9f14a2b34 --- /dev/null +++ b/packages/playgrodd-bundler-webpack/src/index.ts @@ -0,0 +1,13 @@ +import { Bundler, IBundlerFactoryParams } from 'playgrodd-core' +import { Configuration } from 'webpack' +import * as WebpackDevServer from 'webpack-dev-server' + +import { config, setup, server } from './config.dev' + +export const create = (params: IBundlerFactoryParams) => + new Bundler({ + id: 'webpack', + config: config(params), + server: server(params), + setup: setup(params), + }) diff --git a/packages/playgrodd-bundler-webpack/src/loaders.ts b/packages/playgrodd-bundler-webpack/src/loaders.ts new file mode 100644 index 000000000..a48bf8a48 --- /dev/null +++ b/packages/playgrodd-bundler-webpack/src/loaders.ts @@ -0,0 +1,15 @@ +import { Loader } from 'webpack' + +import * as merge from 'deepmerge' +import { load } from 'load-cfg' + +export const babel: Loader = { + loader: require.resolve('babel-loader'), + options: merge(load('babel', null), { + babelrc: false, + cacheDirectory: true, + highlightCode: true, + presets: [require.resolve('babel-preset-react-app')], + plugins: [require.resolve('react-hot-loader/babel')], + }), +} diff --git a/packages/playgrodd-bundler-webpack/src/types.d.ts b/packages/playgrodd-bundler-webpack/src/types.d.ts new file mode 100644 index 000000000..940e35d3a --- /dev/null +++ b/packages/playgrodd-bundler-webpack/src/types.d.ts @@ -0,0 +1,2 @@ +declare module 'react-dev-utils/errorOverlayMiddleware' +declare module 'react-dev-utils/WebpackDevServerUtils' diff --git a/packages/playgrodd-bundler-webpack/tsconfig.json b/packages/playgrodd-bundler-webpack/tsconfig.json new file mode 100644 index 000000000..f80816349 --- /dev/null +++ b/packages/playgrodd-bundler-webpack/tsconfig.json @@ -0,0 +1,14 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "target": "es5", + "module": "commonjs", + "declaration": true, + "outDir": "dist", + "rootDir": "src", + "types": ["node"], + "typeRoots": ["node_modules/@types", "src/types"] + }, + "include": ["src/**/*"], + "exclude": ["node_modules/**"] +} diff --git a/packages/playgrodd-bundler-webpack/tslint.json b/packages/playgrodd-bundler-webpack/tslint.json new file mode 100644 index 000000000..0946f2096 --- /dev/null +++ b/packages/playgrodd-bundler-webpack/tslint.json @@ -0,0 +1,3 @@ +{ + "extends": "../../tslint.json" +} diff --git a/packages/playgrodd-core/package.json b/packages/playgrodd-core/package.json index 872e0bf63..2ca2cef4d 100644 --- a/packages/playgrodd-core/package.json +++ b/packages/playgrodd-core/package.json @@ -1,53 +1,37 @@ { "name": "playgrodd-core", "version": "0.0.1", - "main": "./dist/main/index.js", - "typings": "./dist/main/index.d.ts", - "module": "./dist/module/index.js", + "main": "dist/index.js", + "umd:main": "dist/index.umd.js", + "module": "dist/index.m.js", + "source": "src/index.ts", + "typings": "./dist/index.d.ts", "scripts": { "copy-templates": "node scripts/copy-templates", - "clean": "trash dist && yarn copy-templates", - "dev": "run-s clean build:main && run-p \"build:main -- -w\"", - "build": "run-s clean && run-p build:*", - "build:main": "tsc -p tsconfig.json", - "build:module": "tsc -p tsconfig.module.json", + "clean": "trash dist", + "postclean": "run-s copy-templates", + "compile": "tsc -p tsconfig.json", + "dev": "run-s clean && run-s \"compile -w\"", + "build": "run-s clean && run-s compile", "fix": "run-s fix:*", "fix:prettier": "prettier \"src/**/*.{ts,tsx}\" --write", "fix:tslint": "tslint --fix --project ." }, "dependencies": { - "@babel/core": "^7.0.0-beta.44", - "@babel/runtime": "^7.0.0-beta.44", "art-template": "^4.12.2", - "babel-loader": "^8.0.0-beta.1", - "babel-polyfill": "^7.0.0-beta.3", "babel-traverse": "^6.26.0", "babel-types": "^6.26.0", "babylon": "^6.18.0", - "deepmerge": "^2.1.0", - "del": "^3.0.0", "express": "^4.16.3", "fast-glob": "^2.2.0", - "html-webpack-plugin": "^3.2.0", - "load-cfg": "^0.0.1", - "mkdirp": "^0.5.1", - "react-dev-utils": "^5.0.1", - "react-hot-loader": "^4.0.1", - "webpack": "^4.5.0", - "webpack-dev-middleware": "^3.1.2", - "webpack-dev-server": "^3.1.3", - "webpack-messages": "^1.0.1" + "mkdirp": "^0.5.1" }, "devDependencies": { "@types/babel-traverse": "^6.25.3", "@types/babylon": "^6.16.2", - "@types/deepmerge": "^2.1.0", "@types/del": "^3.0.1", "@types/express": "^4.11.1", "@types/mkdirp": "^0.5.2", - "@types/webpack": "^4.1.3", - "@types/webpack-dev-server": "^2.9.4", - "@types/html-webpack-plugin": "^2.30.3", "shelljs": "^0.8.1" } } diff --git a/packages/playgrodd-core/src/Bundler.ts b/packages/playgrodd-core/src/Bundler.ts index c0231016b..3b611f1e1 100644 --- a/packages/playgrodd-core/src/Bundler.ts +++ b/packages/playgrodd-core/src/Bundler.ts @@ -22,11 +22,11 @@ const touch = (file: string, content: string) => { const compiled = (templateFile: string) => compile(fs.readFileSync(`${paths.TEMPLATES_PATH}/${templateFile}`, 'utf-8')) -type TConfigFn = (entries: Entry[]) => C -type TSetupFn = (config: C) => Promise -type TServerFn = (compiler: any) => S +export type TConfigFn = (entries: Entry[]) => C +export type TSetupFn = (config: C) => Promise +export type TServerFn = (compiler: any) => S -interface IConstructorParams { +export interface IConstructorParams { id: string config: TConfigFn setup: TSetupFn @@ -50,11 +50,11 @@ export class Bundler { this.server = server } - public async createCompiler(entries: Entry[]) { + public async createCompiler(theme: string, entries: Entry[]) { const config = this.config(entries) await del(paths.PLAYGRODD) - touch(paths.APP_JS, app({ entries })) + touch(paths.APP_JS, app({ theme, entries })) touch(paths.INDEX_JS, js({})) touch(paths.INDEX_HTML, html({})) @@ -65,3 +65,12 @@ export class Bundler { return await this.server(compiler) } } + +export interface IBundlerFactoryParams { + port: number + paths: paths.Paths +} + +export interface BundlerFactory { + create: (args: IBundlerFactoryParams) => Bundler +} diff --git a/packages/playgrodd-core/src/bundlers/index.ts b/packages/playgrodd-core/src/bundlers/index.ts deleted file mode 100644 index 9c8a2bd60..000000000 --- a/packages/playgrodd-core/src/bundlers/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { bundler as webpack } from './webpack' diff --git a/packages/playgrodd-core/src/bundlers/webpack/index.ts b/packages/playgrodd-core/src/bundlers/webpack/index.ts deleted file mode 100644 index 27ee74170..000000000 --- a/packages/playgrodd-core/src/bundlers/webpack/index.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { Configuration } from 'webpack' -import * as WebpackDevServer from 'webpack-dev-server' - -import { Bundler } from '../../Bundler' -import { config, setup, server } from './config-dev' - -interface IBundlerParams { - port: number -} - -export const bundler = ({ port }: IBundlerParams): Bundler => - new Bundler({ - id: 'webpack', - config, - server, - setup: setup(port), - }) diff --git a/packages/playgrodd-core/src/config/paths.ts b/packages/playgrodd-core/src/config/paths.ts index 8fdc2645b..c9ecfe69c 100644 --- a/packages/playgrodd-core/src/config/paths.ts +++ b/packages/playgrodd-core/src/config/paths.ts @@ -1,6 +1,19 @@ import * as fs from 'fs' import * as path from 'path' +export type Paths = { + ROOT: string + PLAYGRODD: string + PACKAGE_JSON: string + + APP_JS: string + INDEX_JS: string + INDEX_HTML: string + DIST: string + + TEMPLATES_PATH: string +} + export const ROOT = fs.realpathSync(process.cwd()) export const PLAYGRODD = path.join(ROOT, '.playgrodd') export const PACKAGE_JSON = path.join(ROOT, 'package.json') diff --git a/packages/playgrodd-core/src/index.ts b/packages/playgrodd-core/src/index.ts index 84927709c..e38e19dc8 100644 --- a/packages/playgrodd-core/src/index.ts +++ b/packages/playgrodd-core/src/index.ts @@ -1 +1,5 @@ +export { Paths } from './config/Paths' + export { Server } from './server' +export { Entry } from './Entry' +export { Bundler, IBundlerFactoryParams } from './Bundler' diff --git a/packages/playgrodd-core/src/server.ts b/packages/playgrodd-core/src/server.ts index b8932cc05..764831696 100644 --- a/packages/playgrodd-core/src/server.ts +++ b/packages/playgrodd-core/src/server.ts @@ -1,27 +1,46 @@ -import * as bundlers from './bundlers' +import * as paths from './config/paths' import { Entries } from './Entries' -import { prop } from './utils/helpers' +import { Bundler, BundlerFactory } from './Bundler' -interface IConstructorParams { +process.env.BABEL_ENV = process.env.BABEL_ENV || 'development' +process.env.NODE_ENV = process.env.NODE_ENV || 'development' + +export interface IConstructorParams { port: number + theme: string files: string - bundler: 'webpack' + bundler: string } export class Server { - private bundler: any - private entries: Entries private port: number + private theme: string + private bundler: Bundler + private entries: Entries - constructor({ port, bundler, files: pattern }: IConstructorParams) { + constructor({ port, bundler, files: pattern, theme }: IConstructorParams) { this.port = port + this.theme = theme this.entries = new Entries(pattern) - this.bundler = prop(bundler, bundlers)({ port }) + this.bundler = this.getBundler(bundler).create({ port, paths }) + } + + private getBundler(bundler: string): BundlerFactory { + try { + return require(`playgrodd-bundler-${bundler}`) + } catch (err) { + return require('playgrodd-bundler-webpack') + } + } + + private getTheme() { + return `playgrodd-theme-${this.theme}` } public async start() { + const theme = this.getTheme() const entries = this.entries.parse() - const compiler = await this.bundler.createCompiler(entries) + const compiler = await this.bundler.createCompiler(theme, entries) const server = await this.bundler.createServer(compiler) server.listen(this.port) diff --git a/packages/playgrodd-core/src/types.d.ts b/packages/playgrodd-core/src/types.d.ts index 0c7a67a77..3559de213 100644 --- a/packages/playgrodd-core/src/types.d.ts +++ b/packages/playgrodd-core/src/types.d.ts @@ -1,3 +1 @@ declare module 'art-template' -declare module 'react-dev-utils/errorOverlayMiddleware' -declare module 'react-dev-utils/WebpackDevServerUtils' diff --git a/packages/playgrodd-core/templates/app.tpl.js b/packages/playgrodd-core/templates/app.tpl.js index c8ab35869..30cdab576 100644 --- a/packages/playgrodd-core/templates/app.tpl.js +++ b/packages/playgrodd-core/templates/app.tpl.js @@ -2,6 +2,6 @@ <% }); %> import React from 'react' import { hot } from 'react-hot-loader' -import { Theme } from 'playgrodd-theme-default' +import { Theme } from '<%- theme %>' export const App = hot(module)(Theme) diff --git a/packages/playgrodd-core/tsconfig.json b/packages/playgrodd-core/tsconfig.json index 65c840db6..757c89cf9 100644 --- a/packages/playgrodd-core/tsconfig.json +++ b/packages/playgrodd-core/tsconfig.json @@ -3,8 +3,8 @@ "compilerOptions": { "target": "es5", "module": "commonjs", - - "outDir": "dist/main", + "declaration": true, + "outDir": "dist", "rootDir": "src", "types": ["node"], "typeRoots": ["node_modules/@types", "src/types"]