Skip to content
This repository was archived by the owner on Jan 11, 2023. It is now read-only.

TypeScript support: don't try to compile templates #1222

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@
"http-link-header": "^1.0.2",
"shimport": "^1.0.1",
"sourcemap-codec": "^1.4.6",
"string-hash": "^1.1.3"
"string-hash": "^1.1.3",
"tippex": "^3.0.0"
},
"devDependencies": {
"@types/mocha": "^5.2.7",
Expand Down
47 changes: 29 additions & 18 deletions src/core/create_manifest_data.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,26 @@
import * as fs from 'fs';
import * as path from 'path';
import svelte from 'svelte/compiler';
import * as tippex from 'tippex';
import { Page, PageComponent, ServerRoute, ManifestData } from '../interfaces';
import { posixify, reserved_words } from '../utils';

export function template_has_preload(content: string) {
const regex = /<script.*?context="module".*?>([^]*?)<\/script>/g;
let m;
while ((m = regex.exec(content)) !== null) {
// This is necessary to avoid infinite loops with zero-width matches
if (m.index === regex.lastIndex) {
regex.lastIndex++;
}

const source_minus_comments = tippex.erase(m[1]);
if (/export\s+.*?preload/.test(source_minus_comments)) {
return true;
}
}
return false;
}

export default function create_manifest_data(cwd: string, extensions: string = '.svelte .html'): ManifestData {

const component_extensions = extensions.split(' ');
Expand All @@ -13,30 +30,24 @@ export default function create_manifest_data(cwd: string, extensions: string = '
throw new Error(`As of Sapper 0.21, the routes/ directory should become src/routes/`);
}

function has_preload(file: string) {
const source = fs.readFileSync(path.join(cwd, file), 'utf-8');

if (/preload/.test(source)) {
try {
const { vars } = svelte.compile(source.replace(/<style\b[^>]*>[^]*?<\/style>/g, ''), { generate: false });
return vars.some((variable: any) => variable.module && variable.export_name === 'preload');
} catch (err) {}
}

return false;
function file_has_preload(file: string) {
const content = fs.readFileSync(path.join(cwd, file), 'utf-8');
return template_has_preload(content);
}

function find_layout(file_name: string, component_name: string, dir: string = '') {
const ext = component_extensions.find((ext) => fs.existsSync(path.join(cwd, dir, `${file_name}${ext}`)));
const file = posixify(path.join(dir, `${file_name}${ext}`))

return ext
? {
if (!ext) {
return null;
}

return {
name: component_name,
file: file,
has_preload: has_preload(file)
}
: null;
has_preload: file_has_preload(file)
};
}

const components: PageComponent[] = [];
Expand Down Expand Up @@ -162,7 +173,7 @@ export default function create_manifest_data(cwd: string, extensions: string = '
const component = {
name: get_slug(item.file),
file: item.file,
has_preload: has_preload(item.file)
has_preload: file_has_preload(item.file)
};

components.push(component);
Expand Down
61 changes: 60 additions & 1 deletion test/unit/create_manifest_data/test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,65 @@
import * as path from 'path';
import * as assert from 'assert';
import create_manifest_data from '../../../src/core/create_manifest_data';
import create_manifest_data, { template_has_preload } from '../../../src/core/create_manifest_data';

describe('template_has_preload', () => {
it('should detect async preload', () => {
const source = `
<script context="module">
export async function preload() {
const client = getClient();
let response = await client.query({ query: GET_POSTS });
let posts = response.data.getPosts;
return { posts };
}
</script>
`;
assert.ok(template_has_preload(source));
});

it('should detect preload in composed function', () => {
const source = `
<script context="module">
export const preload = verifyUser(catchErrors(function () { console.log('test'); }));
</script>
`;
assert.ok(template_has_preload(source));
});

it('should detect reusable preload functions', () => {
const source = `
<script context="module">
export { preload } from './userData'
</script>
`;
assert.ok(template_has_preload(source));
});

it('should not detect preload functions in single line comment', () => {
const source = `
<script context="module">
//export { preload } from './userData'
</script>
`;
assert.ok(!template_has_preload(source));
});

it('should not detect preload functions in comment block', () => {
const source = `
<script context="module">
/*
export async function preload() {
const client = getClient();
let response = await client.query({ query: GET_POSTS });
let posts = response.data.getPosts;
return { posts };
}
*/
</script>
`;
assert.ok(!template_has_preload(source));
});
});

describe('manifest_data', () => {
it('creates routes', () => {
Expand Down