-
Notifications
You must be signed in to change notification settings - Fork 29
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feat: supports optional dependencies #168
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,20 +12,20 @@ const presets = { | |
}; | ||
|
||
export function loadConfig(options, preset, configPath) { | ||
if (! options?.skipConfigLoading) { | ||
if (!options?.skipConfigLoading) { | ||
const explorer = cosmiconfigSync(packageJson.name); | ||
const rc = configPath ? explorer.load(configPath) : explorer.search(); | ||
if (rc) { | ||
const { preset: presetName } = rc.config; | ||
if (presetName) { | ||
if (! preset && presets[presetName]) { | ||
if (!preset && presets[presetName]) { | ||
preset = presets[presetName]; | ||
} | ||
|
||
delete rc.config.preset; | ||
} | ||
if (! options) { | ||
|
||
if (!options) { | ||
options = rc.config; | ||
} | ||
} | ||
|
@@ -37,6 +37,13 @@ export function loadConfig(options, preset, configPath) { | |
]; | ||
} | ||
|
||
const optionalDependencies = { | ||
minifyCss: ['cssnano', 'postcss'], | ||
minifyJs: ['terser'], | ||
minifyUrl: ['relateurl', 'srcset', 'terser'], | ||
minifySvg: ['svgo'], | ||
}; | ||
|
||
function htmlnano(optionsRun, presetRun) { | ||
let [options, preset] = loadConfig(optionsRun, presetRun); | ||
|
||
|
@@ -45,7 +52,7 @@ function htmlnano(optionsRun, presetRun) { | |
let promise = Promise.resolve(tree); | ||
|
||
for (const [moduleName, moduleOptions] of Object.entries(options)) { | ||
if (! moduleOptions) { | ||
if (!moduleOptions) { | ||
// The module is disabled | ||
continue; | ||
} | ||
|
@@ -54,6 +61,18 @@ function htmlnano(optionsRun, presetRun) { | |
throw new Error('Module "' + moduleName + '" is not defined'); | ||
} | ||
|
||
(optionalDependencies[moduleName] || []).forEach(dependency => { | ||
try { | ||
require(dependency); | ||
} catch (e) { | ||
if (e.code === 'MODULE_NOT_FOUND') { | ||
console.warn(`You have to install "${dependency}" in order to use htmlnano's "${moduleName}" module`); | ||
} else { | ||
throw e; | ||
} | ||
} | ||
}); | ||
Comment on lines
+64
to
+74
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Try to resolve the required dependencies before HTML actually being minified. With Node.js's require cache it won't add any performance overhead when those dependencies are required again. |
||
|
||
let module = require('./modules/' + moduleName); | ||
promise = promise.then(tree => module.default(tree, options, moduleOptions)); | ||
} | ||
|
@@ -62,6 +81,12 @@ function htmlnano(optionsRun, presetRun) { | |
}; | ||
} | ||
|
||
htmlnano.getRequiredOptionalDependencies = function (optionsRun, presetRun) { | ||
const [options] = loadConfig(optionsRun, presetRun); | ||
|
||
return [...new Set(Object.keys(options).filter(moduleName => options[moduleName]).map(moduleName => optionalDependencies[moduleName]).flat())]; | ||
}; | ||
Comment on lines
+84
to
+88
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
For example, parcel-bundler has a plugin Ideas and opinions from parcel developers (@devongovett @mischnic) would be appreciated. |
||
|
||
|
||
htmlnano.process = function (html, options, preset, postHtmlOptions) { | ||
return posthtml([htmlnano(options, preset)]) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
purgecss
anduncss
are not included here since only one of them is required when enabled.