@sveltejs/vite-plugin-svelte
Advanced tools
Comparing version 1.0.0-next.11 to 1.0.0-next.12
# @sveltejs/vite-plugin-svelte | ||
## 1.0.0-next.12 | ||
### Minor Changes | ||
- Resolve svelte to svelte/ssr when building for ssr (fixes [#74](https://github.com/sveltejs/vite-plugin-svelte/issues/74)) ([#75](https://github.com/sveltejs/vite-plugin-svelte/pull/75)) ([`f6f56fe`](https://github.com/sveltejs/vite-plugin-svelte/commit/f6f56fee7d3567196052a23440cb1818187fa232)) | ||
- Support svg extension ([#78](https://github.com/sveltejs/vite-plugin-svelte/pull/78)) ([`2eb09cf`](https://github.com/sveltejs/vite-plugin-svelte/commit/2eb09cf180c7ebf0fb4ccfccee663e5264b3814c)) | ||
- Restart dev server when svelte config file changes ([#72](https://github.com/sveltejs/vite-plugin-svelte/pull/72)) ([`5100376`](https://github.com/sveltejs/vite-plugin-svelte/commit/5100376ef91d5e39ec00222f1043e4fda047678b)) | ||
- Allow svelte imports to be added to optimizeDeps.include and don't exclude svelte from optimizeDeps then ([#68](https://github.com/sveltejs/vite-plugin-svelte/pull/68)) ([`9583900`](https://github.com/sveltejs/vite-plugin-svelte/commit/9583900a2b3600133cee3a46b6dbb7df137977b6)) | ||
- Vite config can be updated based on values in svelte config (see [#60](https://github.com/sveltejs/vite-plugin-svelte/issues/60)) ([#64](https://github.com/sveltejs/vite-plugin-svelte/pull/64)) ([`c3f65fd`](https://github.com/sveltejs/vite-plugin-svelte/commit/c3f65fdf414b22810ad60817b3e1e62790ba816f)) | ||
### Patch Changes | ||
- customize changelog format ([#90](https://github.com/sveltejs/vite-plugin-svelte/pull/90)) ([`b5a58cd`](https://github.com/sveltejs/vite-plugin-svelte/commit/b5a58cd814bbc71a5e59060d436770f7a0102262)) | ||
- relax svelte peer dependency to 3.34.0 ([#70](https://github.com/sveltejs/vite-plugin-svelte/pull/70)) ([`377d464`](https://github.com/sveltejs/vite-plugin-svelte/commit/377d464eba30c56f012deba3d306cb5a7195b787)) | ||
- do not transform imports tagged with ?url or ?raw (fixes #87) ([#88](https://github.com/sveltejs/vite-plugin-svelte/pull/88)) ([`d1d2638`](https://github.com/sveltejs/vite-plugin-svelte/commit/d1d2638b247830852faa89e7b9bc9a430b81ba51)) | ||
- update svelte-hmr to ^0.14.5 to fix hmr reordering issue introduced by a change in svelte 3.38.3 ([#92](https://github.com/sveltejs/vite-plugin-svelte/pull/92)) ([`cdfd821`](https://github.com/sveltejs/vite-plugin-svelte/commit/cdfd8210770150c6e40f68b6b48cd2e455414299)) | ||
- fix kit-node tests ([#55](https://github.com/sveltejs/vite-plugin-svelte/pull/55)) ([`09b63d3`](https://github.com/sveltejs/vite-plugin-svelte/commit/09b63d32e8816acc554a66d4d01062be197dfbb7)) | ||
- output sourcemap in hmr helper preprocessor ([#71](https://github.com/sveltejs/vite-plugin-svelte/pull/71)) ([`97ee68c`](https://github.com/sveltejs/vite-plugin-svelte/commit/97ee68c5106e58b2e7c4eb97e8cf7dd1c52bbfd3)) | ||
- reduced debug output ([#83](https://github.com/sveltejs/vite-plugin-svelte/pull/83)) ([`eb048ff`](https://github.com/sveltejs/vite-plugin-svelte/commit/eb048ff9419488f75869ffb880a78a2a3aa5a6bb)) | ||
- Refactored e2e-tests to use package.json scripts | ||
- Updated dependencies | ||
## 1.0.0-next.11 | ||
@@ -7,3 +41,3 @@ | ||
- [#54](https://github.com/sveltejs/vite-plugin-svelte/pull/54) [`0f7e256`](https://github.com/sveltejs/vite-plugin-svelte/commit/0f7e256a9ebb0ee9ac6075146d27bf4f11ecdab3) feat: convert to es module with cjs fallback, use named export instead of default | ||
- convert to es module with cjs fallback, use named export instead of default ([#54](https://github.com/sveltejs/vite-plugin-svelte/pull/54)) ([`0f7e256`](https://github.com/sveltejs/vite-plugin-svelte/commit/0f7e256a9ebb0ee9ac6075146d27bf4f11ecdab3)) | ||
@@ -29,11 +63,11 @@ If you are using vite-plugin-svelte with require, you should switch to esm and import the named export "svelte". | ||
- [#45](https://github.com/sveltejs/vite-plugin-svelte/pull/45) [`673cf61`](https://github.com/sveltejs/vite-plugin-svelte/commit/673cf61b3800e7a64be2b73a7273909da95729d2) Feature: log svelte compiler warnings to console. use options.onwarn to customize logging | ||
- Log svelte compiler warnings to console. use options.onwarn to customize logging ([#45](https://github.com/sveltejs/vite-plugin-svelte/pull/45)) ([`673cf61`](https://github.com/sveltejs/vite-plugin-svelte/commit/673cf61b3800e7a64be2b73a7273909da95729d2)) | ||
### Patch Changes | ||
- [#44](https://github.com/sveltejs/vite-plugin-svelte/pull/44) [`24ae093`](https://github.com/sveltejs/vite-plugin-svelte/commit/24ae0934301cb50506bf39cdccc07ad3eac546fd) update to esbuild 0.12 and vite 2.3.7 | ||
- Update to esbuild 0.12 and vite 2.3.7 ([#44](https://github.com/sveltejs/vite-plugin-svelte/pull/44)) ([`24ae093`](https://github.com/sveltejs/vite-plugin-svelte/commit/24ae0934301cb50506bf39cdccc07ad3eac546fd)) | ||
* [#44](https://github.com/sveltejs/vite-plugin-svelte/pull/44) [`24ae093`](https://github.com/sveltejs/vite-plugin-svelte/commit/24ae0934301cb50506bf39cdccc07ad3eac546fd) update engines.node to "^12.20 || ^14.13.1 || >= 16" | ||
- Update engines.node to "^12.20 || ^14.13.1 || >= 16" ([#44](https://github.com/sveltejs/vite-plugin-svelte/pull/44)) ([`24ae093`](https://github.com/sveltejs/vite-plugin-svelte/commit/24ae0934301cb50506bf39cdccc07ad3eac546fd)) | ||
- [#45](https://github.com/sveltejs/vite-plugin-svelte/pull/45) [`673cf61`](https://github.com/sveltejs/vite-plugin-svelte/commit/673cf61b3800e7a64be2b73a7273909da95729d2) enable logging for compiler warnings | ||
- Enable logging for compiler warnings ([#45](https://github.com/sveltejs/vite-plugin-svelte/pull/45)) ([`673cf61`](https://github.com/sveltejs/vite-plugin-svelte/commit/673cf61b3800e7a64be2b73a7273909da95729d2)) | ||
@@ -44,3 +78,3 @@ ## 1.0.0-next.10 | ||
- [#41](https://github.com/sveltejs/vite-plugin-svelte/pull/41) [`cb7f03d`](https://github.com/sveltejs/vite-plugin-svelte/commit/cb7f03d61c19f0b98c6412c11bbaa4af978da9ed) Feature: Allow `emitCss: false` for production builds and customizable compilerOptions.css and hydratable - fixes #9 | ||
- Allow `emitCss: false` for production builds and customizable compilerOptions.css and hydratable (fixes [#9](https://github.com/sveltejs/vite-plugin-svelte/issues/9)) ([#41](https://github.com/sveltejs/vite-plugin-svelte/pull/41)) ([`cb7f03d`](https://github.com/sveltejs/vite-plugin-svelte/commit/cb7f03d61c19f0b98c6412c11bbaa4af978da9ed)) | ||
@@ -51,3 +85,3 @@ ## 1.0.0-next.9 | ||
- [#38](https://github.com/sveltejs/vite-plugin-svelte/pull/38) [`5aef91c`](https://github.com/sveltejs/vite-plugin-svelte/commit/5aef91c8752c8de94a1f1fcb28618606b7c44670) fix: ensure esm config loading works on windows | ||
- Ensure esm config loading works on windows ([#38](https://github.com/sveltejs/vite-plugin-svelte/pull/38)) ([`5aef91c`](https://github.com/sveltejs/vite-plugin-svelte/commit/5aef91c8752c8de94a1f1fcb28618606b7c44670)) | ||
@@ -58,9 +92,9 @@ ## 1.0.0-next.8 | ||
- [#35](https://github.com/sveltejs/vite-plugin-svelte/pull/35) [`4018ce6`](https://github.com/sveltejs/vite-plugin-svelte/commit/4018ce621b4df75877e0e18057c332f27158d42b) Feature: Support esm in svelte.config.js and svelte.config.mjs | ||
- Support esm in svelte.config.js and svelte.config.mjs ([#35](https://github.com/sveltejs/vite-plugin-svelte/pull/35)) ([`4018ce6`](https://github.com/sveltejs/vite-plugin-svelte/commit/4018ce621b4df75877e0e18057c332f27158d42b)) | ||
* [#35](https://github.com/sveltejs/vite-plugin-svelte/pull/35) [`4018ce6`](https://github.com/sveltejs/vite-plugin-svelte/commit/4018ce621b4df75877e0e18057c332f27158d42b) Feature: add configFile option | ||
- Add configFile option ([#35](https://github.com/sveltejs/vite-plugin-svelte/pull/35)) ([`4018ce6`](https://github.com/sveltejs/vite-plugin-svelte/commit/4018ce621b4df75877e0e18057c332f27158d42b)) | ||
### Patch Changes | ||
- [#34](https://github.com/sveltejs/vite-plugin-svelte/pull/34) [`e5d4749`](https://github.com/sveltejs/vite-plugin-svelte/commit/e5d4749c0850260a295daab9cb15866fe58ee709) fix: watch preprocessor dependencies and trigger hmr on change | ||
- Watch preprocessor dependencies and trigger hmr on change ([#34](https://github.com/sveltejs/vite-plugin-svelte/pull/34)) ([`e5d4749`](https://github.com/sveltejs/vite-plugin-svelte/commit/e5d4749c0850260a295daab9cb15866fe58ee709)) | ||
@@ -71,3 +105,3 @@ ## 1.0.0-next.7 | ||
- [#32](https://github.com/sveltejs/vite-plugin-svelte/pull/32) [`113bb7d`](https://github.com/sveltejs/vite-plugin-svelte/commit/113bb7dc330a7517085d12d1d0758a376a12253f) Reduced cache usage, share css cache between SSR and client | ||
- Reduced cache usage, share css cache between SSR and client ([#32](https://github.com/sveltejs/vite-plugin-svelte/pull/32)) ([`113bb7d`](https://github.com/sveltejs/vite-plugin-svelte/commit/113bb7dc330a7517085d12d1d0758a376a12253f)) | ||
@@ -74,0 +108,0 @@ ## 1.0.0-next.6 |
@@ -26,4 +26,7 @@ var __defProp = Object.defineProperty; | ||
// src/index.ts | ||
import fs5 from "fs"; | ||
// src/utils/log.ts | ||
import chalk from "chalk"; | ||
import { cyan, yellow, red } from "kleur/colors"; | ||
import debug from "debug"; | ||
@@ -39,3 +42,3 @@ var levels = ["debug", "info", "warn", "error", "silent"]; | ||
info: { | ||
color: chalk.cyan, | ||
color: cyan, | ||
log: console.log, | ||
@@ -45,3 +48,3 @@ enabled: true | ||
warn: { | ||
color: chalk.yellow, | ||
color: yellow, | ||
log: console.warn, | ||
@@ -51,3 +54,3 @@ enabled: true | ||
error: { | ||
color: chalk.red, | ||
color: red, | ||
log: console.error, | ||
@@ -75,6 +78,2 @@ enabled: true | ||
} | ||
var _viteLogOverwriteProtection = false; | ||
function setViteLogOverwriteProtection(viteLogOverwriteProtection) { | ||
_viteLogOverwriteProtection = viteLogOverwriteProtection; | ||
} | ||
function _log(logger, message, payload) { | ||
@@ -87,3 +86,3 @@ if (!logger.enabled) { | ||
} else { | ||
logger.log(logger.color(`[${prefix}] ${message}`)); | ||
logger.log(logger.color(`${new Date().toLocaleTimeString()} [${prefix}] ${message}`)); | ||
if (payload) { | ||
@@ -93,5 +92,2 @@ logger.log(payload); | ||
} | ||
if (_viteLogOverwriteProtection) { | ||
logger.log(""); | ||
} | ||
} | ||
@@ -113,4 +109,3 @@ function createLogger(level) { | ||
error: createLogger("error"), | ||
setLevel, | ||
setViteLogOverwriteProtection | ||
setLevel | ||
}; | ||
@@ -180,3 +175,2 @@ function logCompilerWarnings(warnings, options) { | ||
const result = [...affectedModules].filter(Boolean); | ||
log.debug(`handleHotUpdate result for ${svelteRequest.id}`, result); | ||
const ssrModulesToInvalidate = result.filter((m) => !!m.ssrTransformResult); | ||
@@ -187,2 +181,5 @@ if (ssrModulesToInvalidate.length > 0) { | ||
} | ||
if (result.length > 0) { | ||
log.debug(`handleHotUpdate for ${svelteRequest.id} result: ${result.map((m) => m.id).join(", ")}`); | ||
} | ||
return result; | ||
@@ -335,5 +332,10 @@ } | ||
const query = qs.parse(rawQuery); | ||
if (query.svelte != null) { | ||
query.svelte = true; | ||
for (const p of ["svelte", "url", "raw"]) { | ||
if (query[p] != null) { | ||
query[p] = true; | ||
} | ||
} | ||
if (query.url || query.raw) { | ||
return; | ||
} | ||
const normalizedFilename = normalize(filename, root); | ||
@@ -395,4 +397,8 @@ const cssId = createVirtualImportId(filename, root, "style"); | ||
import { pathToFileURL } from "url"; | ||
var knownSvelteConfigNames = ["svelte.config.js", "svelte.config.cjs", "svelte.config.mjs"]; | ||
var dynamicImportDefault = new Function("path", "return import(path).then(m => m.default)"); | ||
var knownSvelteConfigNames = [ | ||
"svelte.config.js", | ||
"svelte.config.cjs", | ||
"svelte.config.mjs" | ||
]; | ||
var dynamicImportDefault = new Function("path", 'return import(path + "?t=" + Date.now()).then(m => m.default)'); | ||
async function loadSvelteConfig(viteConfig, inlineOptions) { | ||
@@ -404,3 +410,10 @@ const configFile = findConfigToLoad(viteConfig, inlineOptions); | ||
try { | ||
return await dynamicImportDefault(pathToFileURL(configFile).href); | ||
const result = await dynamicImportDefault(pathToFileURL(configFile).href); | ||
if (result != null) { | ||
return __spreadProps(__spreadValues({}, result), { | ||
configFile | ||
}); | ||
} else { | ||
throw new Error(`invalid export in ${configFile}`); | ||
} | ||
} catch (e) { | ||
@@ -411,8 +424,18 @@ log.error(`failed to import config ${configFile}`, e); | ||
} | ||
try { | ||
return __require(configFile); | ||
} catch (e) { | ||
log.error(`failed to require config ${configFile}`, e); | ||
if (!err) { | ||
err = e; | ||
if (!configFile.endsWith(".mjs")) { | ||
try { | ||
delete __require.cache[__require.resolve(configFile)]; | ||
const result = __require(configFile); | ||
if (result != null) { | ||
return __spreadProps(__spreadValues({}, result), { | ||
configFile | ||
}); | ||
} else { | ||
throw new Error(`invalid export in ${configFile}`); | ||
} | ||
} catch (e) { | ||
log.error(`failed to require config ${configFile}`, e); | ||
if (!err) { | ||
err = e; | ||
} | ||
} | ||
@@ -443,80 +466,19 @@ } | ||
// src/utils/preprocess.ts | ||
var supportedStyleLangs = ["css", "less", "sass", "scss", "styl", "stylus", "postcss"]; | ||
var supportedScriptLangs = ["ts"]; | ||
function createPreprocessorFromVitePlugin(config, options, pluginName, supportedLangs) { | ||
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`); | ||
} | ||
const pluginTransform = plugin.transform.bind(null); | ||
return async ({ attributes, content, filename }) => { | ||
var _a, _b, _c, _d; | ||
const lang = attributes.lang; | ||
if (!supportedLangs.includes(lang)) { | ||
return { code: content }; | ||
} | ||
const moduleId = `${filename}.${lang}`; | ||
const moduleGraph = (_a = options.server) == null ? void 0 : _a.moduleGraph; | ||
if (moduleGraph && !moduleGraph.getModuleById(moduleId)) { | ||
await moduleGraph.ensureEntryFromUrl(moduleId); | ||
} | ||
const transformResult = await pluginTransform(content, moduleId); | ||
const hasMap = !!((_b = transformResult.map) == null ? void 0 : _b.mappings); | ||
if (((_d = (_c = transformResult.map) == null ? void 0 : _c.sources) == null ? void 0 : _d[0]) === moduleId) { | ||
transformResult.map.sources[0] = filename; | ||
} | ||
return { | ||
code: transformResult.code, | ||
map: hasMap ? transformResult.map : null, | ||
dependencies: transformResult.deps | ||
}; | ||
}; | ||
} | ||
function createVitePreprocessorGroup(config, options) { | ||
return { | ||
script: createPreprocessorFromVitePlugin(config, options, "vite:esbuild", supportedScriptLangs), | ||
style: createPreprocessorFromVitePlugin(config, options, "vite:css", supportedStyleLangs) | ||
}; | ||
} | ||
function createInjectScopeEverythingRulePreprocessorGroup() { | ||
return { | ||
style({ content }) { | ||
return { | ||
code: `${content} *{}` | ||
}; | ||
} | ||
}; | ||
} | ||
function buildExtraPreprocessors(options, config) { | ||
const extraPreprocessors = []; | ||
if (options.useVitePreprocess) { | ||
log.debug("adding vite preprocessor"); | ||
extraPreprocessors.push(createVitePreprocessorGroup(config, options)); | ||
} | ||
const pluginsWithPreprocessors = config.plugins.filter((p) => p == null ? void 0 : p.sveltePreprocess); | ||
if (pluginsWithPreprocessors.length > 0) { | ||
log.debug(`adding preprocessors from other vite plugins: ${pluginsWithPreprocessors.map((p) => p.name).join(", ")}`); | ||
extraPreprocessors.push(...pluginsWithPreprocessors.map((p) => p.sveltePreprocess)); | ||
} | ||
if (options.hot && !options.disableCssHmr) { | ||
extraPreprocessors.push(createInjectScopeEverythingRulePreprocessorGroup()); | ||
} | ||
return extraPreprocessors; | ||
} | ||
function addExtraPreprocessors(options, config) { | ||
const extra = buildExtraPreprocessors(options, config); | ||
if ((extra == null ? void 0 : extra.length) > 0) { | ||
if (!options.preprocess) { | ||
options.preprocess = extra; | ||
} else if (Array.isArray(options.preprocess)) { | ||
options.preprocess.push(...extra); | ||
} else { | ||
options.preprocess = [options.preprocess, ...extra]; | ||
} | ||
} | ||
} | ||
// src/utils/constants.ts | ||
var VITE_RESOLVE_MAIN_FIELDS = ["module", "jsnext:main", "jsnext"]; | ||
var SVELTE_RESOLVE_MAIN_FIELDS = ["svelte", ...VITE_RESOLVE_MAIN_FIELDS]; | ||
var SVELTE_IMPORTS = [ | ||
"svelte/animate", | ||
"svelte/easing", | ||
"svelte/internal", | ||
"svelte/motion", | ||
"svelte/store", | ||
"svelte/transition", | ||
"svelte" | ||
]; | ||
var SVELTE_HMR_IMPORTS = [ | ||
"svelte-hmr/runtime/hot-api-esm.js", | ||
"svelte-hmr/runtime/proxy-adapter-dom.js", | ||
"svelte-hmr" | ||
]; | ||
@@ -537,3 +499,3 @@ // src/utils/options.ts | ||
]); | ||
function buildDefaultOptions({ isProduction }, options) { | ||
function buildDefaultOptions(isProduction, options) { | ||
const disableCssHmr = !!(options == null ? void 0 : options.disableCssHmr); | ||
@@ -607,21 +569,57 @@ const emitCss = (options == null ? void 0 : options.emitCss) != null ? options.emitCss : isProduction || !disableCssHmr; | ||
} | ||
function mergeOptions(defaultOptions, svelteConfig, inlineOptions, viteConfig) { | ||
return __spreadProps(__spreadValues(__spreadValues(__spreadValues({}, defaultOptions), svelteConfig), inlineOptions), { | ||
function mergeOptions(defaultOptions, svelteConfig, inlineOptions, viteConfig, viteEnv) { | ||
const merged = __spreadProps(__spreadValues(__spreadValues(__spreadValues({}, defaultOptions), svelteConfig), inlineOptions), { | ||
compilerOptions: __spreadValues(__spreadValues(__spreadValues({}, defaultOptions.compilerOptions), (svelteConfig == null ? void 0 : svelteConfig.compilerOptions) || {}), (inlineOptions == null ? void 0 : inlineOptions.compilerOptions) || {}), | ||
root: viteConfig.root, | ||
isProduction: viteConfig.isProduction, | ||
isBuild: viteConfig.command === "build", | ||
isServe: viteConfig.command === "serve" | ||
root: viteConfig.root || process.cwd(), | ||
isProduction: viteEnv.mode === "production", | ||
isBuild: viteEnv.command === "build", | ||
isServe: viteEnv.command === "serve" | ||
}); | ||
if (svelteConfig == null ? void 0 : svelteConfig.configFile) { | ||
merged.configFile = svelteConfig.configFile; | ||
} | ||
return merged; | ||
} | ||
async function resolveOptions(inlineOptions = {}, viteConfig) { | ||
const defaultOptions = buildDefaultOptions(viteConfig, inlineOptions); | ||
async function resolveOptions(inlineOptions = {}, viteConfig, viteEnv) { | ||
const defaultOptions = buildDefaultOptions(viteEnv.mode === "production", inlineOptions); | ||
const svelteConfig = await loadSvelteConfig(viteConfig, inlineOptions) || {}; | ||
const resolvedOptions = mergeOptions(defaultOptions, svelteConfig, inlineOptions, viteConfig); | ||
const resolvedOptions = mergeOptions(defaultOptions, svelteConfig, inlineOptions, viteConfig, viteEnv); | ||
enforceOptionsForProduction(resolvedOptions); | ||
enforceOptionsForHmr(resolvedOptions); | ||
addExtraPreprocessors(resolvedOptions, viteConfig); | ||
log.debug("resolved options", resolvedOptions); | ||
return resolvedOptions; | ||
} | ||
function buildExtraViteConfig(options, config) { | ||
var _a, _b, _c; | ||
const allSvelteImports = [...SVELTE_IMPORTS, ...SVELTE_HMR_IMPORTS]; | ||
const excludeFromOptimize = allSvelteImports.filter((x) => { | ||
var _a2, _b2; | ||
return !((_b2 = (_a2 = config.optimizeDeps) == null ? void 0 : _a2.include) == null ? void 0 : _b2.includes(x)); | ||
}); | ||
const extraViteConfig = { | ||
optimizeDeps: { | ||
exclude: excludeFromOptimize | ||
}, | ||
resolve: { | ||
mainFields: [...SVELTE_RESOLVE_MAIN_FIELDS], | ||
dedupe: allSvelteImports | ||
} | ||
}; | ||
if (options.isBuild && ((_a = config.build) == null ? void 0 : _a.ssr)) { | ||
if (!((_c = (_b = config.ssr) == null ? void 0 : _b.external) == null ? void 0 : _c.includes("svelte"))) { | ||
extraViteConfig.ssr = { | ||
noExternal: ["svelte"] | ||
}; | ||
} | ||
} | ||
if (options.useVitePreprocess) { | ||
extraViteConfig.esbuild = { | ||
tsconfigRaw: { | ||
compilerOptions: { | ||
importsNotUsedAsValues: "preserve" | ||
} | ||
} | ||
}; | ||
} | ||
return extraViteConfig; | ||
} | ||
@@ -696,4 +694,4 @@ // src/utils/vite-plugin-svelte-cache.ts | ||
} | ||
getDependants(path3) { | ||
const dependants = this._dependants.get(path3); | ||
getDependants(path4) { | ||
const dependants = this._dependants.get(path4); | ||
return dependants ? [...dependants] : []; | ||
@@ -703,22 +701,12 @@ } | ||
// src/utils/constants.ts | ||
var VITE_RESOLVE_MAIN_FIELDS = ["module", "jsnext:main", "jsnext"]; | ||
var SVELTE_RESOLVE_MAIN_FIELDS = ["svelte", ...VITE_RESOLVE_MAIN_FIELDS]; | ||
var SVELTE_IMPORTS = [ | ||
"svelte/animate", | ||
"svelte/easing", | ||
"svelte/internal", | ||
"svelte/motion", | ||
"svelte/store", | ||
"svelte/transition", | ||
"svelte", | ||
"svelte-hmr/runtime/hot-api-esm.js", | ||
"svelte-hmr/runtime/proxy-adapter-dom.js", | ||
"svelte-hmr" | ||
]; | ||
// src/utils/watch.ts | ||
import fs3 from "fs"; | ||
function setupWatchers(server, cache, requestParser) { | ||
const watcher = server.watcher; | ||
import path2 from "path"; | ||
function setupWatchers(options, cache, requestParser) { | ||
const { server, configFile: svelteConfigFile } = options; | ||
if (!server) { | ||
return; | ||
} | ||
const { watcher, ws } = server; | ||
const { configFile: viteConfigFile, root, server: serverConfig } = server.config; | ||
const emitChangeEventOnDependants = (filename) => { | ||
@@ -742,6 +730,41 @@ const dependants = cache.getDependants(filename); | ||
}; | ||
watcher.on("change", emitChangeEventOnDependants); | ||
watcher.on("unlink", (filename) => { | ||
removeUnlinkedFromCache(filename); | ||
emitChangeEventOnDependants(filename); | ||
const triggerViteRestart = (filename) => { | ||
if (!!viteConfigFile && !serverConfig.middlewareMode) { | ||
log.info(`svelte config changed: restarting vite server. - file: ${filename}`); | ||
watcher.emit("change", viteConfigFile); | ||
} else { | ||
const message = "Svelte config change detected, restart your dev process to apply the changes."; | ||
log.info(message, filename); | ||
ws.send({ | ||
type: "error", | ||
err: { message, stack: "", plugin: "vite-plugin-svelte", id: filename } | ||
}); | ||
} | ||
}; | ||
const possibleSvelteConfigs = knownSvelteConfigNames.map((cfg) => path2.join(root, cfg)); | ||
const restartOnConfigAdd = (filename) => { | ||
if (possibleSvelteConfigs.includes(filename)) { | ||
triggerViteRestart(filename); | ||
} | ||
}; | ||
const restartOnConfigChange = (filename) => { | ||
if (filename === svelteConfigFile) { | ||
triggerViteRestart(filename); | ||
} | ||
}; | ||
const listeners = { | ||
add: [], | ||
change: [emitChangeEventOnDependants], | ||
unlink: [removeUnlinkedFromCache, emitChangeEventOnDependants] | ||
}; | ||
if (svelteConfigFile) { | ||
listeners.change.push(restartOnConfigChange); | ||
listeners.unlink.push(restartOnConfigChange); | ||
} else { | ||
listeners.add.push(restartOnConfigAdd); | ||
} | ||
Object.entries(listeners).forEach(([evt, listeners2]) => { | ||
if (listeners2.length > 0) { | ||
watcher.on(evt, (filename) => listeners2.forEach((listener) => listener(filename))); | ||
} | ||
}); | ||
@@ -751,3 +774,3 @@ } | ||
// src/utils/resolve.ts | ||
import path2 from "path"; | ||
import path3 from "path"; | ||
import fs4 from "fs"; | ||
@@ -757,6 +780,6 @@ import relative from "require-relative"; | ||
if (importer && isBareImport(importee)) { | ||
const importeePkgFile = relative.resolve(`${importee}/package.json`, path2.dirname(importer)); | ||
const importeePkgFile = relative.resolve(`${importee}/package.json`, path3.dirname(importer)); | ||
const importeePkg = JSON.parse(fs4.readFileSync(importeePkgFile, { encoding: "utf-8" })); | ||
if (importeePkg.svelte) { | ||
return path2.resolve(path2.dirname(importeePkgFile), importeePkg.svelte); | ||
return path3.resolve(path3.dirname(importeePkgFile), importeePkg.svelte); | ||
} | ||
@@ -766,3 +789,3 @@ } | ||
function isBareImport(importee) { | ||
if (!importee || importee[0] === "." || importee[0] === "\0" || path2.isAbsolute(importee)) { | ||
if (!importee || importee[0] === "." || importee[0] === "\0" || path3.isAbsolute(importee)) { | ||
return false; | ||
@@ -781,2 +804,85 @@ } | ||
// src/utils/preprocess.ts | ||
import MagicString from "magic-string"; | ||
var supportedStyleLangs = ["css", "less", "sass", "scss", "styl", "stylus", "postcss"]; | ||
var supportedScriptLangs = ["ts"]; | ||
function createPreprocessorFromVitePlugin(config, options, pluginName, supportedLangs) { | ||
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`); | ||
} | ||
const pluginTransform = plugin.transform.bind(null); | ||
return async ({ attributes, content, filename }) => { | ||
var _a, _b, _c, _d; | ||
const lang = attributes.lang; | ||
if (!supportedLangs.includes(lang)) { | ||
return { code: content }; | ||
} | ||
const moduleId = `${filename}.${lang}`; | ||
const moduleGraph = (_a = options.server) == null ? void 0 : _a.moduleGraph; | ||
if (moduleGraph && !moduleGraph.getModuleById(moduleId)) { | ||
await moduleGraph.ensureEntryFromUrl(moduleId); | ||
} | ||
const transformResult = await pluginTransform(content, moduleId); | ||
const hasMap = !!((_b = transformResult.map) == null ? void 0 : _b.mappings); | ||
if (((_d = (_c = transformResult.map) == null ? void 0 : _c.sources) == null ? void 0 : _d[0]) === moduleId) { | ||
transformResult.map.sources[0] = filename; | ||
} | ||
return { | ||
code: transformResult.code, | ||
map: hasMap ? transformResult.map : null, | ||
dependencies: transformResult.deps | ||
}; | ||
}; | ||
} | ||
function createVitePreprocessorGroup(config, options) { | ||
return { | ||
script: createPreprocessorFromVitePlugin(config, options, "vite:esbuild", supportedScriptLangs), | ||
style: createPreprocessorFromVitePlugin(config, options, "vite:css", supportedStyleLangs) | ||
}; | ||
} | ||
function createInjectScopeEverythingRulePreprocessorGroup() { | ||
return { | ||
style({ content, filename }) { | ||
const s = new MagicString(content); | ||
s.append(" *{}"); | ||
return { | ||
code: s.toString(), | ||
map: s.generateDecodedMap({ file: filename }) | ||
}; | ||
} | ||
}; | ||
} | ||
function buildExtraPreprocessors(options, config) { | ||
const extraPreprocessors = []; | ||
if (options.useVitePreprocess) { | ||
log.debug("adding vite preprocessor"); | ||
extraPreprocessors.push(createVitePreprocessorGroup(config, options)); | ||
} | ||
const pluginsWithPreprocessors = config.plugins.filter((p) => p == null ? void 0 : p.sveltePreprocess); | ||
if (pluginsWithPreprocessors.length > 0) { | ||
log.debug(`adding preprocessors from other vite plugins: ${pluginsWithPreprocessors.map((p) => p.name).join(", ")}`); | ||
extraPreprocessors.push(...pluginsWithPreprocessors.map((p) => p.sveltePreprocess)); | ||
} | ||
if (options.hot && !options.disableCssHmr) { | ||
extraPreprocessors.push(createInjectScopeEverythingRulePreprocessorGroup()); | ||
} | ||
return extraPreprocessors; | ||
} | ||
function addExtraPreprocessors(options, config) { | ||
const extra = buildExtraPreprocessors(options, config); | ||
if ((extra == null ? void 0 : extra.length) > 0) { | ||
if (!options.preprocess) { | ||
options.preprocess = extra; | ||
} else if (Array.isArray(options.preprocess)) { | ||
options.preprocess.push(...extra); | ||
} else { | ||
options.preprocess = [options.preprocess, ...extra]; | ||
} | ||
} | ||
} | ||
// src/index.ts | ||
@@ -792,7 +898,9 @@ function svelte(inlineOptions) { | ||
let options; | ||
let viteConfig; | ||
let compileSvelte; | ||
let resolvedSvelteSSR; | ||
return { | ||
name: "vite-plugin-svelte", | ||
enforce: "pre", | ||
config(config) { | ||
async config(config, configEnv) { | ||
if (process.env.DEBUG) { | ||
@@ -803,20 +911,4 @@ log.setLevel("debug"); | ||
} | ||
const extraViteConfig = { | ||
optimizeDeps: { | ||
exclude: [...SVELTE_IMPORTS] | ||
}, | ||
resolve: { | ||
mainFields: [...SVELTE_RESOLVE_MAIN_FIELDS], | ||
dedupe: [...SVELTE_IMPORTS] | ||
} | ||
}; | ||
if (inlineOptions == null ? void 0 : inlineOptions.useVitePreprocess) { | ||
extraViteConfig.esbuild = { | ||
tsconfigRaw: { | ||
compilerOptions: { | ||
importsNotUsedAsValues: "preserve" | ||
} | ||
} | ||
}; | ||
} | ||
options = await resolveOptions(inlineOptions, config, configEnv); | ||
const extraViteConfig = buildExtraViteConfig(options, config); | ||
log.debug("additional vite config", extraViteConfig); | ||
@@ -826,19 +918,17 @@ return extraViteConfig; | ||
async configResolved(config) { | ||
options = await resolveOptions(inlineOptions, config); | ||
addExtraPreprocessors(options, config); | ||
requestParser = buildIdParser(options); | ||
compileSvelte = createCompileSvelte(options); | ||
viteConfig = config; | ||
log.debug("resolved options", options); | ||
}, | ||
configureServer(server) { | ||
options.server = server; | ||
setupWatchers(server, cache, requestParser); | ||
setupWatchers(options, cache, requestParser); | ||
}, | ||
load(id, ssr) { | ||
const svelteRequest = requestParser(id, !!ssr); | ||
if (!svelteRequest) { | ||
return; | ||
} | ||
log.debug("load", svelteRequest); | ||
const { filename, query } = svelteRequest; | ||
if (query.svelte) { | ||
if (query.type === "style") { | ||
if (svelteRequest) { | ||
const { filename, query } = svelteRequest; | ||
if (query.svelte && query.type === "style") { | ||
const css = cache.getCSS(svelteRequest); | ||
@@ -850,2 +940,6 @@ if (css) { | ||
} | ||
if (viteConfig.assetsInclude(filename)) { | ||
log.debug(`load returns raw content for ${filename}`); | ||
return fs5.readFileSync(filename, "utf-8"); | ||
} | ||
} | ||
@@ -855,3 +949,2 @@ }, | ||
const svelteRequest = requestParser(importee, !!ssr); | ||
log.debug("resolveId", svelteRequest || importee); | ||
if (svelteRequest == null ? void 0 : svelteRequest.query.svelte) { | ||
@@ -865,2 +958,14 @@ if (svelteRequest.query.type === "style") { | ||
} | ||
if (ssr && importee === "svelte") { | ||
if (!resolvedSvelteSSR) { | ||
resolvedSvelteSSR = this.resolve("svelte/ssr", void 0, { skipSelf: true }).then((svelteSSR) => { | ||
log.debug("resolved svelte to svelte/ssr"); | ||
return svelteSSR; | ||
}, (err) => { | ||
log.debug("failed to resolve svelte to svelte/ssr. Update svelte to a version that exports it", err); | ||
return null; | ||
}); | ||
} | ||
return resolvedSvelteSSR; | ||
} | ||
try { | ||
@@ -890,3 +995,2 @@ const resolved = resolveViaPackageJsonSvelte(importee, importer); | ||
} | ||
log.debug("transform", svelteRequest); | ||
const { filename, query } = svelteRequest; | ||
@@ -918,11 +1022,6 @@ if (query.svelte) { | ||
const svelteRequest = requestParser(ctx.file, false, ctx.timestamp); | ||
if (!svelteRequest) { | ||
return; | ||
if (svelteRequest) { | ||
return handleHotUpdate(compileSvelte, ctx, svelteRequest, cache, options); | ||
} | ||
log.debug("handleHotUpdate", svelteRequest); | ||
return handleHotUpdate(compileSvelte, ctx, svelteRequest, cache, options); | ||
}, | ||
transformIndexHtml(html, ctx) { | ||
log.debug("transformIndexHtml", html); | ||
}, | ||
buildEnd() { | ||
@@ -929,0 +1028,0 @@ if (pkg_export_errors.size > 0) { |
127
package.json
{ | ||
"name": "@sveltejs/vite-plugin-svelte", | ||
"version": "1.0.0-next.11", | ||
"license": "MIT", | ||
"author": "dominikg", | ||
"files": [ | ||
"dist", | ||
"src", | ||
"README.md", | ||
"LICENSE", | ||
"package.json" | ||
], | ||
"type": "module", | ||
"main": "dist/index.cjs", | ||
"module": "dist/index.js", | ||
"types": "dist/index.d.ts", | ||
"exports": { | ||
".": { | ||
"import": "./dist/index.js", | ||
"require": "./dist/index.cjs" | ||
}, | ||
"./package.json": "./package.json" | ||
}, | ||
"scripts": { | ||
"dev": "pnpm run build:ci -- --watch src", | ||
"build:ci": "rimraf dist && tsup-node src/index.ts --format esm,cjs --no-splitting", | ||
"build": "pnpm run build:ci -- --dts --dts-resolve --sourcemap" | ||
}, | ||
"engines": { | ||
"node": "^12.20 || ^14.13.1 || >= 16" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/sveltejs/vite-plugin-svelte.git" | ||
}, | ||
"keywords": [ | ||
"vite-plugin", | ||
"vite plugin", | ||
"vite", | ||
"svelte" | ||
], | ||
"bugs": { | ||
"url": "https://github.com/sveltejs/vite-plugin-svelte/issues" | ||
}, | ||
"homepage": "https://github.com/sveltejs/vite-plugin-svelte/tree/main/packages/vite-plugin-svelte#readme", | ||
"dependencies": { | ||
"@rollup/pluginutils": "^4.1.0", | ||
"chalk": "^4.1.1", | ||
"debug": "^4.3.2", | ||
"require-relative": "^0.8.7", | ||
"svelte-hmr": "^0.14.4" | ||
}, | ||
"peerDependencies": { | ||
"svelte": "^3.38.2", | ||
"vite": "^2.3.7" | ||
}, | ||
"devDependencies": { | ||
"@types/debug": "^4.1.5", | ||
"esbuild": "^0.12.8", | ||
"rollup": "^2.51.1", | ||
"svelte": "^3.38.2", | ||
"tsup": "^4.11.2", | ||
"vite": "^2.3.7" | ||
} | ||
"name": "@sveltejs/vite-plugin-svelte", | ||
"version": "1.0.0-next.12", | ||
"license": "MIT", | ||
"author": "dominikg", | ||
"files": [ | ||
"dist", | ||
"src", | ||
"README.md", | ||
"LICENSE", | ||
"package.json" | ||
], | ||
"type": "module", | ||
"main": "dist/index.cjs", | ||
"module": "dist/index.js", | ||
"types": "dist/index.d.ts", | ||
"exports": { | ||
".": { | ||
"import": "./dist/index.js", | ||
"require": "./dist/index.cjs" | ||
}, | ||
"./package.json": "./package.json" | ||
}, | ||
"scripts": { | ||
"dev": "pnpm run build:ci -- --watch src", | ||
"build:ci": "rimraf dist && tsup-node src/index.ts --format esm,cjs --no-splitting", | ||
"build": "pnpm run build:ci -- --dts --dts-resolve --sourcemap" | ||
}, | ||
"engines": { | ||
"node": "^12.20 || ^14.13.1 || >= 16" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/sveltejs/vite-plugin-svelte.git" | ||
}, | ||
"keywords": [ | ||
"vite-plugin", | ||
"vite plugin", | ||
"vite", | ||
"svelte" | ||
], | ||
"bugs": { | ||
"url": "https://github.com/sveltejs/vite-plugin-svelte/issues" | ||
}, | ||
"homepage": "https://github.com/sveltejs/vite-plugin-svelte/tree/main/packages/vite-plugin-svelte#readme", | ||
"dependencies": { | ||
"@rollup/pluginutils": "^4.1.0", | ||
"debug": "^4.3.2", | ||
"kleur": "^4.1.4", | ||
"magic-string": "^0.25.7", | ||
"require-relative": "^0.8.7", | ||
"svelte-hmr": "^0.14.5" | ||
}, | ||
"peerDependencies": { | ||
"svelte": "^3.34.0", | ||
"vite": "^2.3.7" | ||
}, | ||
"devDependencies": { | ||
"@types/debug": "^4.1.6", | ||
"esbuild": "^0.12.15", | ||
"rollup": "^2.53.0", | ||
"svelte": "^3.38.3", | ||
"tsup": "^4.12.5", | ||
"vite": "^2.4.1" | ||
} | ||
} |
@@ -66,3 +66,3 @@ # @sveltejs/vite-plugin-svelte | ||
This is needed because Vite's dependency pre-bundling doesn't deduplicate the Svelte instance, resulting in multiple Svelte instance running at once, causing errors like `Function called outside component initialization`. | ||
This is needed because [Vite's dependency pre-bundling doesn't deduplicate the Svelte instance](https://github.com/vitejs/vite/issues/3910), resulting in multiple Svelte instance running at once, causing errors like `Function called outside component initialization`. | ||
@@ -90,4 +90,52 @@ If you're unsure whether a library uses the lifecycle API, place it in `optimizeDeps.exclude` and you'll be fine. The team is working on removing this limitation soon. | ||
## FAQ | ||
### Why is component state reset on hmr update? | ||
Preservation of local component state after js updates is disabled to avoid unpredictable and errorprone behavior. You can read more about it [here](https://github.com/rixo/svelte-hmr#preservation-of-local-state). | ||
Please note that if you only edit the `style` node, a separate css update can be applied where component state is 100% preserved. | ||
### What is the recommended node order for svelte sfc files? | ||
The `<style>` node should be last to ensure optimal hmr results. | ||
This is also the default order with [prettier-plugin-svelte](https://github.com/sveltejs/prettier-plugin-svelte) | ||
Good: | ||
```sveltehtml | ||
<script></script> | ||
<div></div> | ||
<style></style> | ||
``` | ||
Bad: | ||
```sveltehtml | ||
<script></script> | ||
<style></style> | ||
<!-- this template element is below the style node and may cause extra js hmr updates --> | ||
<div></div> | ||
``` | ||
### Why isn't vite detecting my imports correctly in `.svelte` files with typescript? | ||
You have to use the `lang="ts"` attribute for vite to parse it. Never `lang="typescript"` or `type="text/typescript"` | ||
Good: | ||
```sveltehtml | ||
<script lang="ts"></script> | ||
``` | ||
Bad: | ||
```sveltehtml | ||
<!-- these are not detected by vite --> | ||
<script lang="typescript"></script> | ||
<script type="text/typescript"></script> | ||
``` | ||
## License | ||
MIT | ||
[MIT](./LICENSE) |
@@ -54,3 +54,2 @@ import { ModuleNode, HmrContext } from 'vite'; | ||
const result = [...affectedModules].filter(Boolean) as ModuleNode[]; | ||
log.debug(`handleHotUpdate result for ${svelteRequest.id}`, result); | ||
@@ -63,3 +62,7 @@ // TODO is this enough? see also: https://github.com/vitejs/vite/issues/2274 | ||
} | ||
if (result.length > 0) { | ||
log.debug( | ||
`handleHotUpdate for ${svelteRequest.id} result: ${result.map((m) => m.id).join(', ')}` | ||
); | ||
} | ||
return result; | ||
@@ -66,0 +69,0 @@ } |
@@ -1,2 +0,3 @@ | ||
import { HmrContext, IndexHtmlTransformContext, ModuleNode, Plugin, UserConfig } from 'vite'; | ||
import fs from 'fs'; | ||
import { HmrContext, ModuleNode, Plugin, ResolvedConfig, UserConfig } from 'vite'; | ||
import { handleHotUpdate } from './handle-hot-update'; | ||
@@ -7,2 +8,3 @@ import { log, logCompilerWarnings } from './utils/log'; | ||
import { | ||
buildExtraViteConfig, | ||
validateInlineOptions, | ||
@@ -16,5 +18,6 @@ Options, | ||
import { SVELTE_IMPORTS, SVELTE_RESOLVE_MAIN_FIELDS } from './utils/constants'; | ||
import { setupWatchers } from './utils/watch'; | ||
import { resolveViaPackageJsonSvelte } from './utils/resolve'; | ||
import { addExtraPreprocessors } from './utils/preprocess'; | ||
import { PartialResolvedId } from 'rollup'; | ||
@@ -39,3 +42,3 @@ // extend the Vite plugin interface to be able to have `sveltePreprocess` injection | ||
let options: ResolvedOptions; | ||
let viteConfig: ResolvedConfig; | ||
/* eslint-disable no-unused-vars */ | ||
@@ -49,2 +52,4 @@ let compileSvelte: ( | ||
let resolvedSvelteSSR: Promise<PartialResolvedId | null>; | ||
return { | ||
@@ -54,3 +59,3 @@ name: 'vite-plugin-svelte', | ||
enforce: 'pre', | ||
config(config): Partial<UserConfig> { | ||
async config(config, configEnv): Promise<Partial<UserConfig>> { | ||
// setup logger | ||
@@ -62,24 +67,5 @@ if (process.env.DEBUG) { | ||
} | ||
options = await resolveOptions(inlineOptions, config, configEnv); | ||
// extra vite config | ||
const extraViteConfig: Partial<UserConfig> = { | ||
optimizeDeps: { | ||
exclude: [...SVELTE_IMPORTS] | ||
}, | ||
resolve: { | ||
mainFields: [...SVELTE_RESOLVE_MAIN_FIELDS], | ||
dedupe: [...SVELTE_IMPORTS] | ||
} | ||
}; | ||
// needed to transform svelte files with component imports | ||
// can cause issues with other typescript files, see https://github.com/sveltejs/vite-plugin-svelte/pull/20 | ||
if (inlineOptions?.useVitePreprocess) { | ||
extraViteConfig.esbuild = { | ||
tsconfigRaw: { | ||
compilerOptions: { | ||
importsNotUsedAsValues: 'preserve' | ||
} | ||
} | ||
}; | ||
} | ||
const extraViteConfig = buildExtraViteConfig(options, config); | ||
log.debug('additional vite config', extraViteConfig); | ||
@@ -90,5 +76,7 @@ return extraViteConfig as Partial<UserConfig>; | ||
async configResolved(config) { | ||
options = await resolveOptions(inlineOptions, config); | ||
addExtraPreprocessors(options, config); | ||
requestParser = buildIdParser(options); | ||
compileSvelte = createCompileSvelte(options); | ||
viteConfig = config; | ||
log.debug('resolved options', options); | ||
}, | ||
@@ -99,3 +87,3 @@ | ||
options.server = server; | ||
setupWatchers(server, cache, requestParser); | ||
setupWatchers(options, cache, requestParser); | ||
}, | ||
@@ -105,12 +93,6 @@ | ||
const svelteRequest = requestParser(id, !!ssr); | ||
if (!svelteRequest) { | ||
return; | ||
} | ||
log.debug('load', svelteRequest); | ||
const { filename, query } = svelteRequest; | ||
// | ||
if (query.svelte) { | ||
if (query.type === 'style') { | ||
if (svelteRequest) { | ||
const { filename, query } = svelteRequest; | ||
// virtual css module | ||
if (query.svelte && query.type === 'style') { | ||
const css = cache.getCSS(svelteRequest); | ||
@@ -122,2 +104,7 @@ if (css) { | ||
} | ||
// prevent vite asset plugin from loading files as url that should be compiled in transform | ||
if (viteConfig.assetsInclude(filename)) { | ||
log.debug(`load returns raw content for ${filename}`); | ||
return fs.readFileSync(filename, 'utf-8'); | ||
} | ||
} | ||
@@ -128,3 +115,2 @@ }, | ||
const svelteRequest = requestParser(importee, !!ssr); | ||
log.debug('resolveId', svelteRequest || importee); | ||
if (svelteRequest?.query.svelte) { | ||
@@ -141,2 +127,21 @@ if (svelteRequest.query.type === 'style') { | ||
if (ssr && importee === 'svelte') { | ||
if (!resolvedSvelteSSR) { | ||
resolvedSvelteSSR = this.resolve('svelte/ssr', undefined, { skipSelf: true }).then( | ||
(svelteSSR) => { | ||
log.debug('resolved svelte to svelte/ssr'); | ||
return svelteSSR; | ||
}, | ||
(err) => { | ||
log.debug( | ||
'failed to resolve svelte to svelte/ssr. Update svelte to a version that exports it', | ||
err | ||
); | ||
return null; // returning null here leads to svelte getting resolved regularly | ||
} | ||
); | ||
} | ||
return resolvedSvelteSSR; | ||
} | ||
try { | ||
@@ -166,3 +171,2 @@ const resolved = resolveViaPackageJsonSvelte(importee, importer); | ||
} | ||
log.debug('transform', svelteRequest); | ||
const { filename, query } = svelteRequest; | ||
@@ -196,14 +200,7 @@ | ||
const svelteRequest = requestParser(ctx.file, false, ctx.timestamp); | ||
if (!svelteRequest) { | ||
return; | ||
if (svelteRequest) { | ||
return handleHotUpdate(compileSvelte, ctx, svelteRequest, cache, options); | ||
} | ||
log.debug('handleHotUpdate', svelteRequest); | ||
return handleHotUpdate(compileSvelte, ctx, svelteRequest, cache, options); | ||
}, | ||
// eslint-disable-next-line no-unused-vars | ||
transformIndexHtml(html: string, ctx: IndexHtmlTransformContext) { | ||
// TODO useful for ssr? and maybe svelte:head stuff | ||
log.debug('transformIndexHtml', html); | ||
}, | ||
/** | ||
@@ -210,0 +207,0 @@ * All resolutions done; display warnings wrt `package.json` access. |
@@ -12,3 +12,6 @@ const VITE_RESOLVE_MAIN_FIELDS = ['module', 'jsnext:main', 'jsnext']; | ||
'svelte/transition', | ||
'svelte', | ||
'svelte' | ||
]; | ||
export const SVELTE_HMR_IMPORTS = [ | ||
'svelte-hmr/runtime/hot-api-esm.js', | ||
@@ -15,0 +18,0 @@ 'svelte-hmr/runtime/proxy-adapter-dom.js', |
@@ -10,7 +10,12 @@ /* eslint-disable no-unused-vars */ | ||
const IS_WINDOWS = process.platform === 'win32'; | ||
export type SvelteQueryTypes = 'style' | 'script'; | ||
export interface SvelteQuery { | ||
export interface RequestQuery { | ||
// our own | ||
svelte?: boolean; | ||
type?: SvelteQueryTypes; | ||
// vite specific | ||
url?: boolean; | ||
raw?: boolean; | ||
} | ||
@@ -23,3 +28,3 @@ | ||
normalizedFilename: string; | ||
query: SvelteQuery; | ||
query: RequestQuery; | ||
timestamp: number; | ||
@@ -43,8 +48,14 @@ ssr: boolean; | ||
ssr: boolean | ||
): SvelteRequest { | ||
const query = qs.parse(rawQuery) as SvelteQuery; | ||
if (query.svelte != null) { | ||
query.svelte = true; | ||
): SvelteRequest | undefined { | ||
const query: RequestQuery = qs.parse(rawQuery) as RequestQuery; | ||
for (const p of ['svelte', 'url', 'raw'] as Array<keyof RequestQuery>) { | ||
if (query[p] != null) { | ||
// @ts-ignore | ||
query[p] = true; | ||
} | ||
} | ||
if (query.url || query.raw) { | ||
// skip requests with special vite tags | ||
return; | ||
} | ||
const normalizedFilename = normalize(filename, root); | ||
@@ -51,0 +62,0 @@ const cssId = createVirtualImportId(filename, root, 'style'); |
@@ -6,16 +6,23 @@ import path from 'path'; | ||
import { Options } from './options'; | ||
import { ResolvedConfig } from 'vite'; | ||
import { UserConfig } from 'vite'; | ||
const knownSvelteConfigNames = ['svelte.config.js', 'svelte.config.cjs', 'svelte.config.mjs']; | ||
export const knownSvelteConfigNames = [ | ||
'svelte.config.js', | ||
'svelte.config.cjs', | ||
'svelte.config.mjs' | ||
]; | ||
// hide dynamic import from ts transform to prevent it turning into a require | ||
// see https://github.com/microsoft/TypeScript/issues/43329#issuecomment-811606238 | ||
const dynamicImportDefault = new Function('path', 'return import(path).then(m => m.default)'); | ||
// also use timestamp query to avoid caching on reload | ||
const dynamicImportDefault = new Function( | ||
'path', | ||
'return import(path + "?t=" + Date.now()).then(m => m.default)' | ||
); | ||
export async function loadSvelteConfig( | ||
viteConfig: ResolvedConfig, | ||
viteConfig: UserConfig, | ||
inlineOptions: Partial<Options> | ||
) { | ||
): Promise<Partial<Options> | undefined> { | ||
const configFile = findConfigToLoad(viteConfig, inlineOptions); | ||
if (configFile) { | ||
@@ -26,3 +33,11 @@ let err; | ||
try { | ||
return await dynamicImportDefault(pathToFileURL(configFile).href); | ||
const result = await dynamicImportDefault(pathToFileURL(configFile).href); | ||
if (result != null) { | ||
return { | ||
...result, | ||
configFile | ||
}; | ||
} else { | ||
throw new Error(`invalid export in ${configFile}`); | ||
} | ||
} catch (e) { | ||
@@ -34,8 +49,20 @@ log.error(`failed to import config ${configFile}`, e); | ||
// cjs or error with dynamic import | ||
try { | ||
return require(configFile); | ||
} catch (e) { | ||
log.error(`failed to require config ${configFile}`, e); | ||
if (!err) { | ||
err = e; | ||
if (!configFile.endsWith('.mjs')) { | ||
try { | ||
// avoid loading cached version on reload | ||
delete require.cache[require.resolve(configFile)]; | ||
const result = require(configFile); | ||
if (result != null) { | ||
return { | ||
...result, | ||
configFile | ||
}; | ||
} else { | ||
throw new Error(`invalid export in ${configFile}`); | ||
} | ||
} catch (e) { | ||
log.error(`failed to require config ${configFile}`, e); | ||
if (!err) { | ||
err = e; | ||
} | ||
} | ||
@@ -48,3 +75,3 @@ } | ||
function findConfigToLoad(viteConfig: ResolvedConfig, inlineOptions: Partial<Options>) { | ||
function findConfigToLoad(viteConfig: UserConfig, inlineOptions: Partial<Options>) { | ||
const root = viteConfig.root || process.cwd(); | ||
@@ -51,0 +78,0 @@ if (inlineOptions.configFile) { |
/* eslint-disable no-unused-vars */ | ||
import chalk from 'chalk'; | ||
import { cyan, yellow, red } from 'kleur/colors'; | ||
import debug from 'debug'; | ||
@@ -15,3 +15,3 @@ import { ResolvedOptions, Warning } from './options'; | ||
info: { | ||
color: chalk.cyan, | ||
color: cyan, | ||
log: console.log, | ||
@@ -21,3 +21,3 @@ enabled: true | ||
warn: { | ||
color: chalk.yellow, | ||
color: yellow, | ||
log: console.warn, | ||
@@ -27,3 +27,3 @@ enabled: true | ||
error: { | ||
color: chalk.red, | ||
color: red, | ||
log: console.error, | ||
@@ -53,7 +53,2 @@ enabled: true | ||
let _viteLogOverwriteProtection = false; | ||
function setViteLogOverwriteProtection(viteLogOverwriteProtection: boolean) { | ||
_viteLogOverwriteProtection = viteLogOverwriteProtection; | ||
} | ||
function _log(logger: any, message: string, payload?: any) { | ||
@@ -66,3 +61,3 @@ if (!logger.enabled) { | ||
} else { | ||
logger.log(logger.color(`[${prefix}] ${message}`)); | ||
logger.log(logger.color(`${new Date().toLocaleTimeString()} [${prefix}] ${message}`)); | ||
if (payload) { | ||
@@ -72,5 +67,2 @@ logger.log(payload); | ||
} | ||
if (_viteLogOverwriteProtection) { | ||
logger.log(''); | ||
} | ||
} | ||
@@ -99,6 +91,3 @@ | ||
error: createLogger('error'), | ||
setLevel, | ||
// TODO still needed? | ||
setViteLogOverwriteProtection | ||
setLevel | ||
}; | ||
@@ -105,0 +94,0 @@ |
/* eslint-disable no-unused-vars */ | ||
import { ResolvedConfig, ViteDevServer } from 'vite'; | ||
import { ConfigEnv, UserConfig, ViteDevServer } from 'vite'; | ||
import { log } from './log'; | ||
import { loadSvelteConfig } from './load-svelte-config'; | ||
import { addExtraPreprocessors } from './preprocess'; | ||
import { SVELTE_HMR_IMPORTS, SVELTE_IMPORTS, SVELTE_RESOLVE_MAIN_FIELDS } from './constants'; | ||
@@ -21,6 +21,3 @@ const knownOptions = new Set([ | ||
function buildDefaultOptions( | ||
{ isProduction }: ResolvedConfig, | ||
options: Partial<Options> | ||
): Partial<Options> { | ||
function buildDefaultOptions(isProduction: boolean, options: Partial<Options>): Partial<Options> { | ||
const disableCssHmr = !!options?.disableCssHmr; | ||
@@ -119,5 +116,6 @@ // emit for prod, emit in dev unless css hmr is disabled | ||
inlineOptions: Partial<Options>, | ||
viteConfig: ResolvedConfig | ||
viteConfig: UserConfig, | ||
viteEnv: ConfigEnv | ||
): ResolvedOptions { | ||
return { | ||
const merged = { | ||
...defaultOptions, | ||
@@ -131,7 +129,13 @@ ...svelteConfig, | ||
}, | ||
root: viteConfig.root, | ||
isProduction: viteConfig.isProduction, | ||
isBuild: viteConfig.command === 'build', | ||
isServe: viteConfig.command === 'serve' | ||
root: viteConfig.root || process.cwd(), | ||
isProduction: viteEnv.mode === 'production', | ||
isBuild: viteEnv.command === 'build', | ||
isServe: viteEnv.command === 'serve' | ||
}; | ||
// configFile of svelteConfig contains the absolute path it was loaded from, | ||
// prefer it over the possibly relative inline path | ||
if (svelteConfig?.configFile) { | ||
merged.configFile = svelteConfig.configFile; | ||
} | ||
return merged; | ||
} | ||
@@ -141,17 +145,71 @@ | ||
inlineOptions: Partial<Options> = {}, | ||
viteConfig: ResolvedConfig | ||
viteConfig: UserConfig, | ||
viteEnv: ConfigEnv | ||
): Promise<ResolvedOptions> { | ||
const defaultOptions = buildDefaultOptions(viteConfig, inlineOptions); | ||
const defaultOptions = buildDefaultOptions(viteEnv.mode === 'production', inlineOptions); | ||
const svelteConfig = (await loadSvelteConfig(viteConfig, inlineOptions)) || {}; | ||
const resolvedOptions = mergeOptions(defaultOptions, svelteConfig, inlineOptions, viteConfig); | ||
const resolvedOptions = mergeOptions( | ||
defaultOptions, | ||
svelteConfig, | ||
inlineOptions, | ||
viteConfig, | ||
viteEnv | ||
); | ||
enforceOptionsForProduction(resolvedOptions); | ||
enforceOptionsForHmr(resolvedOptions); | ||
addExtraPreprocessors(resolvedOptions, viteConfig); | ||
log.debug('resolved options', resolvedOptions); | ||
return resolvedOptions; | ||
} | ||
export function buildExtraViteConfig( | ||
options: ResolvedOptions, | ||
config: UserConfig | ||
): Partial<UserConfig> { | ||
const allSvelteImports = [...SVELTE_IMPORTS, ...SVELTE_HMR_IMPORTS]; | ||
// exclude svelte imports from optimization unless explicitly included | ||
const excludeFromOptimize = allSvelteImports.filter( | ||
(x) => !config.optimizeDeps?.include?.includes(x) | ||
); | ||
const extraViteConfig: Partial<UserConfig> = { | ||
optimizeDeps: { | ||
exclude: excludeFromOptimize | ||
}, | ||
resolve: { | ||
mainFields: [...SVELTE_RESOLVE_MAIN_FIELDS], | ||
dedupe: allSvelteImports | ||
} | ||
// this option is still awaiting a PR in vite to be supported | ||
// see https://github.com/sveltejs/vite-plugin-svelte/issues/60 | ||
// @ts-ignore | ||
// knownJsSrcExtensions: options.extensions | ||
}; | ||
if (options.isBuild && config.build?.ssr) { | ||
// add svelte to ssr.noExternal unless it is present in ssr.external | ||
// so we can resolve it with svelte/ssr | ||
// @ts-ignore | ||
if (!config.ssr?.external?.includes('svelte')) { | ||
// @ts-ignore | ||
extraViteConfig.ssr = { | ||
noExternal: ['svelte'] | ||
}; | ||
} | ||
} | ||
if (options.useVitePreprocess) { | ||
// needed to transform svelte files with component imports | ||
// can cause issues with other typescript files, see https://github.com/sveltejs/vite-plugin-svelte/pull/20 | ||
extraViteConfig.esbuild = { | ||
tsconfigRaw: { | ||
compilerOptions: { | ||
importsNotUsedAsValues: 'preserve' | ||
} | ||
} | ||
}; | ||
} | ||
return extraViteConfig; | ||
} | ||
export interface Options { | ||
@@ -158,0 +216,0 @@ // eslint-disable no-unused-vars |
import { ResolvedConfig, TransformResult } from 'vite'; | ||
import MagicString from 'magic-string'; | ||
import { Preprocessor, PreprocessorGroup, ResolvedOptions } from './options'; | ||
@@ -70,5 +71,8 @@ import { TransformPluginContext } from 'rollup'; | ||
return { | ||
style({ content }) { | ||
style({ content, filename }) { | ||
const s = new MagicString(content); | ||
s.append(' *{}'); | ||
return { | ||
code: `${content} *{}` | ||
code: s.toString(), | ||
map: s.generateDecodedMap({ file: filename }) | ||
}; | ||
@@ -75,0 +79,0 @@ } |
@@ -1,2 +0,1 @@ | ||
import { ViteDevServer } from 'vite'; | ||
import { VitePluginSvelteCache } from './vite-plugin-svelte-cache'; | ||
@@ -6,9 +5,17 @@ import fs from 'fs'; | ||
import { IdParser } from './id'; | ||
import { ResolvedOptions } from './options'; | ||
import { knownSvelteConfigNames } from './load-svelte-config'; | ||
import path from 'path'; | ||
export function setupWatchers( | ||
server: ViteDevServer, | ||
options: ResolvedOptions, | ||
cache: VitePluginSvelteCache, | ||
requestParser: IdParser | ||
) { | ||
const watcher = server.watcher; | ||
const { server, configFile: svelteConfigFile } = options; | ||
if (!server) { | ||
return; | ||
} | ||
const { watcher, ws } = server; | ||
const { configFile: viteConfigFile, root, server: serverConfig } = server.config; | ||
@@ -37,7 +44,51 @@ const emitChangeEventOnDependants = (filename: string) => { | ||
watcher.on('change', emitChangeEventOnDependants); | ||
watcher.on('unlink', (filename) => { | ||
removeUnlinkedFromCache(filename); | ||
emitChangeEventOnDependants(filename); | ||
const triggerViteRestart = (filename: string) => { | ||
// vite restart is triggered by simulating a change to vite config. This requires that vite config exists | ||
// also we do not restart in middleware-mode as it could be risky | ||
if (!!viteConfigFile && !serverConfig.middlewareMode) { | ||
log.info(`svelte config changed: restarting vite server. - file: ${filename}`); | ||
watcher.emit('change', viteConfigFile); | ||
} else { | ||
const message = | ||
'Svelte config change detected, restart your dev process to apply the changes.'; | ||
log.info(message, filename); | ||
ws.send({ | ||
type: 'error', | ||
err: { message, stack: '', plugin: 'vite-plugin-svelte', id: filename } | ||
}); | ||
} | ||
}; | ||
const possibleSvelteConfigs = knownSvelteConfigNames.map((cfg) => path.join(root, cfg)); | ||
const restartOnConfigAdd = (filename: string) => { | ||
if (possibleSvelteConfigs.includes(filename)) { | ||
triggerViteRestart(filename); | ||
} | ||
}; | ||
const restartOnConfigChange = (filename: string) => { | ||
if (filename === svelteConfigFile) { | ||
triggerViteRestart(filename); | ||
} | ||
}; | ||
// collection of watcher listeners by event | ||
const listeners = { | ||
add: [], | ||
change: [emitChangeEventOnDependants], | ||
unlink: [removeUnlinkedFromCache, emitChangeEventOnDependants] | ||
}; | ||
if (svelteConfigFile) { | ||
listeners.change.push(restartOnConfigChange); | ||
listeners.unlink.push(restartOnConfigChange); | ||
} else { | ||
// @ts-ignore | ||
listeners.add.push(restartOnConfigAdd); | ||
} | ||
Object.entries(listeners).forEach(([evt, listeners]) => { | ||
if (listeners.length > 0) { | ||
watcher.on(evt, (filename) => listeners.forEach((listener) => listener(filename))); | ||
} | ||
}); | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
275024
3725
140
2
8
17
+ Addedkleur@^4.1.4
+ Addedmagic-string@^0.25.7
+ Addedkleur@4.1.5(transitive)
+ Addedmagic-string@0.25.9(transitive)
+ Addedsourcemap-codec@1.4.8(transitive)
- Removedchalk@^4.1.1
- Removedansi-styles@4.3.0(transitive)
- Removedchalk@4.1.2(transitive)
- Removedcolor-convert@2.0.1(transitive)
- Removedcolor-name@1.1.4(transitive)
- Removedhas-flag@4.0.0(transitive)
- Removedsupports-color@7.2.0(transitive)
Updatedsvelte-hmr@^0.14.5