Skip to content
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

Supports SourceMap on renderer and filter #5643

Open
2 tasks done
wherewhere opened this issue Mar 20, 2025 · 0 comments
Open
2 tasks done

Supports SourceMap on renderer and filter #5643

wherewhere opened this issue Mar 20, 2025 · 0 comments

Comments

@wherewhere
Copy link

Check List

  • I have already read Docs page.
  • 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:

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_generateroute 里写入 SourceMap,这种方法想要获取之前的 SourceMap 会很麻烦,或许有更好的方法我并不知道,不过还是在编译期间传递 SourceMap 更方便。

/**
 * @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()
      })
    })
  }))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant