mirror of https://github.com/curbengh/hexo-yam
feat: add source map supports
This commit is contained in:
parent
83f62ea518
commit
2528fcc394
|
@ -90,6 +90,8 @@ minify:
|
||||||
- **verbose** - Verbose output. Defaults to `false`.
|
- **verbose** - Verbose output. Defaults to `false`.
|
||||||
- **exclude** - Exclude files. Support [wildcard](http://www.globtester.com/) pattern(s) in a string or array.
|
- **exclude** - Exclude files. Support [wildcard](http://www.globtester.com/) pattern(s) in a string or array.
|
||||||
- **level** - Optimization level. Defaults to `2`.
|
- **level** - Optimization level. Defaults to `2`.
|
||||||
|
- **sourceMap** - Source map options. Defaults to `false`.
|
||||||
|
- **mapIncludeSources** - Include sources in map, Defaults to `false`.
|
||||||
- **globOptions** - See [globbing](#globbing) section.
|
- **globOptions** - See [globbing](#globbing) section.
|
||||||
|
|
||||||
For more options, see [clean-css](https://github.com/jakubpawlowicz/clean-css).
|
For more options, see [clean-css](https://github.com/jakubpawlowicz/clean-css).
|
||||||
|
@ -112,6 +114,8 @@ minify:
|
||||||
- **mangle** - Mangle variable names. Defaults to `true`. Pass an object to specify [mangle options](https://github.com/terser-js/terser#mangle-options).
|
- **mangle** - Mangle variable names. Defaults to `true`. Pass an object to specify [mangle options](https://github.com/terser-js/terser#mangle-options).
|
||||||
- **output** - Output options.
|
- **output** - Output options.
|
||||||
- To retain comments, `output: {comments: true}`.
|
- To retain comments, `output: {comments: true}`.
|
||||||
|
- **sourceMap** - Source map options. Defaults to `false`.
|
||||||
|
- To include sources in map, `sourceMap: { includeSources: true }`
|
||||||
- **globOptions** - See [globbing](#globbing) section.
|
- **globOptions** - See [globbing](#globbing) section.
|
||||||
|
|
||||||
For more options, see [Terser](https://github.com/terser-js/terser).
|
For more options, see [Terser](https://github.com/terser-js/terser).
|
||||||
|
|
13
index.js
13
index.js
|
@ -32,6 +32,8 @@ hexo.config.minify.css = {
|
||||||
verbose: false,
|
verbose: false,
|
||||||
exclude: ['*.min.css'],
|
exclude: ['*.min.css'],
|
||||||
level: 2,
|
level: 2,
|
||||||
|
sourceMap: false,
|
||||||
|
mapIncludeSources: false,
|
||||||
globOptions: { basename: true },
|
globOptions: { basename: true },
|
||||||
...hexo.config.minify.css
|
...hexo.config.minify.css
|
||||||
}
|
}
|
||||||
|
@ -44,6 +46,7 @@ hexo.config.minify.js = {
|
||||||
compress: {},
|
compress: {},
|
||||||
mangle: true,
|
mangle: true,
|
||||||
output: {},
|
output: {},
|
||||||
|
sourceMap: false,
|
||||||
globOptions: { basename: true },
|
globOptions: { basename: true },
|
||||||
...hexo.config.minify.js
|
...hexo.config.minify.js
|
||||||
}
|
}
|
||||||
|
@ -109,11 +112,21 @@ if (hexo.config.minify.enable === true && !(hexo.config.minify.previewServer ===
|
||||||
hexo.extend.filter.register('after_render:html', require('./lib/html').minifyHtml, hexo.config.minify.html.priority)
|
hexo.extend.filter.register('after_render:html', require('./lib/html').minifyHtml, hexo.config.minify.html.priority)
|
||||||
}
|
}
|
||||||
if (hexo.config.minify.css.enable === true) {
|
if (hexo.config.minify.css.enable === true) {
|
||||||
|
if (hexo.config.minify.css.sourceMap) {
|
||||||
|
hexo.extend.filter.register('after_generate', require('./lib/css').minifyCssWithMap, hexo.config.minify.js.priority)
|
||||||
|
}
|
||||||
|
else {
|
||||||
hexo.extend.filter.register('after_render:css', require('./lib/css').minifyCss, hexo.config.minify.css.priority)
|
hexo.extend.filter.register('after_render:css', require('./lib/css').minifyCss, hexo.config.minify.css.priority)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (hexo.config.minify.js.enable === true) {
|
if (hexo.config.minify.js.enable === true) {
|
||||||
|
if (hexo.config.minify.js.sourceMap) {
|
||||||
|
hexo.extend.filter.register('after_generate', require('./lib/js').minifyJsWithMap, hexo.config.minify.js.priority)
|
||||||
|
}
|
||||||
|
else {
|
||||||
hexo.extend.filter.register('after_render:js', require('./lib/js').minifyJs, hexo.config.minify.js.priority)
|
hexo.extend.filter.register('after_render:js', require('./lib/js').minifyJs, hexo.config.minify.js.priority)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (hexo.config.minify.svg.enable === true) {
|
if (hexo.config.minify.svg.enable === true) {
|
||||||
hexo.extend.filter.register('after_generate', require('./lib/svg').minifySvg, hexo.config.minify.svg.priority)
|
hexo.extend.filter.register('after_generate', require('./lib/svg').minifySvg, hexo.config.minify.svg.priority)
|
||||||
}
|
}
|
||||||
|
|
49
lib/css.js
49
lib/css.js
|
@ -1,6 +1,6 @@
|
||||||
'use strict'
|
'use strict'
|
||||||
const CleanCSS = require('clean-css')
|
const CleanCSS = require('clean-css')
|
||||||
const { isMatch, logFn } = require('./tools')
|
const { isMatch, match, logFn } = require('./tools')
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} str
|
* @param {string} str
|
||||||
|
@ -13,6 +13,7 @@ async function minifyCss(str, data) {
|
||||||
|
|
||||||
const path = data.path
|
const path = data.path
|
||||||
const { exclude, globOptions, verbose } = options
|
const { exclude, globOptions, verbose } = options
|
||||||
|
options.returnPromise = true
|
||||||
|
|
||||||
if (isMatch(path, exclude, globOptions)) return str
|
if (isMatch(path, exclude, globOptions)) return str
|
||||||
|
|
||||||
|
@ -25,6 +26,48 @@ async function minifyCss(str, data) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
function minifyCssWithMap() {
|
||||||
minifyCss
|
const hexo = this
|
||||||
|
const options = hexo.config.minify.css
|
||||||
|
const { parse } = require('path')
|
||||||
|
|
||||||
|
const route = hexo.route
|
||||||
|
const routeList = route.list()
|
||||||
|
/** @type {{ exclude: string[] }} */
|
||||||
|
const { exclude, globOptions, verbose } = options
|
||||||
|
const include = ['*.css', ...exclude.map(x => `!${x}`)]
|
||||||
|
options.returnPromise = true
|
||||||
|
const cleanCSS = new CleanCSS(options)
|
||||||
|
|
||||||
|
return Promise.all((match(routeList, include, globOptions)).map(path => {
|
||||||
|
return new Promise((/** @type {(value: void) => void} */ resolve, reject) => {
|
||||||
|
const assetPath = route.get(path)
|
||||||
|
let assetTxt = ''
|
||||||
|
assetPath.on('data', chunk => (assetTxt += chunk))
|
||||||
|
assetPath.on('end', async () => {
|
||||||
|
if (assetTxt.length) {
|
||||||
|
try {
|
||||||
|
const { base, ext, name } = parse(path)
|
||||||
|
const { styles, sourceMap } = await cleanCSS.minify(assetTxt)
|
||||||
|
if (verbose) logFn.call(this, assetTxt, result, path, 'css')
|
||||||
|
route.set(path, `${styles}\n/*# sourceMappingURL=${base}.map */`)
|
||||||
|
const map = sourceMap.toJSON()
|
||||||
|
map.sources = [`${name}.source${ext}`]
|
||||||
|
if (options.mapIncludeSources === true) {
|
||||||
|
map.sourcesContent = [assetTxt]
|
||||||
|
}
|
||||||
|
route.set(`${path}.map`, JSON.stringify(map))
|
||||||
|
} catch (err) {
|
||||||
|
reject(new Error(`Path: ${path}\n${err}`))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
resolve()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
minifyCss,
|
||||||
|
minifyCssWithMap
|
||||||
}
|
}
|
54
lib/js.js
54
lib/js.js
|
@ -1,6 +1,6 @@
|
||||||
'use strict'
|
'use strict'
|
||||||
const { minify: terserMinify } = require('terser')
|
const { minify: terserMinify } = require('terser')
|
||||||
const { isMatch, logFn } = require('./tools')
|
const { isMatch, match, logFn } = require('./tools')
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} str
|
* @param {string} str
|
||||||
|
@ -31,6 +31,54 @@ async function minifyJs(str, data) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
function minifyJsWithMap() {
|
||||||
minifyJs
|
const hexo = this
|
||||||
|
const options = hexo.config.minify.js
|
||||||
|
const { parse } = require('path')
|
||||||
|
|
||||||
|
const route = hexo.route
|
||||||
|
const routeList = route.list()
|
||||||
|
/** @type {{ exclude: string[] }} */
|
||||||
|
const { exclude, globOptions, verbose, ...jsOptions } = options
|
||||||
|
const include = ['*.js', ...exclude.map(x => `!${x}`)]
|
||||||
|
|
||||||
|
// Terser doesn't like unsupported options
|
||||||
|
delete jsOptions.enable
|
||||||
|
delete jsOptions.priority
|
||||||
|
// Old option, retained to avoid crash when upgrading to v4
|
||||||
|
delete jsOptions.logger
|
||||||
|
|
||||||
|
return Promise.all((match(routeList, include, globOptions)).map(path => {
|
||||||
|
return new Promise((/** @type {(value: void) => void} */ resolve, reject) => {
|
||||||
|
const assetPath = route.get(path)
|
||||||
|
let assetTxt = ''
|
||||||
|
assetPath.on('data', chunk => (assetTxt += chunk))
|
||||||
|
assetPath.on('end', async () => {
|
||||||
|
if (assetTxt.length) {
|
||||||
|
try {
|
||||||
|
const { base, ext, name } = parse(path)
|
||||||
|
jsOptions.sourceMap = {
|
||||||
|
...jsOptions.sourceMap,
|
||||||
|
filename: base,
|
||||||
|
asObject: true,
|
||||||
|
url: `${base}.map`
|
||||||
|
}
|
||||||
|
const { code, map } = await terserMinify(assetTxt, { ...jsOptions })
|
||||||
|
if (verbose) logFn.call(this, assetTxt, result, path, 'js')
|
||||||
|
route.set(path, code)
|
||||||
|
map.sources = [`${name}.source${ext}`]
|
||||||
|
route.set(`${path}.map`, JSON.stringify(map))
|
||||||
|
} catch (err) {
|
||||||
|
reject(new Error(`Path: ${path}\n${err}`))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
resolve()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
minifyJs,
|
||||||
|
minifyJsWithMap
|
||||||
}
|
}
|
|
@ -10,7 +10,7 @@ function gzipFn() {
|
||||||
const options = hexo.config.minify.gzip
|
const options = hexo.config.minify.gzip
|
||||||
|
|
||||||
const route = hexo.route
|
const route = hexo.route
|
||||||
/** @type {string} */
|
/** @type {string[]} */
|
||||||
const routeList = route.list()
|
const routeList = route.list()
|
||||||
const { globOptions, include, verbose } = options
|
const { globOptions, include, verbose } = options
|
||||||
let level = options.level
|
let level = options.level
|
||||||
|
@ -43,6 +43,7 @@ function brotliFn() {
|
||||||
const options = hexo.config.minify.brotli
|
const options = hexo.config.minify.brotli
|
||||||
|
|
||||||
const route = hexo.route
|
const route = hexo.route
|
||||||
|
/** @type {string[]} */
|
||||||
const routeList = route.list()
|
const routeList = route.list()
|
||||||
const { globOptions, include, verbose } = options
|
const { globOptions, include, verbose } = options
|
||||||
let level = options.level
|
let level = options.level
|
||||||
|
|
Loading…
Reference in New Issue