diff --git a/index.d.ts b/index.d.ts index 25f9e05..a627108 100644 --- a/index.d.ts +++ b/index.d.ts @@ -2,13 +2,16 @@ import { Plugin, RollupWarning, SourceMap as Mapping } from 'rollup'; import { PreprocessorGroup } from 'svelte/types/compiler/preprocess'; import { CompileOptions } from 'svelte/types/compiler/interfaces'; +type Arrayable = T | T[]; type SourceMap = Omit; +type WarningHandler = (warning: RollupWarning | string) => void; + declare class CssWriter { code: string; filename: string; + warn: WarningHandler; map: false | SourceMap; - warn: RollupWarning; write(file: string, map?: boolean): void; emit(name: string, source: string): string; sourcemap(file: string, sourcemap: SourceMap): void; @@ -17,64 +20,41 @@ declare class CssWriter { type CssEmitter = (css: CssWriter) => any; -interface Options extends CompileOptions { - /** - * By default, all ".svelte" files are compiled - * @default ['.svelte'] - */ - extensions?: string[]; - - /** - * You can restrict which files are compiled - * using `include` and `exclude` - * @typedef {string} InclureAndExclude - */ +interface Options { + /** One or more minimatch patterns */ + include: Arrayable; - /** - * @type {IncludeAndExclude} - */ - include?: string; + /** One or more minimatch patterns */ + exclude: Arrayable; /** - * @type {IncludeAndExclude} + * By default, all ".svelte" files are compiled + * @default ['.svelte'] */ - exclude?: string; + extensions: string[]; /** * Optionally, preprocess components with svelte.preprocess: - * https://svelte.dev/docs#svelte_preprocess + * @see https://svelte.dev/docs#svelte_preprocess */ - preprocess?: PreprocessorGroup | PreprocessorGroup[]; + preprocess: Arrayable; // { // style: ({ content }) => { // return transformStyles(content); // } // }, - /** - * Add extra code for development and debugging purposes. - * @default false - */ - dev?: boolean; + /** Emit CSS as "files" for other plugins to process */ + emitCss: boolean; - /** - * Emit CSS as "files" for other plugins to process - * @default false - */ - emitCss?: boolean; + /** Extract CSS into a separate file (recommended) */ + css: false | CssEmitter; - /** - * Extract CSS into a separate file (recommended). - */ - css?: false | CssEmitter; + /** Options passed to `svelte.compile` method. */ + compilerOptions: CompileOptions; - /** - * let Rollup handle all other warnings normally - */ - onwarn?: ( - warning: RollupWarning, - handler: (w: RollupWarning | string) => void - ) => void; + /** Custom warnings handler; defers to Rollup as default. */ + onwarn(warning: RollupWarning, handler: WarningHandler): void; } -export default function svelte(options?: Options): Plugin; +export default function svelte(options?: Partial): Plugin; diff --git a/index.js b/index.js index fad4c49..aeb28fd 100644 --- a/index.js +++ b/index.js @@ -4,11 +4,13 @@ const { createFilter } = require('rollup-pluginutils'); const { compile, preprocess } = require('svelte/compiler'); const { encode, decode } = require('sourcemap-codec'); +const PREFIX = '[rollup-plugin-svelte]'; const pkg_export_errors = new Set(); const plugin_options = new Set([ 'include', 'exclude', 'extensions', - 'emitCss', 'preprocess', 'onwarn', + 'preprocess', 'onwarn', + 'emitCss', 'css', ]); function to_entry_css(bundle) { @@ -29,7 +31,7 @@ class CssWriter { sources: map.sources, sourcesContent: map.sourcesContent, names: [], - mappings: map.mappings + mappings: encode(map.mappings) }; this.warn = context.warn; @@ -78,22 +80,25 @@ class CssWriter { } } -/** @returns {import('rollup').Plugin} */ +/** + * @param [options] {Partial} + * @returns {import('rollup').Plugin} + */ module.exports = function (options = {}) { - const extensions = options.extensions || ['.svelte']; - const filter = createFilter(options.include, options.exclude); + const { compilerOptions={}, ...rest } = options; + const extensions = rest.extensions || ['.svelte']; + const filter = createFilter(rest.include, rest.exclude); - /** @type {import('svelte/types/compiler/interfaces').ModuleFormat} */ - const format = 'esm', config = { format }; + compilerOptions.format = 'esm'; + const isDev = !!compilerOptions.dev; - for (let key in options) { - // forward `svelte/compiler` options + for (let key in rest) { if (plugin_options.has(key)) continue; - config[key] = config[key] || options[key]; + console.warn(`${PREFIX} Unknown "${key}" option. Please use "compilerOptions" for any Svelte compiler configuration.`); } const css_cache = new Map(); // [filename]:[chunk] - const { css, emitCss, onwarn } = options; + const { css, emitCss, onwarn } = rest; const ctype = typeof css; const toWrite = ctype === 'function' && css; @@ -103,7 +108,7 @@ module.exports = function (options = {}) { // block svelte's inline CSS if writer const external_css = !!(toWrite || emitCss); - if (external_css) config.css = false; + if (external_css) compilerOptions.css = false; return { name: 'svelte', @@ -163,13 +168,13 @@ module.exports = function (options = {}) { const dependencies = []; const filename = path.relative(process.cwd(), id); - if (options.preprocess) { - const processed = await preprocess(code, options.preprocess, { filename }); + if (rest.preprocess) { + const processed = await preprocess(code, rest.preprocess, { filename }); if (processed.dependencies) dependencies.push(...processed.dependencies); code = processed.code; } - const compiled = compile(code, { ...config, filename }); + const compiled = compile(code, { ...compilerOptions, filename }); (compiled.warnings || []).forEach(warning => { if (!css && !emitCss && warning.code === 'css-unused-selector') return; @@ -203,7 +208,7 @@ module.exports = function (options = {}) { */ generateBundle(config, bundle) { if (pkg_export_errors.size > 0) { - console.warn('\nrollup-plugin-svelte: The following packages did not export their `package.json` file so we could not check the `svelte` field. If you had difficulties importing svelte components from a package, then please contact the author and ask them to export the package.json file.\n'); + console.warn(`\n${PREFIX} The following packages did not export their \`package.json\` file so we could not check the "svelte" field. If you had difficulties importing svelte components from a package, then please contact the author and ask them to export the package.json file.\n`); console.warn(Array.from(pkg_export_errors, s => `- ${s}`).join('\n') + '\n'); } @@ -239,13 +244,8 @@ module.exports = function (options = {}) { } }); - toWrite( - new CssWriter(this, bundle, !!options.dev, result, config.sourcemap && { - sources, - sourcesContent, - mappings: encode(mappings) - }) - ); + const sourceMap = config.sourcemap && { sources, sourcesContent, mappings }; + toWrite(new CssWriter(this, bundle, isDev, result, sourceMap)); } }; }; diff --git a/test/index.js b/test/index.js index 9448b39..71ad0b3 100644 --- a/test/index.js +++ b/test/index.js @@ -214,7 +214,9 @@ test('produces readable sourcemap output when `dev` is truthy', async () => { input: 'test/sourcemap-test/src/main.js', plugins: [ plugin({ - dev: true, + compilerOptions: { + dev: true + }, css: value => { css = value; css.write('bundle.css');