summaryrefslogtreecommitdiff
path: root/scripts/utils/svelte-plugin.js
blob: f8a30ff33aae91f907b291e8e101e6e12e51c3e8 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
// @ts-nocheck
import { compile } from 'svelte/compiler';
import { relative, isAbsolute, join, dirname } from 'path';
import { promises as fs } from 'fs';

const convertMessage = ({ message, start, end, filename, frame }) => ({
  text: message,
  location: start &&
    end && {
      file: filename,
      line: start.line,
      column: start.column,
      length: start.line === end.line ? end.column - start.column : 0,
      lineText: frame,
    },
});

const handleLoad = async (args, generate, { isDev }) => {
  const { path } = args;
  const source = await fs.readFile(path, 'utf8');
  const filename = relative(process.cwd(), path);

  try {
    let compileOptions = { dev: isDev, css: false, generate, hydratable: true };

    let { js, warnings } = compile(source, { ...compileOptions, filename });
    let contents = js.code + `\n//# sourceMappingURL=` + js.map.toUrl();

    return { loader: 'js', contents, resolveDir: dirname(path), warnings: warnings.map((w) => convertMessage(w)) };
  } catch (e) {
    return { errors: [convertMessage(e)] };
  }
};

export default function sveltePlugin({ isDev = false }) {
  return {
    name: 'svelte-esbuild',
    setup(build) {
      build.onResolve({ filter: /\.svelte$/ }, (args) => {
        let path = args.path.replace(/\.(?:client|server)/, '');
        path = isAbsolute(path) ? path : join(args.resolveDir, path);

        if (/\.client\.svelte$/.test(args.path)) {
          return {
            path,
            namespace: 'svelte:client',
          };
        }

        if (/\.server\.svelte$/.test(args.path)) {
          return {
            path,
            namespace: 'svelte:server',
          };
        }
      });
      build.onLoad({ filter: /.*/, namespace: 'svelte:client' }, (args) => handleLoad(args, 'dom', { isDev }));
      build.onLoad({ filter: /.*/, namespace: 'svelte:server' }, (args) => handleLoad(args, 'ssr', { isDev }));
    },
  };
}