fix some typescript stuff

This commit is contained in:
Rich Harris
2018-02-14 12:25:24 -05:00
parent 9adb6ca7e6
commit 0f390920a8
4 changed files with 57 additions and 23 deletions

View File

@@ -16,11 +16,7 @@ function fudge_mtime(file: string) {
); );
} }
function create_app({ function create_app({ src, dev, entry }: {
src,
dev,
entry
}: {
src: string; src: string;
dev: boolean; dev: boolean;
entry: { client: string; server: string }; entry: { client: string; server: string };

View File

@@ -4,18 +4,29 @@ import glob from 'glob';
import { create_templates, render } from './templates'; import { create_templates, render } from './templates';
import create_routes from './create_routes'; import create_routes from './create_routes';
function ensure_array(thing) { function ensure_array(thing: any) {
return Array.isArray(thing) ? thing : [thing]; // omg webpack what the HELL are you doing return Array.isArray(thing) ? thing : [thing]; // omg webpack what the HELL are you doing
} }
export default function create_assets({ src, dest, dev, client_info, server_info }) { type WebpackInfo = {
assetsByChunkName: Record<string, string>;
assets: Array<{ name: string }>
}
export default function create_assets({ src, dest, dev, client_info, server_info }: {
src: string;
dest: string;
dev: boolean;
client_info: WebpackInfo;
server_info: WebpackInfo;
}) {
create_templates(); // TODO refactor this... create_templates(); // TODO refactor this...
const main_file = `/client/${ensure_array(client_info.assetsByChunkName.main)[0]}`; const main_file = `/client/${ensure_array(client_info.assetsByChunkName.main)[0]}`;
const chunk_files = client_info.assets.map(chunk => `/client/${chunk.name}`); const chunk_files = client_info.assets.map(chunk => `/client/${chunk.name}`);
const service_worker = generate_service_worker({ chunk_files, src }); const service_worker = generate_service_worker(chunk_files, src);
const index = generate_index(main_file); const index = generate_index(main_file);
const routes = create_routes({ src }); const routes = create_routes({ src });
@@ -31,13 +42,13 @@ export default function create_assets({ src, dest, dev, client_info, server_info
chunk_files, chunk_files,
main: read(`${dest}${main_file}`), main: read(`${dest}${main_file}`),
chunks: chunk_files.reduce((lookup, file) => { chunks: chunk_files.reduce((lookup: Record<string, string>, file) => {
lookup[file] = read(`${dest}${file}`); lookup[file] = read(`${dest}${file}`);
return lookup; return lookup;
}, {}), }, {}),
// TODO confusing that `routes` refers to an array *and* a lookup // TODO confusing that `routes` refers to an array *and* a lookup
routes: routes.reduce((lookup, route) => { routes: routes.reduce((lookup: Record<string, string>, route) => {
lookup[route.id] = `/client/${ensure_array(client_info.assetsByChunkName[route.id])[0]}`; lookup[route.id] = `/client/${ensure_array(client_info.assetsByChunkName[route.id])[0]}`;
return lookup; return lookup;
}, {}), }, {}),
@@ -54,7 +65,7 @@ export default function create_assets({ src, dest, dev, client_info, server_info
}; };
} }
function generate_service_worker({ chunk_files, src }) { function generate_service_worker(chunk_files: string[], src: string) {
const assets = glob.sync('**', { cwd: 'assets', nodir: true }); const assets = glob.sync('**', { cwd: 'assets', nodir: true });
const routes = create_routes({ src }); const routes = create_routes({ src });
@@ -67,13 +78,13 @@ function generate_service_worker({ chunk_files, src }) {
}]`; }]`;
return read('templates/service-worker.js') return read('templates/service-worker.js')
.replace(/__timestamp__/g, Date.now()) .replace(/__timestamp__/g, String(Date.now()))
.replace(/__assets__/g, JSON.stringify(assets)) .replace(/__assets__/g, JSON.stringify(assets))
.replace(/__shell__/g, JSON.stringify(chunk_files.concat('/index.html'))) .replace(/__shell__/g, JSON.stringify(chunk_files.concat('/index.html')))
.replace(/__routes__/g, route_code); .replace(/__routes__/g, route_code);
} }
function generate_index(main_file) { function generate_index(main_file: string) {
return render(200, { return render(200, {
styles: '', styles: '',
head: '', head: '',
@@ -82,6 +93,6 @@ function generate_index(main_file) {
}); });
} }
function read(file) { function read(file: string) {
return fs.readFileSync(file, 'utf-8'); return fs.readFileSync(file, 'utf-8');
} }

View File

@@ -6,11 +6,24 @@ export default function create_compilers() {
return { return {
client: webpack( client: webpack(
require(path.resolve('webpack.client.config.js')) require(path.resolve('webpack/client.config.js'))
), ),
server: webpack( server: webpack(
require(path.resolve('webpack.server.config.js')) require(path.resolve('webpack/server.config.js'))
),
serviceWorker: webpack(
tryRequire(path.resolve('webpack/server.config.js'))
) )
}; };
}
function tryRequire(specifier: string) {
try {
return require(specifier);
} catch (err) {
if (err.code === 'MODULE_NOT_FOUND') return null;
throw err;
}
} }

View File

@@ -1,9 +1,23 @@
import * as path from 'path'; import * as path from 'path';
import glob from 'glob'; import glob from 'glob';
export default function create_routes({ src, files = glob.sync('**/*.+(html|js|mjs)', { cwd: src }) }) { type Route = {
const routes = files id: string;
.map(file => { type: 'page' | 'route';
file: string;
pattern: RegExp;
test: (url: string) => boolean;
exec: (url: string) => Record<string, string>;
parts: string[];
dynamic: string[];
}
export default function create_routes({ src, files = glob.sync('**/*.+(html|js|mjs)', { cwd: src }) }: {
src: string;
files?: string[];
}) {
const routes: Route[] = files
.map((file: string) => {
if (/(^|\/|\\)_/.test(file)) return; if (/(^|\/|\\)_/.test(file)) return;
const parts = file.replace(/\.(html|js|mjs)$/, '').split('/'); // glob output is always posix-style const parts = file.replace(/\.(html|js|mjs)$/, '').split('/'); // glob output is always posix-style
@@ -34,13 +48,13 @@ export default function create_routes({ src, files = glob.sync('**/*.+(html|js|m
const pattern = new RegExp(`^${pattern_string}\\/?$`); const pattern = new RegExp(`^${pattern_string}\\/?$`);
const test = url => pattern.test(url); const test = (url: string) => pattern.test(url);
const exec = url => { const exec = (url: string) => {
const match = pattern.exec(url); const match = pattern.exec(url);
if (!match) return; if (!match) return;
const params = {}; const params: Record<string, string> = {};
dynamic.forEach((param, i) => { dynamic.forEach((param, i) => {
params[param] = match[i + 1]; params[param] = match[i + 1];
}); });
@@ -60,7 +74,7 @@ export default function create_routes({ src, files = glob.sync('**/*.+(html|js|m
}; };
}) })
.filter(Boolean) .filter(Boolean)
.sort((a, b) => { .sort((a: Route, b: Route) => {
let same = true; let same = true;
for (let i = 0; true; i += 1) { for (let i = 0; true; i += 1) {