diff --git a/src/api/build.ts b/src/api/build.ts index 2330a8e..0dce116 100644 --- a/src/api/build.ts +++ b/src/api/build.ts @@ -5,6 +5,7 @@ import rimraf from 'rimraf'; import { EventEmitter } from 'events'; import minify_html from './utils/minify_html'; import { create_compilers, create_main_manifests, create_routes, create_serviceworker_manifest } from '../core'; +import { Compilers, Compiler } from '../core/create_compilers'; import * as events from './interfaces'; export function build(opts: {}) { @@ -28,6 +29,7 @@ async function execute(emitter: EventEmitter, { dest = 'build', app = 'app', webpack = 'webpack', + rollup = 'rollup', routes = 'routes' } = {}) { mkdirp.sync(dest); @@ -51,9 +53,9 @@ async function execute(emitter: EventEmitter, { // create app/manifest/client.js and app/manifest/server.js create_main_manifests({ routes: route_objects }); - const { client, server, serviceworker } = create_compilers({ webpack }); + const { client, server, serviceworker } = create_compilers({ webpack, rollup }); - const client_stats = await compile(client); + const client_stats = await client.compile(); emitter.emit('build', { type: 'client', // TODO duration/warnings @@ -63,7 +65,7 @@ async function execute(emitter: EventEmitter, { const client_info = client_stats.toJson(); fs.writeFileSync(path.join(dest, 'client_assets.json'), JSON.stringify(client_info.assetsByChunkName)); - const server_stats = await compile(server); + const server_stats = await server.compile(); emitter.emit('build', { type: 'server', // TODO duration/warnings @@ -78,7 +80,7 @@ async function execute(emitter: EventEmitter, { client_files: client_stats.toJson().assets.map((chunk: { name: string }) => `client/${chunk.name}`) }); - serviceworker_stats = await compile(serviceworker); + serviceworker_stats = await serviceworker.compile(); emitter.emit('build', { type: 'serviceworker', @@ -86,24 +88,4 @@ async function execute(emitter: EventEmitter, { webpack_stats: serviceworker_stats }); } -} - -function compile(compiler: any) { - return new Promise((fulfil, reject) => { - compiler.run((err: Error, stats: any) => { - if (err) { - reject(err); - process.exit(1); - } - - if (stats.hasErrors()) { - console.error(stats.toString({ colors: true })); - reject(new Error(`Encountered errors while building app`)); - } - - else { - fulfil(stats); - } - }); - }); -} +} \ No newline at end of file diff --git a/src/api/dev.ts b/src/api/dev.ts index 68711c3..1352744 100644 --- a/src/api/dev.ts +++ b/src/api/dev.ts @@ -9,6 +9,7 @@ import format_messages from 'webpack-format-messages'; import { locations } from '../config'; import { EventEmitter } from 'events'; import { create_routes, create_main_manifests, create_compilers, create_serviceworker_manifest } from '../core'; +import { Compiler, Compilers } from '../core/create_compilers'; import Deferred from './utils/Deferred'; import * as events from './interfaces'; @@ -155,7 +156,10 @@ class Watcher extends EventEmitter { }; // TODO watch the configs themselves? - const compilers = create_compilers({ webpack: this.dirs.webpack }); + const compilers: Compilers = create_compilers({ + webpack: this.dirs.webpack, + rollup: this.dirs.rollup + }); let log = ''; @@ -332,16 +336,14 @@ class Watcher extends EventEmitter { } } - watch(compiler: any, { name, invalid = noop, result }: { + watch(compiler: Compiler, { name, invalid = noop, result }: { name: string, invalid?: (filename: string) => void; result: (stats: any) => void; }) { - compiler.hooks.invalid.tap('sapper', (filename: string) => { - invalid(filename); - }); + compiler.oninvalid(invalid); - compiler.watch({}, (err: Error, stats: any) => { + compiler.watch((err: Error, stats: any) => { if (err) { this.emit('error', { type: name, diff --git a/src/cli/build.ts b/src/cli/build.ts index b7bf87b..53f3002 100644 --- a/src/cli/build.ts +++ b/src/cli/build.ts @@ -9,7 +9,8 @@ export function build() { dest: locations.dest(), app: locations.app(), routes: locations.routes(), - webpack: 'webpack' + webpack: 'webpack', + rollup: 'rollup' }); emitter.on('build', event => { diff --git a/src/core/create_compilers.ts b/src/core/create_compilers.ts index 51a866d..a6794b9 100644 --- a/src/core/create_compilers.ts +++ b/src/core/create_compilers.ts @@ -1,29 +1,98 @@ +import * as fs from 'fs'; import * as path from 'path'; import relative from 'require-relative'; -export default function create_compilers({ webpack }: { webpack: string }) { - const wp = relative('webpack', process.cwd()); +let r: any; +let wp: any; - const serviceworker_config = try_require(path.resolve(`${webpack}/service-worker.config.js`)); +export class WebpackCompiler { + _: any; - return { - client: wp( - require(path.resolve(`${webpack}/client.config.js`)) - ), + constructor(config: any) { + this._ = wp(require(path.resolve(config))); + } - server: wp( - require(path.resolve(`${webpack}/server.config.js`)) - ), + oninvalid(cb: (filename: string) => void) { + this._.hooks.invalid.tap('sapper', cb); + } - serviceworker: serviceworker_config && wp(serviceworker_config) - }; + compile() { + return new Promise((fulfil, reject) => { + this._.run((err: Error, stats: any) => { + if (err) { + reject(err); + process.exit(1); + } + + if (stats.hasErrors()) { + console.error(stats.toString({ colors: true })); + reject(new Error(`Encountered errors while building app`)); + } + + else { + fulfil(stats); + } + }); + }); + } + + watch(cb: (err: Error, stats: any) => void) { + this._.watch({}, cb); + } } -function try_require(specifier: string) { - try { - return require(specifier); - } catch (err) { - if (err.code === 'MODULE_NOT_FOUND') return null; - throw err; +export class RollupCompiler { + constructor(config: any) { + } + + oninvalid(cb: (filename: string) => void) { + + } + + compile() { + return new Promise((fulfil, reject) => { + + }); + } + + watch(cb: (err: Error, stats: any) => void) { + + } +} + +export type Compiler = RollupCompiler | WebpackCompiler; + +export type Compilers = { + client: Compiler; + server: Compiler; + serviceworker?: Compiler; +} + +export default function create_compilers({ webpack, rollup }: { webpack: string, rollup: string }): Compilers { + if (fs.existsSync(rollup)) { + if (!r) r = relative('rollup', process.cwd()); + + const sw = `${rollup}/service-worker.config.js`; + + return { + client: new RollupCompiler(`${rollup}/client.config.js`), + server: new RollupCompiler(`${rollup}/server.config.js`), + serviceworker: fs.existsSync(sw) && new RollupCompiler(sw) + }; + } + + if (fs.existsSync(webpack)) { + if (!wp) wp = relative('webpack', process.cwd()); + + const sw = `${webpack}/service-worker.config.js`; + + return { + client: new WebpackCompiler(`${webpack}/client.config.js`), + server: new WebpackCompiler(`${webpack}/server.config.js`), + serviceworker: fs.existsSync(sw) && new WebpackCompiler(sw) + }; + } + + throw new Error(`Could not find config files for rollup or webpack`); } \ No newline at end of file