Compare commits

...

15 Commits

Author SHA1 Message Date
Rich Harris
e66e3cd7eb -> v0.20.4 2018-09-19 11:11:42 -04:00
Rich Harris
ff415b391b Merge pull request #436 from nsivertsen/devtools
Enable debugging in Chrome and VS Code - fixes #435
2018-09-19 11:09:19 -04:00
Rich Harris
91182ad0a2 Merge pull request #441 from silentworks/bugfix/legacy-manifest
Fix for legacy manifest file
2018-09-19 10:43:50 -04:00
Andrew Smith
467041a3cd Fix for legacy manifest file 2018-09-13 19:45:30 +01:00
Nikolai Sivertsen
520949c5e1 Enable debugging in Chrome and VS Code - fixes 435 2018-09-12 16:55:45 +02:00
Rich Harris
8c07d9d2ac -> v0.20.3 2018-09-08 10:24:21 -04:00
Rich Harris
7bd684a80e Merge pull request #428 from nolanlawson/cache-control-service-worker
Set service-worker max-age to 0
2018-09-08 10:20:04 -04:00
Rich Harris
cbb5e8755b Use MDN recommendation for preventing SW caching 2018-09-08 10:12:55 -04:00
Rich Harris
7ef72dbb77 Merge pull request #429 from nolanlawson/consistent-cache-control
Use consistent cache-control:max-age=600 for HTML pages
2018-09-08 09:40:56 -04:00
Nolan Lawson
87ff9c2aeb fix test 2018-09-07 17:25:17 -07:00
Nolan Lawson
2d1f535314 use consistent cache-control:max-age=600 for HTML pages 2018-09-07 16:46:40 -07:00
Rich Harris
cd1b53b80d Merge pull request #424 from nolanlawson/csp-nonce
Allow scripts to contain a CSP nonce
2018-09-07 19:46:07 -04:00
Rich Harris
0a7be736c0 snake_case 2018-09-07 19:45:40 -04:00
Nolan Lawson
5ee53a98c6 set service-worker max-age to 0 2018-09-07 16:28:38 -07:00
Nolan Lawson
e377515867 allow scripts to contain a CSP nonce 2018-09-07 09:46:53 -07:00
7 changed files with 52 additions and 10 deletions

View File

@@ -1,5 +1,16 @@
# sapper changelog # sapper changelog
## 0.20.4
* Fix legacy build CSS ([#439](https://github.com/sveltejs/sapper/issues/439))
* Enable debugging in Chrome and VSCode ([#435](https://github.com/sveltejs/sapper/issues/435))
## 0.20.3
* Inject `nonce` attribute if `res.locals.nonce` is present ([#424](https://github.com/sveltejs/sapper/pull/424))
* Prevent service worker caching ([#428](https://github.com/sveltejs/sapper/pull/428))
* Consistent caching for HTML responses ([#429](https://github.com/sveltejs/sapper/pull/429))
## 0.20.2 ## 0.20.2
* Add `immutable` cache control header for hashed assets ([#425](https://github.com/sveltejs/sapper/pull/425)) * Add `immutable` cache control header for hashed assets ([#425](https://github.com/sveltejs/sapper/pull/425))

View File

@@ -1,6 +1,6 @@
{ {
"name": "sapper", "name": "sapper",
"version": "0.20.2", "version": "0.20.4",
"description": "Military-grade apps, engineered by Svelte", "description": "Military-grade apps, engineered by Svelte",
"main": "dist/middleware.js", "main": "dist/middleware.js",
"bin": { "bin": {
@@ -74,6 +74,7 @@
"test": "mocha --opts mocha.opts", "test": "mocha --opts mocha.opts",
"pretest": "npm run build", "pretest": "npm run build",
"build": "rm -rf dist && rollup -c", "build": "rm -rf dist && rollup -c",
"prepare": "npm run build",
"dev": "rollup -cw", "dev": "rollup -cw",
"prepublishOnly": "npm test", "prepublishOnly": "npm test",
"update_mime_types": "curl http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types | grep -e \"^[^#]\" > src/middleware/mime-types.md" "update_mime_types": "curl http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types | grep -e \"^[^#]\" > src/middleware/mime-types.md"

View File

@@ -79,7 +79,8 @@ async function execute(emitter: EventEmitter, opts: Opts, dirs: Dirs) {
// TODO duration/warnings // TODO duration/warnings
result: client_result result: client_result
}); });
client_result.to_json(manifest_data, dirs);
build_info.legacy_assets = client_result.assets; build_info.legacy_assets = client_result.assets;
delete process.env.SAPPER_LEGACY_BUILD; delete process.env.SAPPER_LEGACY_BUILD;
} }

View File

@@ -36,6 +36,8 @@ class Watcher extends EventEmitter {
live: boolean; live: boolean;
hot: boolean; hot: boolean;
devtools_port: number;
dev_server: DevServer; dev_server: DevServer;
proc: child_process.ChildProcess; proc: child_process.ChildProcess;
filewatchers: Array<{ close: () => void }>; filewatchers: Array<{ close: () => void }>;
@@ -57,6 +59,7 @@ class Watcher extends EventEmitter {
'dev-port': dev_port, 'dev-port': dev_port,
live, live,
hot, hot,
'devtools-port': devtools_port,
bundler, bundler,
webpack = 'webpack', webpack = 'webpack',
rollup = 'rollup', rollup = 'rollup',
@@ -68,6 +71,7 @@ class Watcher extends EventEmitter {
'dev-port': number, 'dev-port': number,
live: boolean, live: boolean,
hot: boolean, hot: boolean,
'devtools-port': number,
bundler?: string, bundler?: string,
webpack: string, webpack: string,
rollup: string, rollup: string,
@@ -84,6 +88,8 @@ class Watcher extends EventEmitter {
this.live = live; this.live = live;
this.hot = hot; this.hot = hot;
this.devtools_port = devtools_port;
this.filewatchers = []; this.filewatchers = [];
this.current_build = { this.current_build = {
@@ -129,6 +135,9 @@ class Watcher extends EventEmitter {
if (!this.dev_port) this.dev_port = await ports.find(10000); if (!this.dev_port) this.dev_port = await ports.find(10000);
// Chrome looks for debugging targets on ports 9222 and 9229 by default
if (!this.devtools_port) this.devtools_port = await ports.find(9222);
let manifest_data: ManifestData; let manifest_data: ManifestData;
try { try {
@@ -238,12 +247,21 @@ class Watcher extends EventEmitter {
restart(); restart();
} }
// we need to give the child process its own DevTools port,
// otherwise Node will try to use the parent's (and fail)
const debugArgRegex = /--inspect(?:-brk|-port)?|--debug-port/;
const execArgv = process.execArgv.slice();
if (execArgv.some((arg: string) => !!arg.match(debugArgRegex))) {
execArgv.push(`--inspect-port=${this.devtools_port}`);
}
this.proc = child_process.fork(`${dest}/server.js`, [], { this.proc = child_process.fork(`${dest}/server.js`, [], {
cwd: process.cwd(), cwd: process.cwd(),
env: Object.assign({ env: Object.assign({
PORT: this.port PORT: this.port
}, process.env), }, process.env),
stdio: ['ipc'] stdio: ['ipc'],
execArgv
}); });
this.proc.stdout.on('data', chunk => { this.proc.stdout.on('data', chunk => {

View File

@@ -170,6 +170,7 @@ export default function extract_css(client_result: CompileResult, components: Pa
} }
const main = client_result.assets.main; const main = client_result.assets.main;
if (process.env.SAPPER_LEGACY_BUILD) main = `legacy/${main}`;
const entry = fs.readFileSync(`${dirs.dest}/client/${main}`, 'utf-8'); const entry = fs.readFileSync(`${dirs.dest}/client/${main}`, 'utf-8');
const replacements = new Map(); const replacements = new Map();

View File

@@ -136,17 +136,17 @@ export default function middleware(opts: {
fs.existsSync(path.join(output, 'index.html')) && serve({ fs.existsSync(path.join(output, 'index.html')) && serve({
pathname: '/index.html', pathname: '/index.html',
cache_control: 'max-age=600' cache_control: dev() ? 'no-cache' : 'max-age=600'
}), }),
fs.existsSync(path.join(output, 'service-worker.js')) && serve({ fs.existsSync(path.join(output, 'service-worker.js')) && serve({
pathname: '/service-worker.js', pathname: '/service-worker.js',
cache_control: 'max-age=600' cache_control: 'no-cache, no-store, must-revalidate'
}), }),
fs.existsSync(path.join(output, 'service-worker.js.map')) && serve({ fs.existsSync(path.join(output, 'service-worker.js.map')) && serve({
pathname: '/service-worker.js.map', pathname: '/service-worker.js.map',
cache_control: 'max-age=600' cache_control: 'no-cache, no-store, must-revalidate'
}), }),
serve({ serve({
@@ -312,6 +312,7 @@ function get_page_handler(
} = get_build_info(); } = get_build_info();
res.setHeader('Content-Type', 'text/html'); res.setHeader('Content-Type', 'text/html');
res.setHeader('Cache-Control', dev() ? 'no-cache' : 'max-age=600');
// preload main.js and current route // preload main.js and current route
// TODO detect other stuff we can preload? images, CSS, fonts? // TODO detect other stuff we can preload? images, CSS, fonts?
@@ -524,9 +525,12 @@ function get_page_handler(
styles = (css && css.code ? `<style>${css.code}</style>` : ''); styles = (css && css.code ? `<style>${css.code}</style>` : '');
} }
// users can set a CSP nonce using res.locals.nonce
const nonce_attr = (res.locals && res.locals.nonce) ? ` nonce="${res.locals.nonce}"` : '';
const body = template() const body = template()
.replace('%sapper.base%', () => `<base href="${req.baseUrl}/">`) .replace('%sapper.base%', () => `<base href="${req.baseUrl}/">`)
.replace('%sapper.scripts%', () => `<script>${script}</script>`) .replace('%sapper.scripts%', () => `<script${nonce_attr}>${script}</script>`)
.replace('%sapper.html%', () => html) .replace('%sapper.html%', () => html)
.replace('%sapper.head%', () => `<noscript id='sapper-head-start'></noscript>${head}<noscript id='sapper-head-end'></noscript>`) .replace('%sapper.head%', () => `<noscript id='sapper-head-start'></noscript>${head}<noscript id='sapper-head-end'></noscript>`)
.replace('%sapper.styles%', () => styles); .replace('%sapper.styles%', () => styles);

View File

@@ -5,6 +5,7 @@ const Nightmare = require('nightmare');
const walkSync = require('walk-sync'); const walkSync = require('walk-sync');
const rimraf = require('rimraf'); const rimraf = require('rimraf');
const ports = require('port-authority'); const ports = require('port-authority');
const fetch = require('node-fetch');
Nightmare.action('page', { Nightmare.action('page', {
title(done) { title(done) {
@@ -800,15 +801,20 @@ function run({ mode, basepath = '' }) {
}); });
describe('headers', () => { describe('headers', () => {
it('sets Content-Type and Link...preload headers', () => { it('sets Content-Type, Link...preload, and Cache-Control headers', () => {
return capture(() => nightmare.goto(base)).then(requests => { return capture(() => fetch(base)).then(responses => {
const { headers } = requests[0]; const { headers } = responses[0];
assert.equal( assert.equal(
headers['content-type'], headers['content-type'],
'text/html' 'text/html'
); );
assert.equal(
headers['cache-control'],
'max-age=600'
);
const str = ['main', '.+?\\.\\d+'] const str = ['main', '.+?\\.\\d+']
.map(file => { .map(file => {
return `<${basepath}/client/[^/]+/${file}\\.js>;rel="preload";as="script"`; return `<${basepath}/client/[^/]+/${file}\\.js>;rel="preload";as="script"`;