mirror of
https://github.com/kevin-DL/sapper.git
synced 2026-01-15 04:14:46 +00:00
Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cb45bb0fbe | ||
|
|
f39455014a | ||
|
|
4fe8df3696 | ||
|
|
44736754ad | ||
|
|
1b9b559d82 |
@@ -1,5 +1,9 @@
|
|||||||
# sapper changelog
|
# sapper changelog
|
||||||
|
|
||||||
|
## 0.23.2
|
||||||
|
|
||||||
|
* Fix entry point CSS ([#471](https://github.com/sveltejs/sapper/pull/471))
|
||||||
|
|
||||||
## 0.23.1
|
## 0.23.1
|
||||||
|
|
||||||
* Scroll to deeplink that matches current URL ([#472](https://github.com/sveltejs/sapper/pull/472))
|
* Scroll to deeplink that matches current URL ([#472](https://github.com/sveltejs/sapper/pull/472))
|
||||||
|
|||||||
1059
package-lock.json
generated
1059
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
46
package.json
46
package.json
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "sapper",
|
"name": "sapper",
|
||||||
"version": "0.23.1",
|
"version": "0.23.2",
|
||||||
"description": "Military-grade apps, engineered by Svelte",
|
"description": "Military-grade apps, engineered by Svelte",
|
||||||
"bin": {
|
"bin": {
|
||||||
"sapper": "./sapper"
|
"sapper": "./sapper"
|
||||||
@@ -17,53 +17,53 @@
|
|||||||
"test": "test"
|
"test": "test"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"html-minifier": "^3.5.16",
|
"html-minifier": "^3.5.20",
|
||||||
"shimport": "0.0.11",
|
"shimport": "0.0.11",
|
||||||
"source-map-support": "^0.5.6",
|
"source-map-support": "^0.5.9",
|
||||||
"sourcemap-codec": "^1.4.1",
|
"sourcemap-codec": "^1.4.3",
|
||||||
"string-hash": "^1.1.3",
|
"string-hash": "^1.1.3",
|
||||||
"tslib": "^1.9.1"
|
"tslib": "^1.9.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/mkdirp": "^0.5.2",
|
"@types/mkdirp": "^0.5.2",
|
||||||
"@types/mocha": "^5.2.5",
|
"@types/mocha": "^5.2.5",
|
||||||
"@types/node": "^10.7.1",
|
"@types/node": "^10.12.0",
|
||||||
"@types/puppeteer": "^1.9.0",
|
"@types/puppeteer": "^1.9.0",
|
||||||
"@types/rimraf": "^2.0.2",
|
"@types/rimraf": "^2.0.2",
|
||||||
"agadoo": "^1.0.1",
|
"agadoo": "^1.0.1",
|
||||||
"cheap-watch": "^0.3.0",
|
"cheap-watch": "^1.0.0",
|
||||||
"cookie": "^0.3.1",
|
"cookie": "^0.3.1",
|
||||||
"devalue": "^1.0.4",
|
"devalue": "^1.0.4",
|
||||||
"eslint": "^4.13.1",
|
"eslint": "^5.7.0",
|
||||||
"eslint-plugin-import": "^2.12.0",
|
"eslint-plugin-import": "^2.14.0",
|
||||||
"kleur": "^2.0.1",
|
"kleur": "^2.0.2",
|
||||||
"mkdirp": "^0.5.1",
|
"mkdirp": "^0.5.1",
|
||||||
"mocha": "^5.2.0",
|
"mocha": "^5.2.0",
|
||||||
"node-fetch": "^2.1.1",
|
"node-fetch": "^2.2.0",
|
||||||
"npm-run-all": "^4.1.3",
|
"npm-run-all": "^4.1.3",
|
||||||
"polka": "^0.4.0",
|
"polka": "^0.5.1",
|
||||||
"port-authority": "^1.0.5",
|
"port-authority": "^1.0.5",
|
||||||
"pretty-bytes": "^5.0.0",
|
"pretty-bytes": "^5.1.0",
|
||||||
"puppeteer": "^1.9.0",
|
"puppeteer": "^1.9.0",
|
||||||
"require-relative": "^0.8.7",
|
"require-relative": "^0.8.7",
|
||||||
"rimraf": "^2.6.2",
|
"rimraf": "^2.6.2",
|
||||||
"rollup": "^0.65.0",
|
"rollup": "^0.66.6",
|
||||||
"rollup-plugin-commonjs": "^9.1.3",
|
"rollup-plugin-commonjs": "^9.2.0",
|
||||||
"rollup-plugin-json": "^3.0.0",
|
"rollup-plugin-json": "^3.1.0",
|
||||||
"rollup-plugin-node-resolve": "^3.4.0",
|
"rollup-plugin-node-resolve": "^3.4.0",
|
||||||
"rollup-plugin-replace": "^2.0.0",
|
"rollup-plugin-replace": "^2.1.0",
|
||||||
"rollup-plugin-string": "^2.0.2",
|
"rollup-plugin-string": "^2.0.2",
|
||||||
"rollup-plugin-svelte": "^4.3.2",
|
"rollup-plugin-svelte": "^4.3.2",
|
||||||
"rollup-plugin-typescript": "^0.8.1",
|
"rollup-plugin-typescript": "^1.0.0",
|
||||||
"sade": "^1.4.1",
|
"sade": "^1.4.1",
|
||||||
"sander": "^0.6.0",
|
"sander": "^0.6.0",
|
||||||
"sirv": "^0.2.2",
|
"sirv": "^0.2.2",
|
||||||
"svelte": "^2.6.3",
|
"svelte": "^2.13.5",
|
||||||
"svelte-loader": "^2.9.0",
|
"svelte-loader": "^2.11.0",
|
||||||
"ts-node": "^7.0.1",
|
"ts-node": "^7.0.1",
|
||||||
"typescript": "^2.8.3",
|
"typescript": "^3.1.3",
|
||||||
"webpack": "^4.8.3",
|
"webpack": "^4.20.2",
|
||||||
"webpack-format-messages": "^2.0.1"
|
"webpack-format-messages": "^2.0.3"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "mocha --opts mocha.opts",
|
"test": "mocha --opts mocha.opts",
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import * as path from 'path';
|
|||||||
import hash from 'string-hash';
|
import hash from 'string-hash';
|
||||||
import * as codec from 'sourcemap-codec';
|
import * as codec from 'sourcemap-codec';
|
||||||
import { PageComponent, Dirs } from '../../interfaces';
|
import { PageComponent, Dirs } from '../../interfaces';
|
||||||
import { CompileResult } from './interfaces';
|
import { CompileResult, Chunk } from './interfaces';
|
||||||
import { posixify } from '../../utils'
|
import { posixify } from '../../utils'
|
||||||
|
|
||||||
const inline_sourcemap_header = 'data:application/json;charset=utf-8;base64,';
|
const inline_sourcemap_header = 'data:application/json;charset=utf-8;base64,';
|
||||||
@@ -46,6 +46,65 @@ type SourceMap = {
|
|||||||
mappings: string;
|
mappings: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function get_css_from_modules(modules: string[], css_map: Map<string, string>, dirs: Dirs) {
|
||||||
|
const parts: string[] = [];
|
||||||
|
const mappings: number[][][] = [];
|
||||||
|
|
||||||
|
const combined_map: SourceMap = {
|
||||||
|
version: 3,
|
||||||
|
file: null,
|
||||||
|
sources: [],
|
||||||
|
sourcesContent: [],
|
||||||
|
names: [],
|
||||||
|
mappings: null
|
||||||
|
};
|
||||||
|
|
||||||
|
modules.forEach(module => {
|
||||||
|
if (!/\.css$/.test(module)) return;
|
||||||
|
|
||||||
|
const css = css_map.get(module);
|
||||||
|
|
||||||
|
const { code, map } = extract_sourcemap(css, module);
|
||||||
|
|
||||||
|
parts.push(code);
|
||||||
|
|
||||||
|
if (map) {
|
||||||
|
const lines = codec.decode(map.mappings);
|
||||||
|
|
||||||
|
if (combined_map.sources.length > 0 || combined_map.names.length > 0) {
|
||||||
|
lines.forEach(line => {
|
||||||
|
line.forEach(segment => {
|
||||||
|
// adjust source index
|
||||||
|
segment[1] += combined_map.sources.length;
|
||||||
|
|
||||||
|
// adjust name index
|
||||||
|
if (segment[4]) segment[4] += combined_map.names.length;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
combined_map.sources.push(...map.sources);
|
||||||
|
combined_map.sourcesContent.push(...map.sourcesContent);
|
||||||
|
combined_map.names.push(...map.names);
|
||||||
|
|
||||||
|
mappings.push(...lines);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (parts.length > 0) {
|
||||||
|
combined_map.mappings = codec.encode(mappings);
|
||||||
|
|
||||||
|
combined_map.sources = combined_map.sources.map(source => path.relative(`${dirs.dest}/client`, source));
|
||||||
|
|
||||||
|
return {
|
||||||
|
code: parts.join('\n'),
|
||||||
|
map: combined_map
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
export default function extract_css(client_result: CompileResult, components: PageComponent[], dirs: Dirs) {
|
export default function extract_css(client_result: CompileResult, components: PageComponent[], dirs: Dirs) {
|
||||||
const result: {
|
const result: {
|
||||||
main: string | null;
|
main: string | null;
|
||||||
@@ -57,151 +116,94 @@ export default function extract_css(client_result: CompileResult, components: Pa
|
|||||||
|
|
||||||
if (!client_result.css_files) return; // Rollup-only for now
|
if (!client_result.css_files) return; // Rollup-only for now
|
||||||
|
|
||||||
const unaccounted_for = new Set();
|
let asset_dir = `${dirs.dest}/client`;
|
||||||
|
if (process.env.SAPPER_LEGACY_BUILD) asset_dir += '/legacy';
|
||||||
|
|
||||||
const css_map = new Map();
|
const unclaimed = new Set(client_result.css_files.map(x => x.id));
|
||||||
client_result.css_files.forEach(css => {
|
|
||||||
unaccounted_for.add(css.id);
|
const lookup = new Map();
|
||||||
css_map.set(css.id, css.code);
|
client_result.chunks.forEach(chunk => {
|
||||||
|
lookup.set(chunk.file, chunk);
|
||||||
});
|
});
|
||||||
|
|
||||||
const chunk_map = new Map();
|
const css_map = new Map();
|
||||||
client_result.chunks.forEach(chunk => {
|
client_result.css_files.forEach(css_module => {
|
||||||
chunk_map.set(chunk.file, chunk);
|
css_map.set(css_module.id, css_module.code);
|
||||||
});
|
});
|
||||||
|
|
||||||
const chunks_with_css = new Set();
|
const chunks_with_css = new Set();
|
||||||
|
|
||||||
// figure out which chunks belong to which components...
|
// concatenate and emit CSS
|
||||||
const component_owners = new Map();
|
|
||||||
client_result.chunks.forEach(chunk => {
|
client_result.chunks.forEach(chunk => {
|
||||||
chunk.modules.forEach(module => {
|
const css_modules = chunk.modules.filter(m => css_map.has(m));
|
||||||
const component = posixify(path.relative(dirs.routes, module));
|
if (!css_modules.length) return;
|
||||||
component_owners.set(component, chunk);
|
|
||||||
});
|
const css = get_css_from_modules(css_modules, css_map, dirs);
|
||||||
|
|
||||||
|
const { code, map } = css;
|
||||||
|
|
||||||
|
const output_file_name = chunk.file.replace(/\.js$/, '.css');
|
||||||
|
|
||||||
|
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=./${output_file_name}.map */`);
|
||||||
|
fs.writeFileSync(`${asset_dir}/${output_file_name}.map`, JSON.stringify(map, null, ' '));
|
||||||
|
|
||||||
|
chunks_with_css.add(chunk);
|
||||||
});
|
});
|
||||||
|
|
||||||
const chunks_depended_upon_by_component = new Map();
|
const entry = path.resolve(dirs.src, 'client.js');
|
||||||
|
const entry_chunk = client_result.chunks.find(chunk => chunk.modules.indexOf(entry) !== -1);
|
||||||
|
|
||||||
// ...so we can figure out which chunks don't belong
|
const entry_chunk_dependencies: Set<Chunk> = new Set([entry_chunk]);
|
||||||
|
const entry_css_modules: string[] = [];
|
||||||
|
|
||||||
|
// recursively find the chunks this component depends on
|
||||||
|
entry_chunk_dependencies.forEach(chunk => {
|
||||||
|
chunk.imports.forEach(file => {
|
||||||
|
entry_chunk_dependencies.add(lookup.get(file));
|
||||||
|
});
|
||||||
|
|
||||||
|
if (chunks_with_css.has(chunk)) {
|
||||||
|
chunk.modules.forEach(file => {
|
||||||
|
unclaimed.delete(file);
|
||||||
|
if (css_map.has(file)) {
|
||||||
|
entry_css_modules.push(file);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// figure out which (css-having) chunks each component depends on
|
||||||
components.forEach(component => {
|
components.forEach(component => {
|
||||||
const chunk = component_owners.get(component.file);
|
const resolved = path.resolve(dirs.routes, component.file);
|
||||||
|
const chunk: Chunk = client_result.chunks.find(chunk => chunk.modules.indexOf(resolved) !== -1);
|
||||||
|
|
||||||
if (!chunk) {
|
if (!chunk) {
|
||||||
// this should never happen!
|
// this should never happen!
|
||||||
throw new Error(`Could not find chunk that owns ${component.file}`);
|
throw new Error(`Could not find chunk that owns ${component.file}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const chunks = new Set([chunk]);
|
const chunk_dependencies: Set<Chunk> = new Set([chunk]);
|
||||||
chunks.forEach(chunk => {
|
const css_dependencies: string[] = [];
|
||||||
chunk.imports.forEach((file: string) => {
|
|
||||||
const chunk = chunk_map.get(file);
|
// recursively find the chunks this component depends on
|
||||||
if (chunk) chunks.add(chunk);
|
chunk_dependencies.forEach(chunk => {
|
||||||
|
chunk.imports.forEach(file => {
|
||||||
|
chunk_dependencies.add(lookup.get(file));
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
|
||||||
chunks.forEach(chunk => {
|
if (chunks_with_css.has(chunk)) {
|
||||||
chunk.modules.forEach((module: string) => {
|
css_dependencies.push(chunk.file.replace(/\.js$/, '.css'));
|
||||||
unaccounted_for.delete(module);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
chunks_depended_upon_by_component.set(
|
chunk.modules.forEach(file => {
|
||||||
component,
|
unclaimed.delete(file);
|
||||||
chunks
|
});
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
function get_css_from_modules(modules: string[]) {
|
|
||||||
const parts: string[] = [];
|
|
||||||
const mappings: number[][][] = [];
|
|
||||||
|
|
||||||
const combined_map: SourceMap = {
|
|
||||||
version: 3,
|
|
||||||
file: null,
|
|
||||||
sources: [],
|
|
||||||
sourcesContent: [],
|
|
||||||
names: [],
|
|
||||||
mappings: null
|
|
||||||
};
|
|
||||||
|
|
||||||
modules.forEach(module => {
|
|
||||||
if (!/\.css$/.test(module)) return;
|
|
||||||
|
|
||||||
const css = css_map.get(module);
|
|
||||||
|
|
||||||
const { code, map } = extract_sourcemap(css, module);
|
|
||||||
|
|
||||||
parts.push(code);
|
|
||||||
|
|
||||||
if (map) {
|
|
||||||
const lines = codec.decode(map.mappings);
|
|
||||||
|
|
||||||
if (combined_map.sources.length > 0 || combined_map.names.length > 0) {
|
|
||||||
lines.forEach(line => {
|
|
||||||
line.forEach(segment => {
|
|
||||||
// adjust source index
|
|
||||||
segment[1] += combined_map.sources.length;
|
|
||||||
|
|
||||||
// adjust name index
|
|
||||||
if (segment[4]) segment[4] += combined_map.names.length;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
combined_map.sources.push(...map.sources);
|
|
||||||
combined_map.sourcesContent.push(...map.sourcesContent);
|
|
||||||
combined_map.names.push(...map.names);
|
|
||||||
|
|
||||||
mappings.push(...lines);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (parts.length > 0) {
|
result.chunks[component.file] = css_dependencies;
|
||||||
combined_map.mappings = codec.encode(mappings);
|
|
||||||
|
|
||||||
combined_map.sources = combined_map.sources.map(source => path.relative(`${dirs.dest}/client`, source));
|
|
||||||
|
|
||||||
return {
|
|
||||||
code: parts.join('\n'),
|
|
||||||
map: combined_map
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
let asset_dir = `${dirs.dest}/client`;
|
|
||||||
if (process.env.SAPPER_LEGACY_BUILD) asset_dir += '/legacy';
|
|
||||||
|
|
||||||
const replacements = new Map();
|
|
||||||
|
|
||||||
chunks_depended_upon_by_component.forEach((chunks, component) => {
|
|
||||||
const chunks_with_css = Array.from(chunks).filter(chunk => {
|
|
||||||
const css = get_css_from_modules(chunk.modules);
|
|
||||||
|
|
||||||
if (css) {
|
|
||||||
const { code, map } = css;
|
|
||||||
|
|
||||||
const output_file_name = chunk.file.replace(/\.js$/, '.css');
|
|
||||||
|
|
||||||
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=./${output_file_name}.map */`);
|
|
||||||
fs.writeFileSync(`${asset_dir}/${output_file_name}.map`, JSON.stringify(map, null, ' '));
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const files = chunks_with_css.map(chunk => chunk.file.replace(/\.js$/, '.css'));
|
|
||||||
|
|
||||||
replacements.set(
|
|
||||||
component.file,
|
|
||||||
files
|
|
||||||
);
|
|
||||||
|
|
||||||
result.chunks[component.file] = files;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
fs.readdirSync(asset_dir).forEach(file => {
|
fs.readdirSync(asset_dir).forEach(file => {
|
||||||
@@ -210,13 +212,17 @@ export default function extract_css(client_result: CompileResult, components: Pa
|
|||||||
const source = fs.readFileSync(`${asset_dir}/${file}`, 'utf-8');
|
const source = fs.readFileSync(`${asset_dir}/${file}`, 'utf-8');
|
||||||
|
|
||||||
const replaced = source.replace(/["']__SAPPER_CSS_PLACEHOLDER:(.+?)__["']/g, (m, route) => {
|
const replaced = source.replace(/["']__SAPPER_CSS_PLACEHOLDER:(.+?)__["']/g, (m, route) => {
|
||||||
return JSON.stringify(replacements.get(route));
|
return JSON.stringify(result.chunks[route]);
|
||||||
});
|
});
|
||||||
|
|
||||||
fs.writeFileSync(`${asset_dir}/${file}`, replaced);
|
fs.writeFileSync(`${asset_dir}/${file}`, replaced);
|
||||||
});
|
});
|
||||||
|
|
||||||
const leftover = get_css_from_modules(Array.from(unaccounted_for));
|
unclaimed.forEach(file => {
|
||||||
|
entry_css_modules.push(css_map.get(file));
|
||||||
|
});
|
||||||
|
|
||||||
|
const leftover = get_css_from_modules(entry_css_modules, css_map, dirs);
|
||||||
if (leftover) {
|
if (leftover) {
|
||||||
const { code, map } = leftover;
|
const { code, map } = leftover;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user