mirror of
https://github.com/kevin-DL/sapper.git
synced 2026-01-22 07:05:24 +00:00
create build API
This commit is contained in:
110
src/api/build.ts
Normal file
110
src/api/build.ts
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
import * as fs from 'fs';
|
||||||
|
import * as path from 'path';
|
||||||
|
import mkdirp from 'mkdirp';
|
||||||
|
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 { locations } from '../config';
|
||||||
|
|
||||||
|
export default function build(opts: {}) {
|
||||||
|
const emitter = new EventEmitter();
|
||||||
|
|
||||||
|
execute(emitter, opts).then(
|
||||||
|
() => {
|
||||||
|
emitter.emit('done', {}); // TODO do we need to pass back any info?
|
||||||
|
},
|
||||||
|
error => {
|
||||||
|
emitter.emit('error', {
|
||||||
|
error
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
return emitter;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function execute(emitter: EventEmitter, {
|
||||||
|
dest = 'build',
|
||||||
|
app = 'app',
|
||||||
|
webpack = 'webpack',
|
||||||
|
routes = 'routes'
|
||||||
|
} = {}) {
|
||||||
|
mkdirp.sync(dest);
|
||||||
|
rimraf.sync(path.join(dest, '**/*'));
|
||||||
|
|
||||||
|
// minify app/template.html
|
||||||
|
// TODO compile this to a function? could be quicker than str.replace(...).replace(...).replace(...)
|
||||||
|
const template = fs.readFileSync(`${app}/template.html`, 'utf-8');
|
||||||
|
|
||||||
|
// remove this in a future version
|
||||||
|
if (template.indexOf('%sapper.base%') === -1) {
|
||||||
|
const error = new Error(`As of Sapper v0.10, your template.html file must include %sapper.base% in the <head>`);
|
||||||
|
error.code = `missing-sapper-base`;
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
|
||||||
|
fs.writeFileSync(`${dest}/template.html`, minify_html(template));
|
||||||
|
|
||||||
|
const route_objects = create_routes();
|
||||||
|
|
||||||
|
// 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_stats = await compile(client);
|
||||||
|
emitter.emit('build', {
|
||||||
|
type: 'client',
|
||||||
|
// TODO duration/warnings
|
||||||
|
webpack_stats: client_stats
|
||||||
|
});
|
||||||
|
|
||||||
|
fs.writeFileSync(path.join(dest, 'client_info.json'), JSON.stringify({
|
||||||
|
assets: client_stats.toJson().assetsByChunkName
|
||||||
|
}));
|
||||||
|
|
||||||
|
const server_stats = await compile(server);
|
||||||
|
emitter.emit('build', {
|
||||||
|
type: 'server',
|
||||||
|
// TODO duration/warnings
|
||||||
|
webpack_stats: server_stats
|
||||||
|
});
|
||||||
|
|
||||||
|
let serviceworker_stats;
|
||||||
|
|
||||||
|
if (serviceworker) {
|
||||||
|
create_serviceworker_manifest({
|
||||||
|
routes: route_objects,
|
||||||
|
client_files: client_stats.toJson().assets.map((chunk: { name: string }) => `client/${chunk.name}`)
|
||||||
|
});
|
||||||
|
|
||||||
|
serviceworker_stats = await compile(serviceworker);
|
||||||
|
|
||||||
|
emitter.emit('build', {
|
||||||
|
type: 'serviceworker',
|
||||||
|
// TODO duration/warnings
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
0
src/api/dev.ts
Normal file
0
src/api/dev.ts
Normal file
0
src/api/export.ts
Normal file
0
src/api/export.ts
Normal file
@@ -1,78 +1,34 @@
|
|||||||
import * as fs from 'fs';
|
import _build from '../api/build';
|
||||||
import * as path from 'path';
|
|
||||||
import * as colors from 'ansi-colors';
|
import * as colors from 'ansi-colors';
|
||||||
import mkdirp from 'mkdirp';
|
|
||||||
import rimraf from 'rimraf';
|
|
||||||
import { minify_html } from './utils/minify_html';
|
|
||||||
import { create_compilers, create_main_manifests, create_routes, create_serviceworker_manifest } from '../core'
|
|
||||||
import { locations } from '../config';
|
import { locations } from '../config';
|
||||||
|
|
||||||
export async function build() {
|
export function build() {
|
||||||
const output = locations.dest();
|
|
||||||
|
|
||||||
mkdirp.sync(output);
|
|
||||||
rimraf.sync(path.join(output, '**/*'));
|
|
||||||
|
|
||||||
// minify app/template.html
|
|
||||||
// TODO compile this to a function? could be quicker than str.replace(...).replace(...).replace(...)
|
|
||||||
const template = fs.readFileSync(`${locations.app()}/template.html`, 'utf-8');
|
|
||||||
|
|
||||||
// remove this in a future version
|
|
||||||
if (template.indexOf('%sapper.base%') === -1) {
|
|
||||||
console.log(`${colors.bold.red(`> As of Sapper v0.10, your template.html file must include %sapper.base% in the <head>`)}`);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
fs.writeFileSync(`${output}/template.html`, minify_html(template));
|
|
||||||
|
|
||||||
const routes = create_routes();
|
|
||||||
|
|
||||||
// create app/manifest/client.js and app/manifest/server.js
|
|
||||||
create_main_manifests({ routes });
|
|
||||||
|
|
||||||
const { client, server, serviceworker } = create_compilers();
|
|
||||||
|
|
||||||
const client_stats = await compile(client);
|
|
||||||
console.log(`${colors.inverse(`\nbuilt client`)}`);
|
|
||||||
console.log(client_stats.toString({ colors: true }));
|
|
||||||
fs.writeFileSync(path.join(output, 'client_info.json'), JSON.stringify({
|
|
||||||
assets: client_stats.toJson().assetsByChunkName
|
|
||||||
}));
|
|
||||||
|
|
||||||
const server_stats = await compile(server);
|
|
||||||
console.log(`${colors.inverse(`\nbuilt server`)}`);
|
|
||||||
console.log(server_stats.toString({ colors: true }));
|
|
||||||
|
|
||||||
let serviceworker_stats;
|
|
||||||
|
|
||||||
if (serviceworker) {
|
|
||||||
create_serviceworker_manifest({
|
|
||||||
routes,
|
|
||||||
client_files: client_stats.toJson().assets.map((chunk: { name: string }) => `client/${chunk.name}`)
|
|
||||||
});
|
|
||||||
|
|
||||||
serviceworker_stats = await compile(serviceworker);
|
|
||||||
console.log(`${colors.inverse(`\nbuilt service worker`)}`);
|
|
||||||
console.log(serviceworker_stats.toString({ colors: true }));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function compile(compiler: any) {
|
|
||||||
return new Promise((fulfil, reject) => {
|
return new Promise((fulfil, reject) => {
|
||||||
compiler.run((err: Error, stats: any) => {
|
try {
|
||||||
if (err) {
|
console.log('1');
|
||||||
reject(err);
|
const emitter = _build({
|
||||||
process.exit(1);
|
dest: locations.dest(),
|
||||||
}
|
app: locations.app(),
|
||||||
|
routes: locations.routes(),
|
||||||
|
webpack: 'webpack'
|
||||||
|
});
|
||||||
|
console.log('2', emitter);
|
||||||
|
|
||||||
if (stats.hasErrors()) {
|
emitter.on('build', event => {
|
||||||
console.error(stats.toString({ colors: true }));
|
console.log(colors.inverse(`\nbuilt ${event.type}`));
|
||||||
reject(new Error(`Encountered errors while building app`));
|
console.log(event.webpack_stats.toString({ colors: true }));
|
||||||
}
|
});
|
||||||
|
|
||||||
else {
|
emitter.on('error', event => {
|
||||||
fulfil(stats);
|
reject(event.error);
|
||||||
}
|
});
|
||||||
});
|
|
||||||
|
emitter.on('done', event => {
|
||||||
|
fulfil();
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
console.log(`${colors.bold.red(`> ${err.message}`)}`);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -7,7 +7,7 @@ import URL from 'url-parse';
|
|||||||
import fetch from 'node-fetch';
|
import fetch from 'node-fetch';
|
||||||
import * as ports from 'port-authority';
|
import * as ports from 'port-authority';
|
||||||
import prettyBytes from 'pretty-bytes';
|
import prettyBytes from 'pretty-bytes';
|
||||||
import { minify_html } from './utils/minify_html';
|
import { minify_html } from '../api/utils/minify_html';
|
||||||
import { locations } from '../config';
|
import { locations } from '../config';
|
||||||
|
|
||||||
export async function exporter(export_dir: string, { basepath = '' }) {
|
export async function exporter(export_dir: string, { basepath = '' }) {
|
||||||
|
|||||||
@@ -1,21 +1,21 @@
|
|||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import relative from 'require-relative';
|
import relative from 'require-relative';
|
||||||
|
|
||||||
export default function create_compilers() {
|
export default function create_compilers({ webpack }: { webpack: string }) {
|
||||||
const webpack = relative('webpack', process.cwd());
|
const wp = relative('webpack', process.cwd());
|
||||||
|
|
||||||
const serviceworker_config = try_require(path.resolve('webpack/service-worker.config.js'));
|
const serviceworker_config = try_require(path.resolve(`${webpack}/service-worker.config.js`));
|
||||||
|
|
||||||
return {
|
return {
|
||||||
client: webpack(
|
client: wp(
|
||||||
require(path.resolve('webpack/client.config.js'))
|
require(path.resolve(`${webpack}/client.config.js`))
|
||||||
),
|
),
|
||||||
|
|
||||||
server: webpack(
|
server: wp(
|
||||||
require(path.resolve('webpack/server.config.js'))
|
require(path.resolve(`${webpack}/server.config.js`))
|
||||||
),
|
),
|
||||||
|
|
||||||
serviceworker: serviceworker_config && webpack(serviceworker_config)
|
serviceworker: serviceworker_config && wp(serviceworker_config)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user