From 35e7039843834b966fb84a5addf9452fa829922a Mon Sep 17 00:00:00 2001 From: bluwy Date: Wed, 2 Nov 2022 23:04:23 +0800 Subject: [PATCH 1/5] feat: export vite preprocessors --- .../preprocess-with-vite/svelte.config.js | 6 ++ .../preprocess-with-vite/vite.config.js | 8 +- packages/vite-plugin-svelte/package.json | 6 +- packages/vite-plugin-svelte/src/preprocess.ts | 89 +++++++++++++++++++ .../src/utils/preprocess.ts | 78 ++-------------- 5 files changed, 106 insertions(+), 81 deletions(-) create mode 100644 packages/e2e-tests/preprocess-with-vite/svelte.config.js create mode 100644 packages/vite-plugin-svelte/src/preprocess.ts diff --git a/packages/e2e-tests/preprocess-with-vite/svelte.config.js b/packages/e2e-tests/preprocess-with-vite/svelte.config.js new file mode 100644 index 000000000..689f9194f --- /dev/null +++ b/packages/e2e-tests/preprocess-with-vite/svelte.config.js @@ -0,0 +1,6 @@ +// eslint-disable-next-line node/no-missing-require +const { viteScript, viteStyle } = require('@sveltejs/vite-plugin-svelte/preprocess'); + +module.exports = { + preprocess: [viteScript(), viteStyle()] +}; diff --git a/packages/e2e-tests/preprocess-with-vite/vite.config.js b/packages/e2e-tests/preprocess-with-vite/vite.config.js index 5248779a5..3f658aba4 100644 --- a/packages/e2e-tests/preprocess-with-vite/vite.config.js +++ b/packages/e2e-tests/preprocess-with-vite/vite.config.js @@ -4,13 +4,7 @@ const { defineConfig } = require('vite'); module.exports = defineConfig(({ command, mode }) => { const isProduction = mode === 'production'; return { - plugins: [ - svelte({ - experimental: { - useVitePreprocess: true - } - }) - ], + plugins: [svelte()], build: { minify: isProduction } diff --git a/packages/vite-plugin-svelte/package.json b/packages/vite-plugin-svelte/package.json index 1104ae916..12397dbac 100644 --- a/packages/vite-plugin-svelte/package.json +++ b/packages/vite-plugin-svelte/package.json @@ -19,12 +19,16 @@ "import": "./dist/index.js", "require": "./dist/index.cjs" }, + "./preprocess": { + "import": "./dist/preprocess.js", + "require": "./dist/preprocess.cjs" + }, "./package.json": "./package.json", "./src/ui/*": "./src/ui/*" }, "scripts": { "dev": "pnpm build:ci --sourcemap --watch src", - "build:ci": "rimraf dist && tsup-node src/index.ts --format esm,cjs --no-splitting --shims", + "build:ci": "rimraf dist && tsup-node src/index.ts src/preprocess.ts --format esm,cjs --no-splitting --shims", "build": "pnpm build:ci --dts --sourcemap" }, "engines": { diff --git a/packages/vite-plugin-svelte/src/preprocess.ts b/packages/vite-plugin-svelte/src/preprocess.ts new file mode 100644 index 000000000..68abfd4be --- /dev/null +++ b/packages/vite-plugin-svelte/src/preprocess.ts @@ -0,0 +1,89 @@ +import path from 'path'; +import * as vite from 'vite'; +import type { ESBuildOptions, ResolvedConfig } from 'vite'; +// eslint-disable-next-line node/no-missing-import +import type { Preprocessor } from 'svelte/types/compiler/preprocess'; + +const supportedStyleLangs = ['css', 'less', 'sass', 'scss', 'styl', 'stylus', 'postcss', 'sss']; + +const supportedScriptLangs = ['ts']; + +export function viteScript(): { script: Preprocessor } { + return { + async script({ attributes, content, filename = '' }) { + const lang = attributes.lang as string; + if (!supportedScriptLangs.includes(lang)) return; + const transformResult = await vite.transformWithEsbuild(content, filename, { + loader: lang as ESBuildOptions['loader'], + target: 'esnext', + tsconfigRaw: { + compilerOptions: { + // svelte typescript needs this flag to work with type imports + importsNotUsedAsValues: 'preserve', + preserveValueImports: true + } + } + }); + return { + code: transformResult.code, + map: transformResult.map + }; + } + }; +} + +export function viteStyle(config: vite.InlineConfig | vite.ResolvedConfig = {}): { + style: Preprocessor; +} { + let transform: CssTransform; + return { + async style({ attributes, content, filename = '' }) { + if (!transform) { + const resolvedConfig = isResolvedConfig(config) + ? config + : await vite.resolveConfig(config, 'build'); + transform = getCssTransformFn(resolvedConfig); + } + const lang = attributes.lang as string; + if (!supportedStyleLangs.includes(lang)) return; + const moduleId = `${filename}.${lang}`; + const result = await transform(content, moduleId); + // patch sourcemap source to point back to original filename + if (result.map?.sources?.[0] === moduleId) { + result.map.sources[0] = path.basename(filename); + } + return { + code: result.code, + map: result.map ?? undefined + }; + } + }; +} + +// eslint-disable-next-line no-unused-vars +type CssTransform = (code: string, filename: string) => Promise<{ code: string; map?: any }>; + +function getCssTransformFn(config: ResolvedConfig): CssTransform { + // API is only available in Vite 3.2 and above + // TODO: Remove Vite plugin hack when bump peer dep to Vite 3.2 + if (vite.preprocessCSS) { + return async (code, filename) => { + return vite.preprocessCSS(code, filename, config); + }; + } else { + const pluginName = 'vite:css'; + const plugin = config.plugins.find((p) => p.name === pluginName); + if (!plugin) { + throw new Error(`failed to find plugin ${pluginName}`); + } + if (!plugin.transform) { + throw new Error(`plugin ${pluginName} has no transform`); + } + // @ts-expect-error + return plugin.transform.bind(null); + } +} + +function isResolvedConfig(config: any): config is vite.ResolvedConfig { + return !!config.inlineConfig; +} diff --git a/packages/vite-plugin-svelte/src/utils/preprocess.ts b/packages/vite-plugin-svelte/src/utils/preprocess.ts index ecd94e28f..2b4cf3a7a 100644 --- a/packages/vite-plugin-svelte/src/utils/preprocess.ts +++ b/packages/vite-plugin-svelte/src/utils/preprocess.ts @@ -1,79 +1,11 @@ -import * as vite from 'vite'; -import type { ESBuildOptions, ResolvedConfig, Plugin } from 'vite'; +import type { ResolvedConfig, Plugin } from 'vite'; import MagicString from 'magic-string'; import { preprocess } from 'svelte/compiler'; -import { Preprocessor, PreprocessorGroup, Processed, ResolvedOptions } from './options'; +import { PreprocessorGroup, Processed, ResolvedOptions } from './options'; import { log } from './log'; import { buildSourceMap } from './sourcemap'; import path from 'path'; - -const supportedStyleLangs = ['css', 'less', 'sass', 'scss', 'styl', 'stylus', 'postcss']; - -const supportedScriptLangs = ['ts']; - -function createViteScriptPreprocessor(): Preprocessor { - return async ({ attributes, content, filename = '' }) => { - const lang = attributes.lang as string; - if (!supportedScriptLangs.includes(lang)) return; - const transformResult = await vite.transformWithEsbuild(content, filename, { - loader: lang as ESBuildOptions['loader'], - target: 'esnext', - tsconfigRaw: { - compilerOptions: { - // svelte typescript needs this flag to work with type imports - importsNotUsedAsValues: 'preserve', - preserveValueImports: true - } - } - }); - return { - code: transformResult.code, - map: transformResult.map - }; - }; -} - -function createViteStylePreprocessor(config: ResolvedConfig): Preprocessor { - const transform = getCssTransformFn(config); - return async ({ attributes, content, filename = '' }) => { - const lang = attributes.lang as string; - if (!supportedStyleLangs.includes(lang)) return; - const moduleId = `${filename}.${lang}`; - const result = await transform(content, moduleId); - // patch sourcemap source to point back to original filename - if (result.map?.sources?.[0] === moduleId) { - result.map.sources[0] = path.basename(filename); - } - return { - code: result.code, - map: result.map ?? undefined - }; - }; -} - -// eslint-disable-next-line no-unused-vars -type CssTransform = (code: string, filename: string) => Promise<{ code: string; map?: any }>; - -function getCssTransformFn(config: ResolvedConfig): CssTransform { - // API is only available in Vite 3.2 and above - // TODO: Remove Vite plugin hack when bump peer dep to Vite 3.2 - if (vite.preprocessCSS) { - return async (code, filename) => { - return vite.preprocessCSS(code, filename, config); - }; - } else { - const pluginName = 'vite:css'; - const plugin = config.plugins.find((p) => p.name === pluginName); - if (!plugin) { - throw new Error(`failed to find plugin ${pluginName}`); - } - if (!plugin.transform) { - throw new Error(`plugin ${pluginName} has no transform`); - } - // @ts-expect-error - return plugin.transform.bind(null); - } -} +import { viteScript, viteStyle } from '../preprocess'; function createVitePreprocessorGroup(config: ResolvedConfig): PreprocessorGroup { return { @@ -81,8 +13,8 @@ function createVitePreprocessorGroup(config: ResolvedConfig): PreprocessorGroup return preprocess( content, { - script: createViteScriptPreprocessor(), - style: createViteStylePreprocessor(config) + script: viteScript().script, + style: viteStyle(config).style }, { filename } ); From 5ee010107a56d09d9a9d4b436b35b614c243af6b Mon Sep 17 00:00:00 2001 From: bluwy Date: Wed, 2 Nov 2022 23:33:57 +0800 Subject: [PATCH 2/5] feat: export vitePreprocess --- packages/vite-plugin-svelte/src/preprocess.ts | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/packages/vite-plugin-svelte/src/preprocess.ts b/packages/vite-plugin-svelte/src/preprocess.ts index 68abfd4be..9a16c3c75 100644 --- a/packages/vite-plugin-svelte/src/preprocess.ts +++ b/packages/vite-plugin-svelte/src/preprocess.ts @@ -2,12 +2,26 @@ import path from 'path'; import * as vite from 'vite'; import type { ESBuildOptions, ResolvedConfig } from 'vite'; // eslint-disable-next-line node/no-missing-import -import type { Preprocessor } from 'svelte/types/compiler/preprocess'; +import type { Preprocessor, PreprocessorGroup } from 'svelte/types/compiler/preprocess'; const supportedStyleLangs = ['css', 'less', 'sass', 'scss', 'styl', 'stylus', 'postcss', 'sss']; - const supportedScriptLangs = ['ts']; +export function vitePreprocess(opts: { + script?: boolean; + style?: boolean | Parameters[0]; +}) { + const preprocessor: PreprocessorGroup = {}; + if (opts.script !== false) { + preprocessor.script = viteScript().script; + } + if (opts.style !== false) { + const styleOpts = typeof opts.style == 'object' ? opts.style : undefined; + preprocessor.style = viteStyle(styleOpts).style; + } + return preprocessor; +} + export function viteScript(): { script: Preprocessor } { return { async script({ attributes, content, filename = '' }) { From b6b4bdf9bbcb56aa821556502580cf1325cf2a5b Mon Sep 17 00:00:00 2001 From: bluwy Date: Wed, 2 Nov 2022 23:41:05 +0800 Subject: [PATCH 3/5] chore: fix types --- packages/vite-plugin-svelte/package.json | 2 ++ packages/vite-plugin-svelte/preprocess.d.ts | 1 + packages/vite-plugin-svelte/src/preprocess.ts | 8 ++++---- 3 files changed, 7 insertions(+), 4 deletions(-) create mode 100644 packages/vite-plugin-svelte/preprocess.d.ts diff --git a/packages/vite-plugin-svelte/package.json b/packages/vite-plugin-svelte/package.json index 12397dbac..e00a4c378 100644 --- a/packages/vite-plugin-svelte/package.json +++ b/packages/vite-plugin-svelte/package.json @@ -16,10 +16,12 @@ "types": "dist/index.d.ts", "exports": { ".": { + "types": "./dist/index.d.ts", "import": "./dist/index.js", "require": "./dist/index.cjs" }, "./preprocess": { + "types": "./dist/preprocess.d.ts", "import": "./dist/preprocess.js", "require": "./dist/preprocess.cjs" }, diff --git a/packages/vite-plugin-svelte/preprocess.d.ts b/packages/vite-plugin-svelte/preprocess.d.ts new file mode 100644 index 000000000..a632a830e --- /dev/null +++ b/packages/vite-plugin-svelte/preprocess.d.ts @@ -0,0 +1 @@ +export { vitePreprocess, viteScript, viteStyle } from './dist/preprocess'; diff --git a/packages/vite-plugin-svelte/src/preprocess.ts b/packages/vite-plugin-svelte/src/preprocess.ts index 9a16c3c75..c1bfa94ef 100644 --- a/packages/vite-plugin-svelte/src/preprocess.ts +++ b/packages/vite-plugin-svelte/src/preprocess.ts @@ -7,16 +7,16 @@ import type { Preprocessor, PreprocessorGroup } from 'svelte/types/compiler/prep const supportedStyleLangs = ['css', 'less', 'sass', 'scss', 'styl', 'stylus', 'postcss', 'sss']; const supportedScriptLangs = ['ts']; -export function vitePreprocess(opts: { +export function vitePreprocess(opts?: { script?: boolean; style?: boolean | Parameters[0]; }) { const preprocessor: PreprocessorGroup = {}; - if (opts.script !== false) { + if (opts?.script !== false) { preprocessor.script = viteScript().script; } - if (opts.style !== false) { - const styleOpts = typeof opts.style == 'object' ? opts.style : undefined; + if (opts?.style !== false) { + const styleOpts = typeof opts?.style == 'object' ? opts?.style : undefined; preprocessor.style = viteStyle(styleOpts).style; } return preprocessor; From a241f5dad3a64a29b6cf33d3a87936a934a583e0 Mon Sep 17 00:00:00 2001 From: dominikg Date: Sat, 12 Nov 2022 20:49:34 +0100 Subject: [PATCH 4/5] experiment: add emitPreprocessed option to generate preprocessed svelte files during build --- .../__tests__/emit-preprocessed.spec.ts | 11 ++++ .../e2e-tests/emit-preprocessed/index.html | 15 ++++++ .../e2e-tests/emit-preprocessed/package.json | 16 ++++++ .../emit-preprocessed/public/favicon.png | Bin 0 -> 3127 bytes .../emit-preprocessed/src/App.svelte | 5 ++ .../emit-preprocessed/src/lib/Counter.svelte | 34 +++++++++++++ .../emit-preprocessed/src/lib/index.js | 1 + .../e2e-tests/emit-preprocessed/src/main.js | 7 +++ .../emit-preprocessed/svelte.config.js | 16 ++++++ .../emit-preprocessed/vite.config.js | 21 ++++++++ packages/vite-plugin-svelte/src/index.ts | 16 ++++++ .../vite-plugin-svelte/src/utils/compile.ts | 6 ++- .../vite-plugin-svelte/src/utils/options.ts | 8 +++ .../src/utils/vite-plugin-svelte-cache.ts | 15 ++++++ pnpm-lock.yaml | 47 +++++++++++++++++- 15 files changed, 215 insertions(+), 3 deletions(-) create mode 100644 packages/e2e-tests/emit-preprocessed/__tests__/emit-preprocessed.spec.ts create mode 100644 packages/e2e-tests/emit-preprocessed/index.html create mode 100644 packages/e2e-tests/emit-preprocessed/package.json create mode 100644 packages/e2e-tests/emit-preprocessed/public/favicon.png create mode 100644 packages/e2e-tests/emit-preprocessed/src/App.svelte create mode 100644 packages/e2e-tests/emit-preprocessed/src/lib/Counter.svelte create mode 100644 packages/e2e-tests/emit-preprocessed/src/lib/index.js create mode 100644 packages/e2e-tests/emit-preprocessed/src/main.js create mode 100644 packages/e2e-tests/emit-preprocessed/svelte.config.js create mode 100644 packages/e2e-tests/emit-preprocessed/vite.config.js diff --git a/packages/e2e-tests/emit-preprocessed/__tests__/emit-preprocessed.spec.ts b/packages/e2e-tests/emit-preprocessed/__tests__/emit-preprocessed.spec.ts new file mode 100644 index 000000000..eba113aa3 --- /dev/null +++ b/packages/e2e-tests/emit-preprocessed/__tests__/emit-preprocessed.spec.ts @@ -0,0 +1,11 @@ +import { getText, isBuild } from '~utils'; + +test('should render Counter', async () => { + expect(await getText('button')).toBe('clicks: 0'); +}); + +if (!isBuild) { + test('should emit preprocessed', () => { + // TODO read assets and ensure they are what we want + }); +} diff --git a/packages/e2e-tests/emit-preprocessed/index.html b/packages/e2e-tests/emit-preprocessed/index.html new file mode 100644 index 000000000..c321fcb17 --- /dev/null +++ b/packages/e2e-tests/emit-preprocessed/index.html @@ -0,0 +1,15 @@ + + + + + + + Svelte app + + + + + + + + diff --git a/packages/e2e-tests/emit-preprocessed/package.json b/packages/e2e-tests/emit-preprocessed/package.json new file mode 100644 index 000000000..c04296ba1 --- /dev/null +++ b/packages/e2e-tests/emit-preprocessed/package.json @@ -0,0 +1,16 @@ +{ + "name": "e2e-tests-emit-preprocessed", + "private": true, + "version": "1.0.0", + "scripts": { + "dev": "vite", + "build": "vite build", + "preview": "vite preview" + }, + "devDependencies": { + "@sveltejs/vite-plugin-svelte": "workspace:*", + "svelte": "^3.52.0", + "vite": "^3.2.3" + }, + "type": "module" +} diff --git a/packages/e2e-tests/emit-preprocessed/public/favicon.png b/packages/e2e-tests/emit-preprocessed/public/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..7e6f5eb5a2f1f1c882d265cf479de25caa925645 GIT binary patch literal 3127 zcmV-749N3|P)i z7)}s4L53SJCkR}iVi00SFk;`MXX*#X*kkwKs@nFGS}c;=?XFjU|G$3t^5sjIVS2G+ zw)WGF83CpoGXhLGW(1gW%uV|X7>1P6VhCX=Ux)Lb!*DZ%@I3!{Gsf7d?gtIQ%nQiK z3%(LUSkBji;C5Rfgd6$VsF@H`Pk@xtY6t<>FNR-pD}=C~$?)9pdm3XZ36N5PNWYjb z$xd$yNQR9N!dfj-Vd@BwQo^FIIWPPmT&sZyQ$v81(sCBV=PGy{0wltEjB%~h157*t zvbe_!{=I_783x!0t1-r#-d{Y?ae$Q4N_Nd^Ui^@y(%)Gjou6y<3^XJdu{rmUf-Me?)zZ>9OR&6U5H*cK; z$gUlB{g0O4gN0sLSO|Of?hU(l?;h(jA3uH!Z{EBKuV23ouU@^Y6#%v+QG;>e*E}%?wlu-NT4DG zs)z)7WbLr)vGAu(ohrKc^em@OpO&f~6_>E61n_e0_V3@{U3^O;j{`^mNCJUj_>;7v zsMs6Hu3g7+@v+lSo;=yTYFqq}jZmQ-BK8K{C4kqi_i*jBaQE(Au0607V-zKeT;EPg zX(`vrn=L+e74+-Tqeok@_`tDa$G9I|$nTU5H*2V8@y()n*zqM?J1G!-1aX;CfDC9B zTnJ#j_%*n8Qb1)re*Bno7g0RG{Eb;IK14irJYJp$5Z6ac9~b_P?+5t~95~SRG$g?1 znFJ7p$xV&GZ18m~79TGRdfsc-BcX$9yXTR*n)mPD@1~O(_?cT$ZvFPucRmGlq&se0 zKrcUf^k}4hM*biEJOWKzz!qQe;CB_ZtSOO9Owg#lZAc=s65^rb{fZe(TYu_rk!wKkEf}RIt=#Om( zR8mN`DM<^xj~59euMMspBolVN zAPTr8sSDI104orIAdmL$uOXn*6hga1G+0WD0E?UtabxC#VC~vf3|10|phW;yQ3CY8 z2CM=)ErF;xq-YJ5G|um}>*1#E+O_Mu|Nr#qQ&G1P-NMq@f?@*XUcSbV?tX=)ilM-Q zBZP|!Bpv0V;#ojKcpc7$=eqO;#Uy~#?^kNI{vSZfLx&DEt~LTmaKWXcx=joubklI<*Aw z>LtMaQ7DR<1I2LkWvwyu#Rwn~;ezT}_g(@5l3h?W%-a86Y-t#O1PubP+z<%?V5D(U zy57A6{h+{?kOZp7&WKZR+=sznMJ}+Dnpo=C_0%R_x_t~J5T?E_{+))l5v1%52>)d-`iiZyx|5!%M2Fb2dU zW3~MwwpEH9Rhue+k$UIOoo($Ds!NbOyMR36fRHu;*15(YcA7siIZk#%JWz>P!qX1?IUojG&nKR>^gArBt2 zit(ETyZ=@V&7mv_Fi4bABcnwP+jzQuHcfU&BrAV91u-rFvEi7y-KnWsvHH=d2 zgAk(GKm_S8RcTJ>2N3~&Hbwp{Z3NF_Xeh}g4Eke)V&dY{W(3&b1j9t4yK_aYJisZZ{1rcU5- z;eD>K;ndPq&B-8yA_S0F!4ThA&{1{x)H<#?k9a#6Pc6L?V^s0``ynL&D;p(!Nmx`Y zFkHex{4p!Ggm^@DlehW}iHHVi}~u=$&N? z(NEBLQ#UxxAkdW>X9LnqUr#t4Lu0=9L8&o>JsqTtT5|%gb3QA~hr0pED71+iFFr)dZ=Q=E6ng{NE{Z~0)C?deO#?Aj zSDQ$z#TeC2T^|=}6GBo-&$;E{HL3!q3Z-szuf)O=G#zDjin4SSP%o%6+2IT#sLjQa ziyxFFz~LMjWY+_a5H!U6%a<=b7QVP^ z*90a62;bVq{?@)P6^DWd^Yilq4|YTV2Nw!Yu;a1lPI-sxR)rf@Fe5DhDP7FH zZZ%4S*1C30P;|O+jB!1;m|rXT90Sm5*RBbQN`PKu+hDD*S^yE(CdtSfg=z>u$cIj> z + import Counter from './lib/Counter.svelte'; + + + diff --git a/packages/e2e-tests/emit-preprocessed/src/lib/Counter.svelte b/packages/e2e-tests/emit-preprocessed/src/lib/Counter.svelte new file mode 100644 index 000000000..a48a22449 --- /dev/null +++ b/packages/e2e-tests/emit-preprocessed/src/lib/Counter.svelte @@ -0,0 +1,34 @@ + + + + + diff --git a/packages/e2e-tests/emit-preprocessed/src/lib/index.js b/packages/e2e-tests/emit-preprocessed/src/lib/index.js new file mode 100644 index 000000000..ff692a3cf --- /dev/null +++ b/packages/e2e-tests/emit-preprocessed/src/lib/index.js @@ -0,0 +1 @@ +export { default as Counter } from './Counter.svelte'; diff --git a/packages/e2e-tests/emit-preprocessed/src/main.js b/packages/e2e-tests/emit-preprocessed/src/main.js new file mode 100644 index 000000000..2c27a2579 --- /dev/null +++ b/packages/e2e-tests/emit-preprocessed/src/main.js @@ -0,0 +1,7 @@ +import App from './App.svelte'; + +const app = new App({ + target: document.body +}); + +export default app; diff --git a/packages/e2e-tests/emit-preprocessed/svelte.config.js b/packages/e2e-tests/emit-preprocessed/svelte.config.js new file mode 100644 index 000000000..44ed640a8 --- /dev/null +++ b/packages/e2e-tests/emit-preprocessed/svelte.config.js @@ -0,0 +1,16 @@ +// eslint-disable-next-line node/no-missing-import +import { vitePreprocess } from '@sveltejs/vite-plugin-svelte/preprocess'; +export default { + preprocess: [vitePreprocess()], + vitePlugin: { + experimental: { + useVitePreprocess: true, + emitPreprocessed(fileName, processed) { + return { + fileName, + source: processed.code + }; + } + } + } +}; diff --git a/packages/e2e-tests/emit-preprocessed/vite.config.js b/packages/e2e-tests/emit-preprocessed/vite.config.js new file mode 100644 index 000000000..20e9a8e57 --- /dev/null +++ b/packages/e2e-tests/emit-preprocessed/vite.config.js @@ -0,0 +1,21 @@ +import { svelte } from '@sveltejs/vite-plugin-svelte'; +import { defineConfig } from 'vite'; + +export default defineConfig(({ command, mode }) => { + return { + plugins: [svelte()], + build: { + // make build faster by skipping transforms and minification + target: 'esnext', + minify: false + }, + server: { + watch: { + // During tests we edit the files too fast and sometimes chokidar + // misses change events, so enforce polling for consistency + usePolling: true, + interval: 100 + } + } + }; +}); diff --git a/packages/vite-plugin-svelte/src/index.ts b/packages/vite-plugin-svelte/src/index.ts index 22dcc4803..e52eb5c52 100644 --- a/packages/vite-plugin-svelte/src/index.ts +++ b/packages/vite-plugin-svelte/src/index.ts @@ -215,6 +215,22 @@ export function svelte(inlineOptions?: Partial): Plugin[] { throw toRollupError(e, options); } } + }, + + generateBundle() { + const emitPreprocessed = options.experimental?.emitPreprocessed; + if (emitPreprocessed) { + const preprocessed = cache.getPreprocessed(); + preprocessed.forEach((processed, filename) => { + const emit = emitPreprocessed(filename, processed); + if (emit) { + if (emit.fileName.startsWith('/')) { + emit.fileName = emit.fileName.slice(1); + } + this.emitFile({ ...emit, type: 'asset' }); + } + }); + } } } ]; diff --git a/packages/vite-plugin-svelte/src/utils/compile.ts b/packages/vite-plugin-svelte/src/utils/compile.ts index d5f31f11d..ed10d912d 100644 --- a/packages/vite-plugin-svelte/src/utils/compile.ts +++ b/packages/vite-plugin-svelte/src/utils/compile.ts @@ -5,6 +5,8 @@ import { createMakeHot } from 'svelte-hmr'; import { SvelteRequest } from './id'; import { safeBase64Hash } from './hash'; import { log } from './log'; +// eslint-disable-next-line node/no-missing-import +import type { Processed } from 'svelte/types/compiler/preprocess'; const scriptLangRE = /