From 836844491a9af259471da82bbf47a6319bd7a280 Mon Sep 17 00:00:00 2001 From: dominikg Date: Sun, 18 Apr 2021 00:18:45 +0200 Subject: [PATCH] feat(vite-plugin-svelte): support esm in svelte.config.js (see #29) --- .changeset/blue-schools-bake.md | 5 ++++ packages/vite-plugin-svelte/src/index.ts | 7 +++--- .../vite-plugin-svelte/src/utils/compile.ts | 23 +++++-------------- .../src/utils/loadSvelteConfig.ts | 8 +++++-- .../vite-plugin-svelte/src/utils/options.ts | 8 ++++--- .../src/utils/preprocess.ts | 15 +++++++++++- 6 files changed, 39 insertions(+), 27 deletions(-) create mode 100644 .changeset/blue-schools-bake.md diff --git a/.changeset/blue-schools-bake.md b/.changeset/blue-schools-bake.md new file mode 100644 index 000000000..596232bdb --- /dev/null +++ b/.changeset/blue-schools-bake.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/vite-plugin-svelte': patch +--- + +Feature: Support esm in svelte.config.js diff --git a/packages/vite-plugin-svelte/src/index.ts b/packages/vite-plugin-svelte/src/index.ts index 541ae2580..58b900962 100644 --- a/packages/vite-plugin-svelte/src/index.ts +++ b/packages/vite-plugin-svelte/src/index.ts @@ -91,11 +91,10 @@ export default function vitePluginSvelte(inlineOptions?: Partial): Plug return extraViteConfig as Partial; }, - configResolved(config) { - options = resolveOptions(inlineOptions, config); + async configResolved(config) { + options = await resolveOptions(inlineOptions, config); requestParser = buildIdParser(options); - // init compiler - compileSvelte = createCompileSvelte(options, config); + compileSvelte = createCompileSvelte(options); }, configureServer(server) { diff --git a/packages/vite-plugin-svelte/src/utils/compile.ts b/packages/vite-plugin-svelte/src/utils/compile.ts index 3a7ee0265..dc13b6b96 100644 --- a/packages/vite-plugin-svelte/src/utils/compile.ts +++ b/packages/vite-plugin-svelte/src/utils/compile.ts @@ -1,14 +1,12 @@ -import { CompileOptions, PreprocessorGroup, ResolvedOptions } from './options'; +import { CompileOptions, ResolvedOptions } from './options'; import { compile, preprocess, walk } from 'svelte/compiler'; // @ts-ignore import { createMakeHot } from 'svelte-hmr'; import { SvelteRequest } from './id'; import { safeBase64Hash } from './hash'; import { log } from './log'; -import { ResolvedConfig } from 'vite'; -import { buildExtraPreprocessors } from './preprocess'; -const _createCompileSvelte = (makeHot: Function, extraPreprocessors: PreprocessorGroup[]) => +const _createCompileSvelte = (makeHot: Function) => async function compileSvelte( svelteRequest: SvelteRequest, code: string, @@ -31,17 +29,9 @@ const _createCompileSvelte = (makeHot: Function, extraPreprocessors: Preprocesso } let preprocessed; - const preprocessors = []; + if (options.preprocess) { - if (Array.isArray(options.preprocess)) { - preprocessors.push(...options.preprocess); - } else { - preprocessors.push(options.preprocess); - } - } - preprocessors.push(...(extraPreprocessors || [])); - if (preprocessors.length > 0) { - preprocessed = await preprocess(code, preprocessors, { filename }); + preprocessed = await preprocess(code, options.preprocess, { filename }); if (preprocessed.dependencies) dependencies.push(...preprocessed.dependencies); if (preprocessed.map) finalCompilerOptions.sourcemap = preprocessed.map; } @@ -97,10 +87,9 @@ function buildMakeHot(options: ResolvedOptions) { } } -export function createCompileSvelte(options: ResolvedOptions, config: ResolvedConfig) { +export function createCompileSvelte(options: ResolvedOptions) { const makeHot = buildMakeHot(options); - const extraPreprocessors = buildExtraPreprocessors(options, config); - return _createCompileSvelte(makeHot, extraPreprocessors); + return _createCompileSvelte(makeHot); } export interface Code { diff --git a/packages/vite-plugin-svelte/src/utils/loadSvelteConfig.ts b/packages/vite-plugin-svelte/src/utils/loadSvelteConfig.ts index 84360be42..22245c9c4 100644 --- a/packages/vite-plugin-svelte/src/utils/loadSvelteConfig.ts +++ b/packages/vite-plugin-svelte/src/utils/loadSvelteConfig.ts @@ -4,7 +4,11 @@ import { log } from './log'; const knownSvelteConfigNames = ['svelte.config.js', 'svelte.config.cjs']; -export function loadSvelteConfig(root: string = process.cwd()) { +// 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)'); + +export async function loadSvelteConfig(root: string = process.cwd()) { const foundConfigs = knownSvelteConfigNames .map((candidate) => path.resolve(root, candidate)) .filter((file) => fs.existsSync(file)); @@ -18,7 +22,7 @@ export function loadSvelteConfig(root: string = process.cwd()) { ); } try { - const config = require(foundConfigs[0]); + const config = await dynamicImportDefault(foundConfigs[0]); log.debug(`loaded svelte config ${foundConfigs[0]}`, config); return config; } catch (e) { diff --git a/packages/vite-plugin-svelte/src/utils/options.ts b/packages/vite-plugin-svelte/src/utils/options.ts index 29cdc03c2..e9909fdbc 100644 --- a/packages/vite-plugin-svelte/src/utils/options.ts +++ b/packages/vite-plugin-svelte/src/utils/options.ts @@ -2,6 +2,7 @@ import { ResolvedConfig, ViteDevServer } from 'vite'; import { log } from './log'; import { loadSvelteConfig } from './loadSvelteConfig'; +import { addExtraPreprocessors } from './preprocess'; const knownOptions = new Set([ 'include', @@ -116,19 +117,20 @@ function mergeOptions( }; } -export function resolveOptions( +export async function resolveOptions( inlineOptions: Partial = {}, viteConfig: ResolvedConfig -): ResolvedOptions { +): Promise { const defaultOptions = buildDefaultOptions(viteConfig, inlineOptions); // TODO always load from vite root dir or make this configurable? - const svelteConfig = loadSvelteConfig(viteConfig.root) || {}; + const svelteConfig = (await loadSvelteConfig(viteConfig.root)) || {}; const resolvedOptions = mergeOptions(defaultOptions, svelteConfig, inlineOptions, viteConfig); enforceOptionsForProduction(resolvedOptions); enforceOptionsForHmr(resolvedOptions); + addExtraPreprocessors(resolvedOptions, viteConfig); log.debug('resolved options', resolvedOptions); return resolvedOptions; } diff --git a/packages/vite-plugin-svelte/src/utils/preprocess.ts b/packages/vite-plugin-svelte/src/utils/preprocess.ts index 6a7b109e2..36bbf7c13 100644 --- a/packages/vite-plugin-svelte/src/utils/preprocess.ts +++ b/packages/vite-plugin-svelte/src/utils/preprocess.ts @@ -74,7 +74,7 @@ function createInjectScopeEverythingRulePreprocessorGroup(): PreprocessorGroup { }; } -export function buildExtraPreprocessors(options: ResolvedOptions, config: ResolvedConfig) { +function buildExtraPreprocessors(options: ResolvedOptions, config: ResolvedConfig) { const extraPreprocessors = []; if (options.useVitePreprocess) { log.debug('adding vite preprocessor'); @@ -99,3 +99,16 @@ export function buildExtraPreprocessors(options: ResolvedOptions, config: Resolv return extraPreprocessors; } + +export function addExtraPreprocessors(options: ResolvedOptions, config: ResolvedConfig) { + const extra = buildExtraPreprocessors(options, config); + if (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]; + } + } +}