mirror of
https://github.com/kevin-DL/sapper.git
synced 2026-01-20 06:15:15 +00:00
sapper build defaults to build dir, sapper export defaults to export dir (#133)
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -4,6 +4,7 @@ node_modules
|
|||||||
cypress/screenshots
|
cypress/screenshots
|
||||||
test/app/.sapper
|
test/app/.sapper
|
||||||
test/app/app/manifest
|
test/app/app/manifest
|
||||||
|
test/app/export
|
||||||
runtime.js
|
runtime.js
|
||||||
runtime.js.map
|
runtime.js.map
|
||||||
cli.js
|
cli.js
|
||||||
@@ -14,3 +15,4 @@ core.js
|
|||||||
core.js.map
|
core.js.map
|
||||||
webpack/config.js
|
webpack/config.js
|
||||||
webpack/config.js.map
|
webpack/config.js.map
|
||||||
|
yarn-error.log
|
||||||
@@ -2,18 +2,16 @@ import * as fs from 'fs';
|
|||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import mkdirp from 'mkdirp';
|
import mkdirp from 'mkdirp';
|
||||||
import rimraf from 'rimraf';
|
import rimraf from 'rimraf';
|
||||||
import { create_compilers, create_app, create_routes, create_serviceworker } from 'sapper/core.js';
|
import { create_compilers, create_app, create_routes, create_serviceworker } from 'sapper/core.js'
|
||||||
|
import { src, dest, dev } from '../config';
|
||||||
|
|
||||||
export default async function build({ src, dest, dev, entry }: {
|
export default async function build() {
|
||||||
src: string;
|
const output = dest();
|
||||||
dest: string;
|
|
||||||
dev: boolean;
|
|
||||||
entry: { client: string, server: string }
|
|
||||||
}) {
|
|
||||||
mkdirp.sync(dest);
|
|
||||||
rimraf.sync(path.join(dest, '**/*'));
|
|
||||||
|
|
||||||
const routes = create_routes({ src });
|
mkdirp.sync(output);
|
||||||
|
rimraf.sync(path.join(output, '**/*'));
|
||||||
|
|
||||||
|
const routes = create_routes();
|
||||||
|
|
||||||
// create app/manifest/client.js and app/manifest/server.js
|
// create app/manifest/client.js and app/manifest/server.js
|
||||||
create_app({ routes, src, dev });
|
create_app({ routes, src, dev });
|
||||||
@@ -21,7 +19,7 @@ export default async function build({ src, dest, dev, entry }: {
|
|||||||
const { client, server, serviceworker } = create_compilers();
|
const { client, server, serviceworker } = create_compilers();
|
||||||
|
|
||||||
const client_stats = await compile(client);
|
const client_stats = await compile(client);
|
||||||
fs.writeFileSync(path.join(dest, 'client_info.json'), JSON.stringify(client_stats.toJson()));
|
fs.writeFileSync(path.join(output, 'client_info.json'), JSON.stringify(client_stats.toJson()));
|
||||||
|
|
||||||
await compile(server);
|
await compile(server);
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import * as http from 'http';
|
|||||||
import mkdirp from 'mkdirp';
|
import mkdirp from 'mkdirp';
|
||||||
import rimraf from 'rimraf';
|
import rimraf from 'rimraf';
|
||||||
import { wait_for_port } from './utils';
|
import { wait_for_port } from './utils';
|
||||||
|
import { dest } from '../config';
|
||||||
import { create_compilers, create_app, create_routes, create_serviceworker, create_template } from 'sapper/core.js';
|
import { create_compilers, create_app, create_routes, create_serviceworker, create_template } from 'sapper/core.js';
|
||||||
|
|
||||||
type Deferred = {
|
type Deferred = {
|
||||||
@@ -66,7 +67,9 @@ function create_hot_update_server(port: number, interval = 10000) {
|
|||||||
return { send };
|
return { send };
|
||||||
}
|
}
|
||||||
|
|
||||||
export default async function dev(src: string, dir: string) {
|
export default async function dev() {
|
||||||
|
const dir = dest();
|
||||||
|
|
||||||
rimraf.sync(dir);
|
rimraf.sync(dir);
|
||||||
mkdirp.sync(dir);
|
mkdirp.sync(dir);
|
||||||
|
|
||||||
@@ -75,8 +78,8 @@ export default async function dev(src: string, dir: string) {
|
|||||||
// initial build
|
// initial build
|
||||||
const dev_port = await require('get-port')(10000);
|
const dev_port = await require('get-port')(10000);
|
||||||
|
|
||||||
const routes = create_routes({ src });
|
const routes = create_routes();
|
||||||
create_app({ routes, src, dev: true, dev_port });
|
create_app({ routes, dev_port });
|
||||||
|
|
||||||
const hot_update_server = create_hot_update_server(dev_port);
|
const hot_update_server = create_hot_update_server(dev_port);
|
||||||
|
|
||||||
@@ -94,8 +97,8 @@ export default async function dev(src: string, dir: string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
watch_files('routes/**/*.+(html|js|mjs)', () => {
|
watch_files('routes/**/*.+(html|js|mjs)', () => {
|
||||||
const routes = create_routes({ src });
|
const routes = create_routes();
|
||||||
create_app({ routes, src, dev: true, dev_port });
|
create_app({ routes, dev_port });
|
||||||
});
|
});
|
||||||
|
|
||||||
watch_files('app/template.html', () => {
|
watch_files('app/template.html', () => {
|
||||||
@@ -190,9 +193,8 @@ export default async function dev(src: string, dir: string) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
create_serviceworker({
|
create_serviceworker({
|
||||||
routes: create_routes({ src }),
|
routes: create_routes(),
|
||||||
client_files,
|
client_files
|
||||||
src
|
|
||||||
});
|
});
|
||||||
|
|
||||||
watch_serviceworker();
|
watch_serviceworker();
|
||||||
|
|||||||
@@ -6,8 +6,7 @@ import cheerio from 'cheerio';
|
|||||||
import URL from 'url-parse';
|
import URL from 'url-parse';
|
||||||
import fetch from 'node-fetch';
|
import fetch from 'node-fetch';
|
||||||
import { wait_for_port } from './utils';
|
import { wait_for_port } from './utils';
|
||||||
|
import { dest } from '../config';
|
||||||
const { OUTPUT_DIR = 'dist' } = process.env;
|
|
||||||
|
|
||||||
const app = express();
|
const app = express();
|
||||||
|
|
||||||
@@ -15,19 +14,24 @@ function read_json(file: string) {
|
|||||||
return JSON.parse(sander.readFileSync(file, { encoding: 'utf-8' }));
|
return JSON.parse(sander.readFileSync(file, { encoding: 'utf-8' }));
|
||||||
}
|
}
|
||||||
|
|
||||||
export default async function exporter(dir: string) { // dir === '.sapper'
|
export default async function exporter(export_dir: string) {
|
||||||
// Prep output directory
|
const build_dir = dest();
|
||||||
sander.rimrafSync(OUTPUT_DIR);
|
|
||||||
|
|
||||||
sander.copydirSync('assets').to(OUTPUT_DIR);
|
// Prep output directory
|
||||||
sander.copydirSync(dir, 'client').to(OUTPUT_DIR, 'client');
|
sander.rimrafSync(export_dir);
|
||||||
sander.copyFileSync(dir, 'service-worker.js').to(OUTPUT_DIR, 'service-worker.js');
|
|
||||||
|
sander.copydirSync('assets').to(export_dir);
|
||||||
|
sander.copydirSync(build_dir, 'client').to(export_dir, 'client');
|
||||||
|
|
||||||
|
if (sander.existsSync(build_dir, 'service-worker.js')) {
|
||||||
|
sander.copyFileSync(build_dir, 'service-worker.js').to(export_dir, 'service-worker.js');
|
||||||
|
}
|
||||||
|
|
||||||
const port = await require('get-port')(3000);
|
const port = await require('get-port')(3000);
|
||||||
|
|
||||||
const origin = `http://localhost:${port}`;
|
const origin = `http://localhost:${port}`;
|
||||||
|
|
||||||
const proc = child_process.fork(path.resolve(`${dir}/server.js`), [], {
|
const proc = child_process.fork(path.resolve(`${build_dir}/server.js`), [], {
|
||||||
cwd: process.cwd(),
|
cwd: process.cwd(),
|
||||||
env: {
|
env: {
|
||||||
PORT: port,
|
PORT: port,
|
||||||
@@ -48,11 +52,11 @@ export default async function exporter(dir: string) { // dir === '.sapper'
|
|||||||
saved.add(url.pathname);
|
saved.add(url.pathname);
|
||||||
|
|
||||||
if (message.type === 'text/html') {
|
if (message.type === 'text/html') {
|
||||||
const dest = `${OUTPUT_DIR}/${url.pathname}/index.html`;
|
const file = `${export_dir}/${url.pathname}/index.html`;
|
||||||
sander.writeFileSync(dest, message.body);
|
sander.writeFileSync(file, message.body);
|
||||||
} else {
|
} else {
|
||||||
const dest = `${OUTPUT_DIR}/${url.pathname}`;
|
const file = `${export_dir}/${url.pathname}`;
|
||||||
sander.writeFileSync(dest, message.body);
|
sander.writeFileSync(file, message.body);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import build from './build';
|
|||||||
import exporter from './export';
|
import exporter from './export';
|
||||||
import dev from './dev';
|
import dev from './dev';
|
||||||
import upgrade from './upgrade';
|
import upgrade from './upgrade';
|
||||||
import { dest, entry, src } from '../config';
|
|
||||||
import * as pkg from '../../package.json';
|
import * as pkg from '../../package.json';
|
||||||
|
|
||||||
const opts = mri(process.argv.slice(2), {
|
const opts = mri(process.argv.slice(2), {
|
||||||
@@ -31,8 +30,9 @@ const start = Date.now();
|
|||||||
|
|
||||||
if (cmd === 'build') {
|
if (cmd === 'build') {
|
||||||
process.env.NODE_ENV = 'production';
|
process.env.NODE_ENV = 'production';
|
||||||
|
process.env.SAPPER_DEST = opts._[1] || 'build';
|
||||||
|
|
||||||
build({ dest, dev: false, entry, src })
|
build()
|
||||||
.then(() => {
|
.then(() => {
|
||||||
const elapsed = Date.now() - start;
|
const elapsed = Date.now() - start;
|
||||||
console.error(`built in ${elapsed}ms`); // TODO beautify this, e.g. 'built in 4.7 seconds'
|
console.error(`built in ${elapsed}ms`); // TODO beautify this, e.g. 'built in 4.7 seconds'
|
||||||
@@ -43,8 +43,10 @@ if (cmd === 'build') {
|
|||||||
} else if (cmd === 'export') {
|
} else if (cmd === 'export') {
|
||||||
process.env.NODE_ENV = 'production';
|
process.env.NODE_ENV = 'production';
|
||||||
|
|
||||||
build({ dest, dev: false, entry, src })
|
const export_dir = opts._[1] || 'export';
|
||||||
.then(() => exporter(dest))
|
|
||||||
|
build()
|
||||||
|
.then(() => exporter(export_dir))
|
||||||
.then(() => {
|
.then(() => {
|
||||||
const elapsed = Date.now() - start;
|
const elapsed = Date.now() - start;
|
||||||
console.error(`extracted in ${elapsed}ms`); // TODO beautify this, e.g. 'built in 4.7 seconds'
|
console.error(`extracted in ${elapsed}ms`); // TODO beautify this, e.g. 'built in 4.7 seconds'
|
||||||
@@ -53,7 +55,7 @@ if (cmd === 'build') {
|
|||||||
console.error(err ? err.details || err.stack || err.message || err : 'Unknown error');
|
console.error(err ? err.details || err.stack || err.message || err : 'Unknown error');
|
||||||
});
|
});
|
||||||
} else if (cmd === 'dev') {
|
} else if (cmd === 'dev') {
|
||||||
dev(src, dest);
|
dev();
|
||||||
} else if (cmd === 'upgrade') {
|
} else if (cmd === 'upgrade') {
|
||||||
upgrade();
|
upgrade();
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -1,12 +1,5 @@
|
|||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
|
|
||||||
export const isDev = () => process.env.NODE_ENV !== 'production';
|
export const dev = () => process.env.NODE_ENV !== 'production';
|
||||||
|
export const src = () => path.resolve(process.env.SAPPER_ROUTES || 'routes');
|
||||||
export const templates = path.resolve(process.env.SAPPER_TEMPLATES || 'templates');
|
export const dest = () => path.resolve(process.env.SAPPER_DEST || '.sapper');
|
||||||
export const src = path.resolve(process.env.SAPPER_ROUTES || 'routes');
|
|
||||||
export const dest = path.resolve(process.env.SAPPER_DEST || '.sapper');
|
|
||||||
|
|
||||||
export const entry = {
|
|
||||||
client: path.resolve(templates, '.main.rendered.js'),
|
|
||||||
server: path.resolve(dest, 'server-entry.js')
|
|
||||||
};
|
|
||||||
|
|||||||
@@ -3,21 +3,20 @@ import * as path from 'path';
|
|||||||
import mkdirp from 'mkdirp';
|
import mkdirp from 'mkdirp';
|
||||||
import create_routes from './create_routes';
|
import create_routes from './create_routes';
|
||||||
import { fudge_mtime, posixify, write } from './utils';
|
import { fudge_mtime, posixify, write } from './utils';
|
||||||
|
import { dev } from '../config';
|
||||||
import { Route } from '../interfaces';
|
import { Route } from '../interfaces';
|
||||||
|
|
||||||
export default function create_app({ routes, src, dev, dev_port }: {
|
export default function create_app({ routes, dev_port }: {
|
||||||
routes: Route[];
|
routes: Route[];
|
||||||
src: string;
|
|
||||||
dev: boolean;
|
|
||||||
dev_port: number;
|
dev_port: number;
|
||||||
}) {
|
}) {
|
||||||
mkdirp.sync('app/manifest');
|
mkdirp.sync('app/manifest');
|
||||||
|
|
||||||
write('app/manifest/client.js', generate_client(routes, src, dev, dev_port));
|
write('app/manifest/client.js', generate_client(routes, dev_port));
|
||||||
write('app/manifest/server.js', generate_server(routes, src));
|
write('app/manifest/server.js', generate_server(routes));
|
||||||
}
|
}
|
||||||
|
|
||||||
function generate_client(routes: Route[], src: string, dev: boolean, dev_port?: number) {
|
function generate_client(routes: Route[], dev_port?: number) {
|
||||||
let code = `
|
let code = `
|
||||||
// This file is generated by Sapper — do not edit it!
|
// This file is generated by Sapper — do not edit it!
|
||||||
export const routes = [
|
export const routes = [
|
||||||
@@ -42,7 +41,7 @@ function generate_client(routes: Route[], src: string, dev: boolean, dev_port?:
|
|||||||
.join(',\n\t')}
|
.join(',\n\t')}
|
||||||
];`.replace(/^\t\t/gm, '').trim();
|
];`.replace(/^\t\t/gm, '').trim();
|
||||||
|
|
||||||
if (dev) {
|
if (dev()) {
|
||||||
const hmr_client = posixify(
|
const hmr_client = posixify(
|
||||||
path.resolve(__dirname, 'hmr-client.js')
|
path.resolve(__dirname, 'hmr-client.js')
|
||||||
);
|
);
|
||||||
@@ -59,7 +58,7 @@ function generate_client(routes: Route[], src: string, dev: boolean, dev_port?:
|
|||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
function generate_server(routes: Route[], src: string) {
|
function generate_server(routes: Route[]) {
|
||||||
let code = `
|
let code = `
|
||||||
// This file is generated by Sapper — do not edit it!
|
// This file is generated by Sapper — do not edit it!
|
||||||
${routes
|
${routes
|
||||||
@@ -74,7 +73,7 @@ function generate_server(routes: Route[], src: string) {
|
|||||||
export const routes = [
|
export const routes = [
|
||||||
${routes
|
${routes
|
||||||
.map(route => {
|
.map(route => {
|
||||||
const file = posixify(`${src}/${route.file}`);
|
const file = posixify(`../../${route.file}`);
|
||||||
|
|
||||||
if (route.id === '_4xx' || route.id === '_5xx') {
|
if (route.id === '_4xx' || route.id === '_5xx') {
|
||||||
return `{ error: '${route.id.slice(1)}', module: ${route.id} }`;
|
return `{ error: '${route.id.slice(1)}', module: ${route.id} }`;
|
||||||
|
|||||||
@@ -1,11 +1,9 @@
|
|||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import glob from 'glob';
|
import glob from 'glob';
|
||||||
|
import { src } from '../config';
|
||||||
import { Route } from '../interfaces';
|
import { Route } from '../interfaces';
|
||||||
|
|
||||||
export default function create_routes({ src, files = glob.sync('**/*.+(html|js|mjs)', { cwd: src }) }: {
|
export default function create_routes({ files } = { files: glob.sync('**/*.+(html|js|mjs)', { cwd: src() }) }) {
|
||||||
src: string;
|
|
||||||
files?: string[];
|
|
||||||
}) {
|
|
||||||
const routes: Route[] = files
|
const routes: Route[] = files
|
||||||
.map((file: string) => {
|
.map((file: string) => {
|
||||||
if (/(^|\/|\\)_/.test(file)) return;
|
if (/(^|\/|\\)_/.test(file)) return;
|
||||||
|
|||||||
@@ -5,10 +5,9 @@ import create_routes from './create_routes';
|
|||||||
import { fudge_mtime, posixify, write } from './utils';
|
import { fudge_mtime, posixify, write } from './utils';
|
||||||
import { Route } from '../interfaces';
|
import { Route } from '../interfaces';
|
||||||
|
|
||||||
export default function create_serviceworker({ routes, client_files, src }: {
|
export default function create_serviceworker({ routes, client_files }: {
|
||||||
routes: Route[];
|
routes: Route[];
|
||||||
client_files: string[];
|
client_files: string[];
|
||||||
src: string;
|
|
||||||
}) {
|
}) {
|
||||||
const assets = glob.sync('**', { cwd: 'assets', nodir: true });
|
const assets = glob.sync('**', { cwd: 'assets', nodir: true });
|
||||||
|
|
||||||
|
|||||||
@@ -7,14 +7,12 @@ import rimraf from 'rimraf';
|
|||||||
import serialize from 'serialize-javascript';
|
import serialize from 'serialize-javascript';
|
||||||
import escape_html from 'escape-html';
|
import escape_html from 'escape-html';
|
||||||
import { create_routes, templates, create_compilers, create_template } from 'sapper/core.js';
|
import { create_routes, templates, create_compilers, create_template } from 'sapper/core.js';
|
||||||
import { dest, entry, isDev, src } from '../config';
|
import { dest } from '../config';
|
||||||
import { Route, Template } from '../interfaces';
|
import { Route, Template } from '../interfaces';
|
||||||
import sourceMapSupport from 'source-map-support';
|
import sourceMapSupport from 'source-map-support';
|
||||||
|
|
||||||
sourceMapSupport.install();
|
sourceMapSupport.install();
|
||||||
|
|
||||||
const dev = isDev();
|
|
||||||
|
|
||||||
type RouteObject = {
|
type RouteObject = {
|
||||||
id: string;
|
id: string;
|
||||||
type: 'page' | 'route';
|
type: 'page' | 'route';
|
||||||
@@ -43,12 +41,14 @@ interface Req extends ClientRequest {
|
|||||||
export default function middleware({ routes }: {
|
export default function middleware({ routes }: {
|
||||||
routes: RouteObject[]
|
routes: RouteObject[]
|
||||||
}) {
|
}) {
|
||||||
const client_info = JSON.parse(fs.readFileSync(path.join(dest, 'client_info.json'), 'utf-8'));
|
const output = dest();
|
||||||
|
|
||||||
|
const client_info = JSON.parse(fs.readFileSync(path.join(output, 'client_info.json'), 'utf-8'));
|
||||||
|
|
||||||
const template = create_template();
|
const template = create_template();
|
||||||
|
|
||||||
const shell = try_read(path.join(dest, 'index.html'));
|
const shell = try_read(path.join(output, 'index.html'));
|
||||||
const serviceworker = try_read(path.join(dest, 'service-worker.js'));
|
const serviceworker = try_read(path.join(output, 'service-worker.js'));
|
||||||
|
|
||||||
const middleware = compose_handlers([
|
const middleware = compose_handlers([
|
||||||
(req: Req, res: ServerResponse, next: () => void) => {
|
(req: Req, res: ServerResponse, next: () => void) => {
|
||||||
@@ -76,7 +76,7 @@ export default function middleware({ routes }: {
|
|||||||
const type = 'application/javascript'; // TODO might not be, if using e.g. CSS plugin
|
const type = 'application/javascript'; // TODO might not be, if using e.g. CSS plugin
|
||||||
|
|
||||||
// TODO cache?
|
// TODO cache?
|
||||||
const rs = fs.createReadStream(path.join(dest, req.pathname.slice(1)));
|
const rs = fs.createReadStream(path.join(output, req.pathname.slice(1)));
|
||||||
|
|
||||||
rs.on('error', error => {
|
rs.on('error', error => {
|
||||||
res.statusCode = 404;
|
res.statusCode = 404;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { dest, isDev, entry } from '../config';
|
import { dest, dev } from '../config';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
dev: isDev(),
|
dev: dev(),
|
||||||
|
|
||||||
client: {
|
client: {
|
||||||
entry: () => {
|
entry: () => {
|
||||||
@@ -17,7 +17,7 @@ export default {
|
|||||||
|
|
||||||
output: () => {
|
output: () => {
|
||||||
return {
|
return {
|
||||||
path: `${dest}/client`,
|
path: `${dest()}/client`,
|
||||||
filename: '[hash]/[name].js',
|
filename: '[hash]/[name].js',
|
||||||
chunkFilename: '[hash]/[name].[id].js',
|
chunkFilename: '[hash]/[name].[id].js',
|
||||||
publicPath: '/client/'
|
publicPath: '/client/'
|
||||||
@@ -34,7 +34,7 @@ export default {
|
|||||||
|
|
||||||
output: () => {
|
output: () => {
|
||||||
return {
|
return {
|
||||||
path: `${dest}`,
|
path: `${dest()}`,
|
||||||
filename: '[name].js',
|
filename: '[name].js',
|
||||||
chunkFilename: '[hash]/[name].[id].js',
|
chunkFilename: '[hash]/[name].[id].js',
|
||||||
libraryTarget: 'commonjs2'
|
libraryTarget: 'commonjs2'
|
||||||
|
|||||||
Reference in New Issue
Block a user