Supports SourceMap on renderer and filter
- Dominant language
- TypeScript
- Stars
- 41.8k
- Forks
- 41
- PR merge metrics
- No merged PRs in 30d
Description
### Check List
- [x] I have already read [Docs page](https://hexo.io/docs/).
- [x] I have already searched existing issues.
### Feature Request
In renderer and filter we can only return the results of js and css. We can not create source map for it or get source map from prevent render or filter. It will be better if it can get and set source map in the pipeline. Such as:
```js
hexo.extend.renderer.register("js", "js", data => {
const sourceMap = data.sourceMap;
const results = someCompiler(str, sourceMap);
data.sourceMap = results.sourceMap;
return results.code;
});
hexo.extend.filter.register("after_render:js", (str, data) => {
const sourceMap = data.sourceMap;
const results = someCompiler(str, sourceMap);
data.sourceMap = results.sourceMap;
return results.code;
});
```
### Others
目前我只能通过 `after_generate` 往 `route` 里写入 SourceMap,这种方法想要获取之前的 SourceMap 会很麻烦,或许有更好的方法我并不知道,不过还是在编译期间传递 SourceMap 更方便。
```js
/**
* @this {import('@types/hexo')}
*/
function minifyJsWithMap() {
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, ...babelOption } = options
const include = ['*.js', ...exclude.map(x => `!${x}`)]
delete babelOption.enable
delete babelOption.priority
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 options = {
...babelOption,
filename: path,
sourceFileName: `${name}.source${ext}`
}
const results = await babelMinify(assetTxt, options)
if (results) {
const { code, map } = results
if (verbose) logFn.call(this, assetTxt, code, path, 'js')
if (babelOption.sourceMaps === true) {
route.set(path, `${code}\n//# sourceMappingURL=${base}.map`)
}
else {
route.set(path, code)
}
route.set(`${path}.map`, JSON.stringify(map))
}
} catch (err) {
reject(new Error(`Path: ${path}\n${err}`))
}
}
resolve()
})
})
}))
}
```
Contributor guide
Assessment
This issue has not been assessed yet.