Skip to content

Commit f57bd74

Browse files
committed
Report error if optional package is required and missing
1 parent 5450af2 commit f57bd74

File tree

3 files changed

+17
-7
lines changed

3 files changed

+17
-7
lines changed

src/html.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { BuildResult } from "esbuild";
22
import * as fs from "fs";
33
import * as path from "path";
4+
import { tryAsync as tryImport } from "./utils";
45

56
export type IndexOptions = {
67
/**
@@ -49,7 +50,7 @@ export async function generateIndexHTML(result: BuildResult, opts: IndexOptions,
4950
throw new Error("No outFile was specified and it could not be inferred from the build options");
5051
}
5152

52-
const cheerio = await import("cheerio");
53+
const cheerio = await tryImport(() => import("cheerio"), "cheerio", "HTML generation");
5354

5455
const $ = cheerio.load(await fs.promises.readFile(opts.originalFile));
5556

@@ -88,8 +89,8 @@ export async function generateIndexHTML(result: BuildResult, opts: IndexOptions,
8889
let html = $.html();
8990

9091
if (min) {
91-
const { minify } = await import("html-minifier")
92-
92+
const { minify } = await tryImport(() => import("html-minifier"), "html-minifier", "HTML minification")
93+
9394
html = minify(html, {
9495
collapseWhitespace: true,
9596
minifyCSS: true,

src/index.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import * as crypto from "crypto";
66
import * as sfc from '@vue/compiler-sfc';
77

88
import { loadRules, replaceRules } from "./paths";
9-
import { fileExists, getFullPath, getUrlParams } from "./utils"
9+
import { fileExists, getFullPath, getUrlParams, tryAsync } from "./utils"
1010
import { Options } from "./options";
1111
import { generateIndexHTML } from "./html";
1212

@@ -135,7 +135,8 @@ const vuePlugin = (opts: Options = {}) => <esbuild.Plugin>{
135135
let source = descriptor.template.content;
136136

137137
if (descriptor.template.lang === "pug") {
138-
source = (await import("pug")).render(descriptor.template.content);
138+
const pug = await tryAsync(() => import("pug"), "pug", "Pug template rendering")
139+
source = pug.render(descriptor.template.content);
139140

140141
// Fix #default="#default" and v-else="v-else"
141142
source = source.replace(/(\B#.*?|\bv-.*?)="\1"/g, "$1");
@@ -163,8 +164,8 @@ const vuePlugin = (opts: Options = {}) => <esbuild.Plugin>{
163164
let includedFiles: string[] = [];
164165

165166
if (style.lang === "sass" || style.lang === "scss") {
166-
const sass = await import("sass");
167-
167+
const sass = await tryAsync(() => import("sass"), "sass", "SASS style preprocessing");
168+
168169
const result: import("sass").Result = await new Promise((resolve, reject) => sass.render({
169170
data: source,
170171
indentedSyntax: style.lang === "sass",

src/utils.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,11 @@ export async function fileExists(path: fs.PathLike) {
2222
export function getFullPath(args: OnResolveArgs) {
2323
return path.isAbsolute(args.path) ? args.path : path.join(args.resolveDir, args.path);
2424
}
25+
26+
export async function tryAsync<T>(fn: () => Promise<T>, module: string, requiredFor: string) {
27+
try {
28+
return await fn();
29+
} catch (err) {
30+
throw new Error(`Package "${module}" is required for ${requiredFor}. Please run "npm i -D ${module}" and try again.`);
31+
}
32+
}

0 commit comments

Comments
 (0)