mirror of
https://github.com/kevin-DL/sapper.git
synced 2026-01-12 11:15:14 +00:00
incorporate Sirv, and add a sapper.start() function
This commit is contained in:
@@ -24,8 +24,9 @@ function template(kind, external) {
|
||||
external,
|
||||
plugins: [
|
||||
resolve({
|
||||
extensions: ['.mjs', '.js', '.ts']
|
||||
extensions: ['.mjs', '.js', '.json', '.ts']
|
||||
}),
|
||||
json(),
|
||||
commonjs(),
|
||||
string({
|
||||
include: '**/*.md'
|
||||
|
||||
@@ -336,7 +336,7 @@ export async function hydrate_target(target: Target): Promise<{
|
||||
}
|
||||
|
||||
function load_css(chunk: string) {
|
||||
const href = `client/${chunk}`;
|
||||
const href = `sapper/${chunk}`;
|
||||
if (document.querySelector(`link[href="${href}"]`)) return;
|
||||
|
||||
return new Promise((fulfil, reject) => {
|
||||
|
||||
@@ -1 +1,14 @@
|
||||
export { default as middleware } from './middleware/index';
|
||||
import * as http from 'http';
|
||||
import middleware from './middleware/index';
|
||||
import { StartOptions, MiddlewareOptions, Handler } from './types';
|
||||
|
||||
export { middleware };
|
||||
|
||||
export function start(opts: StartOptions = {}) {
|
||||
const handler = middleware(opts) as Handler;
|
||||
const server = http.createServer(handler as http.ServerOptions);
|
||||
|
||||
server.listen(opts.port || process.env.PORT);
|
||||
|
||||
return server;
|
||||
}
|
||||
@@ -5,7 +5,7 @@ import cookie from 'cookie';
|
||||
import devalue from 'devalue';
|
||||
import fetch from 'node-fetch';
|
||||
import URL from 'url';
|
||||
import { Manifest, Page, Req, Res } from './types';
|
||||
import { Manifest, Page, Req, Res } from '../types';
|
||||
import { build_dir, dev, src_dir } from '@sapper/internal/manifest-server';
|
||||
import App from '@sapper/internal/App.svelte';
|
||||
|
||||
@@ -21,9 +21,8 @@ export function get_page_handler(
|
||||
? () => read_template(src_dir)
|
||||
: (str => () => str)(read_template(build_dir));
|
||||
|
||||
const has_service_worker = fs.existsSync(path.join(build_dir, 'service-worker.js'));
|
||||
const has_service_worker = fs.existsSync(path.join(build_dir, 'service-worker/service-worker.js'));
|
||||
|
||||
const { server_routes, pages } = manifest;
|
||||
const error_route = manifest.error;
|
||||
|
||||
function handle_error(req: Req, res: Res, statusCode: number, error: Error | string) {
|
||||
@@ -63,7 +62,7 @@ export function get_page_handler(
|
||||
// TODO add dependencies and CSS
|
||||
const link = preloaded_chunks
|
||||
.filter(file => file && !file.match(/\.map$/))
|
||||
.map(file => `<${req.baseUrl}/client/${file}>;rel="modulepreload"`)
|
||||
.map(file => `<${req.baseUrl}/sapper/${file}>;rel="modulepreload"`)
|
||||
.join(', ');
|
||||
|
||||
res.setHeader('Link', link);
|
||||
@@ -72,7 +71,7 @@ export function get_page_handler(
|
||||
.filter(file => file && !file.match(/\.map$/))
|
||||
.map((file) => {
|
||||
const as = /\.css$/.test(file) ? 'style' : 'script';
|
||||
return `<${req.baseUrl}/client/${file}>;rel="preload";as="${as}"`;
|
||||
return `<${req.baseUrl}/sapper/${file}>;rel="preload";as="${as}"`;
|
||||
})
|
||||
.join(', ');
|
||||
|
||||
@@ -263,14 +262,14 @@ export function get_page_handler(
|
||||
}
|
||||
|
||||
const file = [].concat(build_info.assets.main).filter(file => file && /\.js$/.test(file))[0];
|
||||
const main = `${req.baseUrl}/client/${file}`;
|
||||
const main = `${req.baseUrl}/sapper/${file}`;
|
||||
|
||||
if (build_info.bundler === 'rollup') {
|
||||
if (build_info.legacy_assets) {
|
||||
const legacy_main = `${req.baseUrl}/client/legacy/${build_info.legacy_assets.main}`;
|
||||
script += `(function(){try{eval("async function x(){}");var main="${main}"}catch(e){main="${legacy_main}"};var s=document.createElement("script");try{new Function("if(0)import('')")();s.src=main;s.type="module";s.crossOrigin="use-credentials";}catch(e){s.src="${req.baseUrl}/client/shimport@${build_info.shimport}.js";s.setAttribute("data-main",main);}document.head.appendChild(s);}());`;
|
||||
const legacy_main = `${req.baseUrl}/sapper/legacy/${build_info.legacy_assets.main}`;
|
||||
script += `(function(){try{eval("async function x(){}");var main="${main}"}catch(e){main="${legacy_main}"};var s=document.createElement("script");try{new Function("if(0)import('')")();s.src=main;s.type="module";s.crossOrigin="use-credentials";}catch(e){s.src="${req.baseUrl}/sapper/shimport@${build_info.shimport}.js";s.setAttribute("data-main",main);}document.head.appendChild(s);}());`;
|
||||
} else {
|
||||
script += `var s=document.createElement("script");try{new Function("if(0)import('')")();s.src="${main}";s.type="module";s.crossOrigin="use-credentials";}catch(e){s.src="${req.baseUrl}/client/shimport@${build_info.shimport}.js";s.setAttribute("data-main","${main}")}document.head.appendChild(s)`;
|
||||
script += `var s=document.createElement("script");try{new Function("if(0)import('')")();s.src="${main}";s.type="module";s.crossOrigin="use-credentials";}catch(e){s.src="${req.baseUrl}/sapper/shimport@${build_info.shimport}.js";s.setAttribute("data-main","${main}")}document.head.appendChild(s)`;
|
||||
}
|
||||
} else {
|
||||
script += `</script><script src="${main}">`;
|
||||
@@ -295,7 +294,7 @@ export function get_page_handler(
|
||||
});
|
||||
|
||||
styles = Array.from(css_chunks)
|
||||
.map(href => `<link rel="stylesheet" href="client/${href}">`)
|
||||
.map(href => `<link rel="stylesheet" href="sapper/${href}">`)
|
||||
.join('')
|
||||
} else {
|
||||
styles = (css && css.code ? `<style>${css.code}</style>` : '');
|
||||
@@ -327,12 +326,12 @@ export function get_page_handler(
|
||||
|
||||
return function find_route(req: Req, res: Res, next: () => void) {
|
||||
if (req.path === '/service-worker-index.html') {
|
||||
const homePage = pages.find(page => page.pattern.test('/'));
|
||||
const homePage = manifest.pages.find(page => page.pattern.test('/'));
|
||||
handle_page(homePage, req, res);
|
||||
return;
|
||||
}
|
||||
|
||||
for (const page of pages) {
|
||||
for (const page of manifest.pages) {
|
||||
if (page.pattern.test(req.path)) {
|
||||
handle_page(page, req, res);
|
||||
return;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Req, Res, ServerRoute } from './types';
|
||||
import { Req, Res, ServerRoute } from '../types';
|
||||
|
||||
export function get_server_route_handler(routes: ServerRoute[]) {
|
||||
async function handle_route(route: ServerRoute, req: Req, res: Res, next: () => void) {
|
||||
|
||||
@@ -1,23 +1,41 @@
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import sirv from 'sirv';
|
||||
import { build_dir, dev, manifest } from '@sapper/internal/manifest-server';
|
||||
import { Handler, Req, Res } from './types';
|
||||
import { Handler, Req, Res, MiddlewareOptions } from '../types';
|
||||
import { get_server_route_handler } from './get_server_route_handler';
|
||||
import { get_page_handler } from './get_page_handler';
|
||||
import { lookup } from './mime';
|
||||
import { stringify } from 'querystring';
|
||||
|
||||
export default function middleware(opts: {
|
||||
session?: (req: Req, res: Res) => any,
|
||||
ignore?: any
|
||||
} = {}) {
|
||||
export default function middleware(opts: MiddlewareOptions = {}) {
|
||||
const { session, ignore } = opts;
|
||||
|
||||
let emitted_basepath = false;
|
||||
|
||||
return compose_handlers(ignore, [
|
||||
sirv('static', {
|
||||
dev,
|
||||
setHeaders: opts.static && opts.static.headers && ((res: Response, pathname: string, stats: fs.Stats) => {
|
||||
const headers = opts.static.headers(pathname, stats);
|
||||
for (const k in headers) res.setHeader(k, headers[k]);
|
||||
})
|
||||
}),
|
||||
|
||||
sirv(`${build_dir}/client`, {
|
||||
dev,
|
||||
maxAge: 31536000,
|
||||
immutable: true
|
||||
}),
|
||||
|
||||
sirv(`${build_dir}/service-worker`, {
|
||||
dev,
|
||||
maxAge: 300
|
||||
}),
|
||||
|
||||
(req: Req, res: Res, next: () => void) => {
|
||||
if (req.baseUrl === undefined) {
|
||||
let { originalUrl } = req;
|
||||
let originalUrl = req.originalUrl || req.url;
|
||||
if (req.url === '/' && originalUrl[originalUrl.length - 1] !== '/') {
|
||||
originalUrl += '/';
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { Stats } from 'fs';
|
||||
import { ClientRequest, ServerResponse } from 'http';
|
||||
|
||||
export type ServerRoute = {
|
||||
@@ -37,6 +38,18 @@ export type Props = {
|
||||
[key: string]: any;
|
||||
};
|
||||
|
||||
export interface MiddlewareOptions {
|
||||
static?: {
|
||||
headers?: (pathname: string, stats: Stats) => Record<string, string>
|
||||
},
|
||||
session?: (req: Req, res: Res) => any,
|
||||
ignore?: any
|
||||
}
|
||||
|
||||
export interface StartOptions extends MiddlewareOptions {
|
||||
port?: number;
|
||||
}
|
||||
|
||||
export interface Req extends ClientRequest {
|
||||
url: string;
|
||||
baseUrl: string;
|
||||
@@ -122,7 +122,7 @@ export async function build({
|
||||
|
||||
const client_files = client_result.chunks
|
||||
.filter(chunk => !chunk.file.endsWith('.map')) // SW does not need to cache sourcemap files
|
||||
.map(chunk => `client/${chunk.file}`);
|
||||
.map(chunk => `sapper/${chunk.file}`);
|
||||
|
||||
create_serviceworker_manifest({
|
||||
manifest_data,
|
||||
|
||||
@@ -333,7 +333,7 @@ class Watcher extends EventEmitter {
|
||||
JSON.stringify(result.to_json(manifest_data, this.dirs), null, ' ')
|
||||
);
|
||||
|
||||
const client_files = result.chunks.map(chunk => `client/${chunk.file}`);
|
||||
const client_files = result.chunks.map(chunk => `sapper/${chunk.file}`);
|
||||
|
||||
create_serviceworker_manifest({
|
||||
manifest_data,
|
||||
|
||||
@@ -60,9 +60,8 @@ async function _export({
|
||||
rimraf(export_dir);
|
||||
|
||||
copy(static_files, export_dir);
|
||||
copy(path.join(build_dir, 'client'), path.join(export_dir, 'client'));
|
||||
copy(path.join(build_dir, 'service-worker.js'), path.join(export_dir, 'service-worker.js'));
|
||||
copy(path.join(build_dir, 'service-worker.js.map'), path.join(export_dir, 'service-worker.js.map'));
|
||||
copy(path.join(build_dir, 'client'), export_dir);
|
||||
copy(path.join(build_dir, 'service-worker'), export_dir);
|
||||
|
||||
const defaultPort = process.env.PORT ? parseInt(process.env.PORT) : 3000;
|
||||
const port = await ports.find(defaultPort);
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
import * as fs from 'fs';
|
||||
import { mkdirp } from './fs_utils';
|
||||
|
||||
export function copy_shimport(dest: string) {
|
||||
mkdirp(`${dest}/client/sapper`);
|
||||
|
||||
const shimport_version = require('shimport/package.json').version;
|
||||
|
||||
fs.writeFileSync(
|
||||
`${dest}/client/shimport@${shimport_version}.js`,
|
||||
`${dest}/client/sapper/shimport@${shimport_version}.js`,
|
||||
fs.readFileSync(require.resolve('shimport/index.js'))
|
||||
);
|
||||
}
|
||||
@@ -9,7 +9,7 @@ export default {
|
||||
},
|
||||
|
||||
output: () => {
|
||||
let dir = `${dest}/client`;
|
||||
let dir = `${dest}/client/sapper`;
|
||||
if (process.env.SAPPER_LEGACY_BUILD) dir += `/legacy`;
|
||||
|
||||
return {
|
||||
@@ -45,7 +45,7 @@ export default {
|
||||
|
||||
output: () => {
|
||||
return {
|
||||
file: `${dest}/service-worker.js`,
|
||||
file: `${dest}/service-worker/service-worker.js`,
|
||||
format: 'iife'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,10 +12,10 @@ export default {
|
||||
|
||||
output: () => {
|
||||
return {
|
||||
path: `${dest}/client`,
|
||||
path: `${dest}/client/sapper`,
|
||||
filename: '[hash]/[name].js',
|
||||
chunkFilename: '[hash]/[name].[id].js',
|
||||
publicPath: `client/`
|
||||
publicPath: `sapper/`
|
||||
};
|
||||
}
|
||||
},
|
||||
@@ -46,7 +46,7 @@ export default {
|
||||
|
||||
output: () => {
|
||||
return {
|
||||
path: dest,
|
||||
path: `${dest}/service-worker`,
|
||||
filename: '[name].js',
|
||||
chunkFilename: '[name].[id].[hash].js'
|
||||
}
|
||||
|
||||
@@ -116,7 +116,7 @@ export default function extract_css(client_result: CompileResult, components: Pa
|
||||
|
||||
if (!client_result.css_files) return; // Rollup-only for now
|
||||
|
||||
let asset_dir = `${dirs.dest}/client`;
|
||||
let asset_dir = `${dirs.dest}/client/sapper`;
|
||||
if (process.env.SAPPER_LEGACY_BUILD) asset_dir += '/legacy';
|
||||
|
||||
const unclaimed = new Set(client_result.css_files.map(x => x.id));
|
||||
@@ -238,7 +238,7 @@ export default function extract_css(client_result: CompileResult, components: Pa
|
||||
map.file = output_file_name;
|
||||
map.sources = map.sources.map(source => path.relative(asset_dir, source));
|
||||
|
||||
fs.writeFileSync(`${asset_dir}/${output_file_name}`, `${code}\n/* sourceMappingURL=client/${output_file_name}.map */`);
|
||||
fs.writeFileSync(`${asset_dir}/${output_file_name}`, `${code}\n/* sourceMappingURL=sapper/${output_file_name}.map */`);
|
||||
fs.writeFileSync(`${asset_dir}/${output_file_name}.map`, JSON.stringify(map, null, ' '));
|
||||
|
||||
result.main = output_file_name;
|
||||
|
||||
Reference in New Issue
Block a user