Initial commit
This commit is contained in:
commit
62607f0f0b
3 changed files with 106 additions and 0 deletions
1
README.md
Normal file
1
README.md
Normal file
|
|
@ -0,0 +1 @@
|
|||
# Build optimization
|
||||
88
index.ts
Normal file
88
index.ts
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
import type { Integration, IntegrationContext } from "muddle/contracts";
|
||||
|
||||
import * as terser from "terser";
|
||||
import * as svgo from "svgo";
|
||||
import * as csso from "csso";
|
||||
import * as htmlMinifier from "html-minifier-terser";
|
||||
|
||||
export function minifyCss(source: string): string {
|
||||
return csso.minify(source).css;
|
||||
}
|
||||
|
||||
export async function minifyHtml(source: string): Promise<string> {
|
||||
return await htmlMinifier.minify(source, {
|
||||
collapseWhitespace: true,
|
||||
removeComments: true,
|
||||
removeRedundantAttributes: true,
|
||||
removeEmptyAttributes: true,
|
||||
removeOptionalTags: true,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
export async function minifyJavaScript(source: string): Promise<string> {
|
||||
return (await terser.minify(source, { format: { comments: false } })).code ?? source;
|
||||
}
|
||||
|
||||
export function optimizeSvg(source: string): string {
|
||||
return svgo.optimize(source, { multipass: true }).data;
|
||||
}
|
||||
|
||||
export interface ImageOptimizer {
|
||||
optimize(source: Uint8Array, type: string): Promise<Uint8Array> | Uint8Array;
|
||||
}
|
||||
|
||||
export function imageOptimization(optimizer: ImageOptimizer): ImageOptimizer {
|
||||
return optimizer;
|
||||
}
|
||||
|
||||
function loaderIntegration(name: string, extension: string, transform: (source: string) => string | Promise<string>): Integration {
|
||||
return {
|
||||
name,
|
||||
async transform(asset) {
|
||||
if (!asset.path.endsWith(extension)) return asset;
|
||||
const source = typeof asset.content === "string" ? asset.content : new TextDecoder().decode(asset.content);
|
||||
return { ...asset, content: await transform(source) };
|
||||
},
|
||||
setup(context: IntegrationContext) {
|
||||
context.loader(name, { name, extensions: [extension], async load(file) { return { data: {}, content: await transform(file.source) }; } });
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export function terserIntegration(): Integration {
|
||||
return loaderIntegration("terser", ".js", minifyJavaScript);
|
||||
}
|
||||
|
||||
export function cssMinifyIntegration(): Integration {
|
||||
return loaderIntegration("css-minify", ".css", minifyCss);
|
||||
}
|
||||
|
||||
export function htmlMinifyIntegration(): Integration {
|
||||
return loaderIntegration("html-minify", ".html", minifyHtml);
|
||||
}
|
||||
|
||||
export function svgoIntegration(): Integration {
|
||||
return loaderIntegration("svgo", ".svg", optimizeSvg);
|
||||
}
|
||||
|
||||
export function imageOptimizationIntegration(optimizer: ImageOptimizer): Integration {
|
||||
return {
|
||||
name: "image-optimization",
|
||||
async transform(asset) {
|
||||
if (!/\.(png|jpe?g|webp|avif)$/i.test(asset.path)) return asset;
|
||||
const input = typeof asset.content === "string" ? new TextEncoder().encode(asset.content) : asset.content;
|
||||
return { ...asset, content: await optimizer.optimize(input, asset.contentType) };
|
||||
},
|
||||
setup(context: IntegrationContext) {
|
||||
context.loader("image", {
|
||||
name: "image",
|
||||
extensions: [".png", ".jpg", ".jpeg", ".webp", ".avif"],
|
||||
async load(file) {
|
||||
const optimized = await optimizer.optimize(new TextEncoder().encode(file.source), "image/*");
|
||||
return { data: { optimized }, content: file.source };
|
||||
},
|
||||
});
|
||||
},
|
||||
};
|
||||
}
|
||||
17
package.json
Normal file
17
package.json
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
"name": "@muddle/optimize",
|
||||
"version": "0.1.0",
|
||||
"type": "module",
|
||||
"exports": "./index.ts",
|
||||
"dependencies": {
|
||||
"terser": "^5.51.2",
|
||||
"svgo": "^4.1.0",
|
||||
"csso": "^5.0.5",
|
||||
"html-minifier-terser": "^7.2.0",
|
||||
"@types/csso": "^5.0.5",
|
||||
"@types/html-minifier-terser": "^7.0.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"muddle": "*"
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue