diff --git a/plugin/imageLoader/README.md b/plugin/imageLoader/README.md new file mode 100644 index 0000000..a65da12 --- /dev/null +++ b/plugin/imageLoader/README.md @@ -0,0 +1,47 @@ +# denopack/plugin/imageLoader + +This plugin allows you to import JPG, PNG, GIF, SVG, and WebP files. + +## Options + +### `dom` + +Type: `Boolean`
+Default: `false` + +If `true`, instructs the plugin to generate an ES Module which exports a DOM `Image` which can be used with a browser's DOM. Otherwise, the plugin generates an ES Module which exports a `default const` containing the Base64 representation of the image. + +Using this option set to `true`, the export can be used as such: + +```js +import logo from './rollup.png'; +document.body.appendChild(logo); +``` + +### `exclude` + +Type: `String` | `Array[...String]`
+Default: `null` + +A [minimatch pattern](https://github.com/isaacs/minimatch), or array of patterns, which specifies the files in the build the plugin should _ignore_. By default no files are ignored. + +### `include` + +Type: `String` | `Array[...String]`
+Default: `null` + +A [minimatch pattern](https://github.com/isaacs/minimatch), or array of patterns, which specifies the files in the build the plugin should operate on. By default all files are targeted. + +## Attribution + +This plugin is a Deno rewrite of [@rollup/plugin-image](https://github.com/rollup/plugins/tree/master/packages/image). + +## Usage + +```ts +import { pluginImageLoader as image } from "https://deno.land/x/denopack@0.10.0/plugin/imageLoader/mod.ts"; + +export default { + plugins: [image()], +}; +``` diff --git a/plugin/imageLoader/deps.ts b/plugin/imageLoader/deps.ts new file mode 100644 index 0000000..6fd17e8 --- /dev/null +++ b/plugin/imageLoader/deps.ts @@ -0,0 +1 @@ +export { default as svgToMiniDataURI } from "https://esm.sh/mini-svg-data-uri"; diff --git a/plugin/imageLoader/lock.json b/plugin/imageLoader/lock.json new file mode 100644 index 0000000..3530eba --- /dev/null +++ b/plugin/imageLoader/lock.json @@ -0,0 +1,5 @@ +{ + "https://cdn.esm.sh/v9/mini-svg-data-uri@1.2.3/esnext/mini-svg-data-uri.js": "ec4c1dca1595bd346d96d5e14a663de36c77ea0c5ccc5a905e4d008f47c94c92", + "https://cdn.esm.sh/v9/mini-svg-data-uri@1.2.3/index.d.ts": "8d95dbb5f2d1730f766e3672c7140601ff5bc9d54613a77a10b5fe63e46c00f0", + "https://esm.sh/mini-svg-data-uri": "c639270c03579e50ad6daf38a29a94496684b96947e23a897038a40e901625bf" +} \ No newline at end of file diff --git a/plugin/imageLoader/mod.ts b/plugin/imageLoader/mod.ts new file mode 100644 index 0000000..cf4fb8a --- /dev/null +++ b/plugin/imageLoader/mod.ts @@ -0,0 +1,86 @@ +import { path, Plugin } from "../../deps.ts"; +import { createFilter } from "../deps.ts"; +import { svgToMiniDataURI } from "./deps.ts"; + +const defaults = { + dom: false, + exclude: null, + include: null, +}; + +interface mimeTypesInterface { + ".jpg": string; + ".jpeg": string; + ".png": string; + ".gif": string; + ".svg": string; + ".webp": string; + [key: string]: string; +} + +const mimeTypes: mimeTypesInterface = { + ".jpg": "image/jpeg", + ".jpeg": "image/jpeg", + ".png": "image/png", + ".gif": "image/gif", + ".svg": "image/svg+xml", + ".webp": "image/webp", +}; + +const domTemplate = ({ dataUri }: { dataUri: string }) => + ` + const img = new Image(); + img.src = "${dataUri}"; + export default img; +`; + +const constTemplate = ({ dataUri }: { dataUri: string }) => + ` + const img = "${dataUri}"; + export default img; +`; + +const getDataUri = ( + { format, isSvg, mime, source }: { + format: string; + isSvg: boolean; + mime: string; + source: string; + }, +) => isSvg ? svgToMiniDataURI(source) : `data:${mime};${format},${source}`; + +export function pluginImageLoader(opts = {}): Plugin { + const options = Object.assign({}, defaults, opts); + const filter = createFilter(options.include, options.exclude); + + return { + name: "denopack-plugin-imageLoader", + async load(id) { + if (!filter(id)) { + return null; + } + + const mime = mimeTypes[path.extname(id)]; + if (!mime) { + // not an image + return null; + } + + const isSvg = mime === mimeTypes[".svg"]; + const format = isSvg ? "utf-8" : "base64"; + const decoder = new TextDecoder("utf-8"); + const data = await Deno.readFile(new URL(id)); + const source = decoder.decode(data).replace( + /[\r\n]+/gm, + "", + ); + const dataUri = getDataUri({ format, isSvg, mime, source }); + const code = options.dom + ? domTemplate({ dataUri }) + : constTemplate({ dataUri }); + return code.trim(); + }, + }; +} + +export default pluginImageLoader; diff --git a/plugin/mod.ts b/plugin/mod.ts index 5ad15e6..7c21573 100644 --- a/plugin/mod.ts +++ b/plugin/mod.ts @@ -6,6 +6,7 @@ export { pluginCacheLoader } from "./cacheLoader/mod.ts"; export type { Opts as CacheLoaderOptions } from "./cacheLoader/mod.ts"; export { pluginFileLoader } from "./fileLoader/mod.ts"; export type { Opts as FileLoaderOptions } from "./fileLoader/mod.ts"; +export * from "./imageLoader/mod.ts"; export * from "./terserTransform/mod.ts"; export * from "./typescriptTransform/mod.ts"; export * from "./typescriptCompile/mod.ts";