Skip to content

Commit

Permalink
Watch previous files if preprocessing failed
Browse files Browse the repository at this point in the history
  • Loading branch information
Maximiliano Ruani committed Jun 1, 2022
1 parent 6968e89 commit 9ec1e56
Show file tree
Hide file tree
Showing 5 changed files with 112 additions and 8 deletions.
32 changes: 24 additions & 8 deletions index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,11 +129,14 @@ export default function sveltePlugin(options?: esbuildSvelteOptions): Plugin {

//main loader
build.onLoad({ filter: svelteFilter }, async (args) => {
let cachedFile = null;
let previousWatchFiles: string[] = [];

// if told to use the cache, check if it contains the file,
// and if the modified time is not greater than the time when it was cached
// if so, return the cached data
if (options?.cache === true && fileCache.has(args.path)) {
const cachedFile = fileCache.get(args.path) || {
cachedFile = fileCache.get(args.path) || {
dependencies: new Map(),
data: null,
}; // should never hit the null b/c of has check
Expand Down Expand Up @@ -177,13 +180,26 @@ export default function sveltePlugin(options?: esbuildSvelteOptions): Plugin {

//do preprocessor stuff if it exists
if (options?.preprocess) {
let preprocessResult = await preprocess(
originalSource,
options.preprocess,
{
filename,
let preprocessResult = null;

try {
preprocessResult = await preprocess(
originalSource,
options.preprocess,
{
filename,
}
);
}
catch(e: any) {
// if preprocess failed there are chances that an external dependency caused exception
// to avoid stop watching those files, we keep the previous dependencies if available
if (build.initialOptions.watch && cachedFile) {
previousWatchFiles = Array.from(cachedFile.dependencies.keys());
}
);
throw e;
}

if (preprocessResult.map) {
// normalize the sourcemap 'source' entrys to all match if they are the same file
// needed because of differing handling of file names in preprocessors
Expand Down Expand Up @@ -262,7 +278,7 @@ export default function sveltePlugin(options?: esbuildSvelteOptions): Plugin {

return result;
} catch (e: any) {
return { errors: [convertMessage(e)] };
return { errors: [convertMessage(e)], watchFiles: previousWatchFiles };
}
});

Expand Down
5 changes: 5 additions & 0 deletions test/fixtures/watch-preprocessing/entry.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import Test from "./external-styles.svelte";

new Test({
target: document.body,
});
7 changes: 7 additions & 0 deletions test/fixtures/watch-preprocessing/external-styles.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<style lang="scss">
@import "./external.scss";
</style>

<div>
<h1>Hello World</h1>
</div>
1 change: 1 addition & 0 deletions test/fixtures/watch-preprocessing/external.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
p { color: red; }
75 changes: 75 additions & 0 deletions test/watchPreprocessingTest.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { test } from "uvu";
import * as assert from "uvu/assert";
import { writeFileSync } from "fs";
import { fileURLToPath } from "url";
import { dirname } from "path";
import { build as _build } from "esbuild";
import { sass } from "svelte-preprocess-sass";
import sveltePlugin from "../dist/index.mjs";

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);

test("Watch and build while preprocess of external dependency succeed and fails", async () => {

function _createDeferred() {
let resolve = null;
let reject = null;
const promise = new Promise((_resolve, _reject) => {
resolve = _resolve;
reject = _reject;
});
promise.forceResolve = resolve;
promise.forceReject = reject;
return promise;
}

let count = 0;
const firstRebuild = _createDeferred();
const secondRebuild = _createDeferred();

//more advanced
const results = await _build({
entryPoints: ["./test/fixtures/watch-preprocessing/entry.js"],
outdir: "../example/dist",
format: "esm",
minify: true,
bundle: true,
splitting: true,
write: false, //Don't write anywhere
sourcemap: "inline",
plugins: [
sveltePlugin({
preprocess: {
style: sass(),
},
}),
],
watch: {
onRebuild(err, result) {
count++;
if (count === 1) {
firstRebuild.forceResolve(err);
}
else if (count === 2) {
secondRebuild.forceResolve(result);
}
},
},
});

// write external scss with invalid syntax
writeFileSync(`${__dirname}/fixtures/watch-preprocessing/external.scss`, 'p { color: red; }!$%^&*()@$%^@@');
const firstRebuildResult = await firstRebuild;
assert.ok(firstRebuildResult instanceof Error, 'First build did not fail');

// write external scss with valid syntax again
writeFileSync(`${__dirname}/fixtures/watch-preprocessing/external.scss`, 'p { color: red; }');
const secondRebuildResult = await secondRebuild;
assert.ok(secondRebuildResult.errors.length === 0, "Second build fail");

// stop watching
results.stop();
});

test.run();

0 comments on commit 9ec1e56

Please sign in to comment.