diff --git a/src/core/create_compilers/extract_css.ts b/src/core/create_compilers/extract_css.ts
index e885154..a60d848 100644
--- a/src/core/create_compilers/extract_css.ts
+++ b/src/core/create_compilers/extract_css.ts
@@ -219,7 +219,7 @@ export default function extract_css(client_result: CompileResult, components: Pa
});
unclaimed.forEach(file => {
- entry_css_modules.push(css_map.get(file));
+ entry_css_modules.push(file);
});
const leftover = get_css_from_modules(entry_css_modules, css_map, dirs);
diff --git a/test/apps/css/rollup.config.js b/test/apps/css/rollup.config.js
new file mode 100644
index 0000000..943b676
--- /dev/null
+++ b/test/apps/css/rollup.config.js
@@ -0,0 +1,64 @@
+import resolve from 'rollup-plugin-node-resolve';
+import replace from 'rollup-plugin-replace';
+import svelte from 'rollup-plugin-svelte';
+
+const mode = process.env.NODE_ENV;
+const dev = mode === 'development';
+
+const config = require('../../../config/rollup.js');
+
+export default {
+ client: {
+ input: config.client.input(),
+ output: config.client.output(),
+ plugins: [
+ replace({
+ 'process.browser': true,
+ 'process.env.NODE_ENV': JSON.stringify(mode)
+ }),
+ svelte({
+ dev,
+ hydratable: true,
+ emitCss: true
+ }),
+ resolve()
+ ],
+
+ // temporary, pending Rollup 1.0
+ experimentalCodeSplitting: true
+ },
+
+ server: {
+ input: config.server.input(),
+ output: config.server.output(),
+ plugins: [
+ replace({
+ 'process.browser': false,
+ 'process.env.NODE_ENV': JSON.stringify(mode)
+ }),
+ svelte({
+ generate: 'ssr',
+ dev
+ }),
+ resolve({
+ preferBuiltins: true
+ })
+ ],
+ external: ['sirv', 'polka'],
+
+ // temporary, pending Rollup 1.0
+ experimentalCodeSplitting: true
+ },
+
+ serviceworker: {
+ input: config.serviceworker.input(),
+ output: config.serviceworker.output(),
+ plugins: [
+ resolve(),
+ replace({
+ 'process.browser': true,
+ 'process.env.NODE_ENV': JSON.stringify(mode)
+ })
+ ]
+ }
+};
\ No newline at end of file
diff --git a/test/apps/css/src/client.js b/test/apps/css/src/client.js
new file mode 100644
index 0000000..0865a4a
--- /dev/null
+++ b/test/apps/css/src/client.js
@@ -0,0 +1,9 @@
+import * as sapper from '../__sapper__/client.js';
+
+window.start = () => sapper.start({
+ target: document.querySelector('#sapper')
+});
+
+window.prefetchRoutes = () => sapper.prefetchRoutes();
+window.prefetch = href => sapper.prefetch(href);
+window.goto = href => sapper.goto(href);
\ No newline at end of file
diff --git a/test/apps/css/src/routes/_components/Title.html b/test/apps/css/src/routes/_components/Title.html
new file mode 100644
index 0000000..05cf195
--- /dev/null
+++ b/test/apps/css/src/routes/_components/Title.html
@@ -0,0 +1,7 @@
+
Title
+
+
\ No newline at end of file
diff --git a/test/apps/css/src/routes/_error.html b/test/apps/css/src/routes/_error.html
new file mode 100644
index 0000000..4cd55d2
--- /dev/null
+++ b/test/apps/css/src/routes/_error.html
@@ -0,0 +1,3 @@
+{status}
+
+{error.message}
\ No newline at end of file
diff --git a/test/apps/css/src/routes/bar.html b/test/apps/css/src/routes/bar.html
new file mode 100644
index 0000000..876ee63
--- /dev/null
+++ b/test/apps/css/src/routes/bar.html
@@ -0,0 +1,11 @@
+
+
+
\ No newline at end of file
diff --git a/test/apps/css/src/routes/foo.html b/test/apps/css/src/routes/foo.html
new file mode 100644
index 0000000..3aeeeeb
--- /dev/null
+++ b/test/apps/css/src/routes/foo.html
@@ -0,0 +1,7 @@
+Foo
+
+
\ No newline at end of file
diff --git a/test/apps/css/src/routes/index.html b/test/apps/css/src/routes/index.html
new file mode 100644
index 0000000..a9fd9fd
--- /dev/null
+++ b/test/apps/css/src/routes/index.html
@@ -0,0 +1,10 @@
+Great success!
+
+foo
+bar
+
+
\ No newline at end of file
diff --git a/test/apps/css/src/server.js b/test/apps/css/src/server.js
new file mode 100644
index 0000000..0e7741c
--- /dev/null
+++ b/test/apps/css/src/server.js
@@ -0,0 +1,8 @@
+import polka from 'polka';
+import * as sapper from '../__sapper__/server.js';
+
+const { PORT } = process.env;
+
+polka()
+ .use(sapper.middleware())
+ .listen(PORT);
diff --git a/test/apps/css/src/service-worker.js b/test/apps/css/src/service-worker.js
new file mode 100644
index 0000000..9d2ac9d
--- /dev/null
+++ b/test/apps/css/src/service-worker.js
@@ -0,0 +1,82 @@
+import { timestamp, files, shell, routes } from '../__sapper__/service-worker.js';
+
+const ASSETS = `cache${timestamp}`;
+
+// `shell` is an array of all the files generated by webpack,
+// `files` is an array of everything in the `static` directory
+const to_cache = shell.concat(ASSETS);
+const cached = new Set(to_cache);
+
+self.addEventListener('install', event => {
+ event.waitUntil(
+ caches
+ .open(ASSETS)
+ .then(cache => cache.addAll(to_cache))
+ .then(() => {
+ self.skipWaiting();
+ })
+ );
+});
+
+self.addEventListener('activate', event => {
+ event.waitUntil(
+ caches.keys().then(async keys => {
+ // delete old caches
+ for (const key of keys) {
+ if (key !== ASSETS) await caches.delete(key);
+ }
+
+ self.clients.claim();
+ })
+ );
+});
+
+self.addEventListener('fetch', event => {
+ if (event.request.method !== 'GET') return;
+
+ const url = new URL(event.request.url);
+
+ // don't try to handle e.g. data: URIs
+ if (!url.protocol.startsWith('http')) return;
+
+ // ignore dev server requests
+ if (url.hostname === self.location.hostname && url.port !== self.location.port) return;
+
+ // always serve assets and webpack-generated files from cache
+ if (url.host === self.location.host && cached.has(url.pathname)) {
+ event.respondWith(caches.match(event.request));
+ return;
+ }
+
+ // for pages, you might want to serve a shell `index.html` file,
+ // which Sapper has generated for you. It's not right for every
+ // app, but if it's right for yours then uncomment this section
+ /*
+ if (url.origin === self.origin && routes.find(route => route.pattern.test(url.pathname))) {
+ event.respondWith(caches.match('/index.html'));
+ return;
+ }
+ */
+
+ if (event.request.cache === 'only-if-cached') return;
+
+ // for everything else, try the network first, falling back to
+ // cache if the user is offline. (If the pages never change, you
+ // might prefer a cache-first approach to a network-first one.)
+ event.respondWith(
+ caches
+ .open(`offline${timestamp}`)
+ .then(async cache => {
+ try {
+ const response = await fetch(event.request);
+ cache.put(event.request, response.clone());
+ return response;
+ } catch(err) {
+ const response = await cache.match(event.request);
+ if (response) return response;
+
+ throw err;
+ }
+ })
+ );
+});
diff --git a/test/apps/css/src/template.html b/test/apps/css/src/template.html
new file mode 100644
index 0000000..0eb1f3b
--- /dev/null
+++ b/test/apps/css/src/template.html
@@ -0,0 +1,14 @@
+
+
+
+
+
+ %sapper.base%
+ %sapper.styles%
+ %sapper.head%
+
+
+ %sapper.html%
+ %sapper.scripts%
+
+
diff --git a/test/apps/css/test.ts b/test/apps/css/test.ts
new file mode 100644
index 0000000..c6539af
--- /dev/null
+++ b/test/apps/css/test.ts
@@ -0,0 +1,78 @@
+import * as assert from 'assert';
+import * as puppeteer from 'puppeteer';
+import { build } from '../../../api';
+import { AppRunner } from '../AppRunner';
+import { wait } from '../../utils';
+
+describe('css', function() {
+ this.timeout(10000);
+
+ let runner: AppRunner;
+ let page: puppeteer.Page;
+ let base: string;
+
+ // helpers
+ let start: () => Promise;
+ let prefetchRoutes: () => Promise;
+ let prefetch: (href: string) => Promise;
+ let goto: (href: string) => Promise;
+ let title: () => Promise;
+
+ // hooks
+ before(async () => {
+ await build({ cwd: __dirname });
+
+ runner = new AppRunner(__dirname, '__sapper__/build/server/server.js');
+ ({ base, page, start, prefetchRoutes, prefetch, goto, title } = await runner.start());
+ });
+
+ after(() => runner.end());
+
+ it('includes critical CSS with server render', async () => {
+ await page.goto(base);
+
+ assert.equal(
+ await page.evaluate(() => {
+ const h1 = document.querySelector('h1');
+ return getComputedStyle(h1).color;
+ }),
+ 'rgb(255, 0, 0)'
+ );
+ });
+
+ it('loads CSS when navigating client-side', async () => {
+ await page.goto(base);
+
+ await start();
+ await prefetchRoutes();
+
+ await page.click(`[href="foo"]`);
+ await wait(50);
+
+ assert.equal(
+ await page.evaluate(() => {
+ const h1 = document.querySelector('h1');
+ return getComputedStyle(h1).color;
+ }),
+ 'rgb(0, 0, 255)'
+ );
+ });
+
+ it('loads CSS for a lazily-rendered component', async () => {
+ await page.goto(base);
+
+ await start();
+ await prefetchRoutes();
+
+ await page.click(`[href="bar"]`);
+ await wait(50);
+
+ assert.equal(
+ await page.evaluate(() => {
+ const h1 = document.querySelector('h1');
+ return getComputedStyle(h1).color;
+ }),
+ 'rgb(0, 128, 0)'
+ );
+ });
+});
\ No newline at end of file