hexojs / hexojs/hexo

Supports SourceMap on renderer and filter

Open
#5,643 0 comments 3 reactions 0 assignees View on GitHub
feature-request
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.