Skip to content

Proposal: add preprocessor nesting #6031

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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
45 changes: 45 additions & 0 deletions site/content/docs/04-compile-time.md
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,51 @@ const { code } = await svelte.preprocess(source, [
});
```

An additional level of nesting allows more control over the timing of subsequent `markup` functions.

```js
const svelte = require('svelte/compiler');

const { code } = await svelte.preprocess(source, [
[
{
markup: () => {
console.log('this runs first');
},
script: () => {
console.log('this runs third');
},
style: () => {
console.log('this runs fifth');
}
},
{
markup: () => {
console.log('this runs second');
},
script: () => {
console.log('this runs fourth');
},
style: () => {
console.log('this runs sixth');
}
}
],
{
markup: () => {
console.log('this runs seventh');
},
script: () => {
console.log('this runs eighth');
},
style: () => {
console.log('this runs ninth');
}
}
], {
filename: 'App.svelte'
});
```

### `svelte.walk`

Expand Down
66 changes: 53 additions & 13 deletions src/compiler/preprocess/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -195,27 +195,51 @@ async function process_markup(filename: string, process: MarkupPreprocessor, sou
}
}

export default async function preprocess(
source: string,
preprocessor: PreprocessorGroup | PreprocessorGroup[],
options?: { filename?: string }
): Promise<Processed> {
// @ts-ignore todo: doublecheck
const filename = (options && options.filename) || preprocessor.filename; // legacy
function ensureArray<T>(x: T): T extends readonly any[] ? T : T[] {
// @ts-ignore
return Array.isArray(x)? x : [x];
}

const preprocessors = preprocessor ? (Array.isArray(preprocessor) ? preprocessor : [preprocessor]) : [];
function groupPreprocessors(preprocessorsIn: Array<PreprocessorGroup|PreprocessorGroup[]>): PreprocessorGroup[][] {
const preprocessors = { completed: [], building: [] };

const markup = preprocessors.map(p => p.markup).filter(Boolean);
const script = preprocessors.map(p => p.script).filter(Boolean);
const style = preprocessors.map(p => p.style).filter(Boolean);
function cleanUpBuilding() {
if (preprocessors.building.length) {
preprocessors.completed.push(preprocessors.building);
preprocessors.building = [];
}
}

const result = new PreprocessResult(source, filename);
for (const current of preprocessorsIn) {
if (Array.isArray(current)) {
cleanUpBuilding();
preprocessors.completed.push(current);
} else {
preprocessors.building.push(current);
}
}

cleanUpBuilding();

return preprocessors.completed;

}

async function preprocessGrouped<T extends PreprocessResult>(
result: T,
preprocessorGroup: PreprocessorGroup[]|PreprocessorGroup
): Promise<void> {
const preprocessors = ensureArray(preprocessorGroup);

const markup = preprocessors.map((p) => p.markup).filter(Boolean);
const script = preprocessors.map((p) => p.script).filter(Boolean);
const style = preprocessors.map((p) => p.style).filter(Boolean);

// TODO keep track: what preprocessor generated what sourcemap?
// to make debugging easier = detect low-resolution sourcemaps in fn combine_mappings

for (const process of markup) {
result.update_source(await process_markup(filename, process, result));
result.update_source(await process_markup(result.filename, process, result));
}

for (const process of script) {
Expand All @@ -226,5 +250,21 @@ export default async function preprocess(
result.update_source(await process_tag('style', preprocess, result));
}

return;
}

export default async function preprocess(
source: string,
preprocessor: PreprocessorGroup | Array<PreprocessorGroup | PreprocessorGroup[]> = [],
options?: { filename?: string }
): Promise<Processed> {
// @ts-ignore todo: doublecheck
const filename = (options && options.filename) || preprocessor.filename; // legacy
const result = new PreprocessResult(source, filename);

for (const preprocessorGrouping of groupPreprocessors(ensureArray(preprocessor))) {
await preprocessGrouped(result, preprocessorGrouping);
}

return result.to_processed();
}
37 changes: 37 additions & 0 deletions test/preprocess/samples/multiple-preprocessors-grouped/_config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
export default {
preprocess: [
[
{
markup: ({ content }) => ({ code: content.replace(/one/g, 'two') }),
script: ({ content }) => ({ code: content.replace(/three/g, 'four') }),
style: ({ content }) => ({ code: content.replace(/four/g, 'nine') })
},
{
markup: ({ content }) => ({ code: content.replace(/two/g, 'three') }),
script: ({ content }) => ({ code: content.replace(/four/g, 'five') }),
style: ({ content }) => ({ code: content.replace(/three/g, 'four') })
}
],
{
markup: ({ content }) => ({ code: content.replace(/three|four|five/g, 'reset-markup') }),
script: ({ content }) => ({ code: content.replace(/reset-markup/g, 'reset-script') }),
style: ({ content }) => ({ code: content.replace(/reset-markup/g, 'reset-style') })
},
[
{
markup: ({ content }) => ({
code: content
.replace(/reset-markup/, 'six')
.replace(/reset-style/, 'six')
.replace(/reset-script/, 'six') }),
script: ({ content }) => ({ code: content.replace(/seven/g, 'eight') }),
style: ({ content }) => ({ code: content.replace(/eight/g, 'nine') })
},
{
markup: ({ content }) => ({ code: content.replace(/six/g, 'seven') }),
script: ({ content }) => ({ code: content.replace(/eight/g, 'nine') }),
style: ({ content }) => ({ code: content.replace(/seven/g, 'eight') })
}
]
]
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<p>one</p>

<style>
.one {
color: red;
}
</style>

<script>
console.log('one');
</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<p>seven</p>

<style>
.eight {
color: red;
}
</style>

<script>
console.log('nine');
</script>