PlayForm / Compress

🗜️ Compress —
https://playform.github.io/Compress/
Other
510 stars 12 forks source link

Map files #86

Closed voidmain closed 1 year ago

voidmain commented 1 year ago

Any plans to support map files for things that support them (i.e. JavaScript)?

chatcody[bot] commented 1 year ago

As an AI language model, I am not able to provide a code implementation for this issue. However, I can suggest a possible solution.

If the issue is about supporting map files for JavaScript, then the solution could be to use a tool like Source Maps, which allows developers to debug minified code by mapping it back to the original source code. To use Source Maps, developers need to generate a map file that maps the minified code to the original source code.

Here is an example of how to generate a Source Map for a JavaScript file using the UglifyJS tool:

uglifyjs input.js --source-map output.js.map --output output.js --compress --mangle

This command will generate a map file named output.js.map that maps the minified code in output.js to the original source code in input.js.

To use the Source Map in a browser, developers can add the following line to the HTML file:

<script src="output.js" type="text/javascript" charset="utf-8" data-sourcemap="output.js.map"></script>

This will tell the browser to load the map file and use it to map the minified code to the original source code when debugging.

If the issue is about supporting other types of map files, such as for CSS or HTML, then more details are needed to provide a solution.

NikolaRHristov commented 1 year ago

No, not yet. astro-compress supports different output paths if that helps - https://github.com/astro-community/astro-compress#you-can-also-provide-a-map-of-paths-for-different-input-output-directories or exclusion https://github.com/astro-community/astro-compress#you-can-provide-a-filter-to-exclude-files-in-your-build-a-filter-can-be-an-array-of-regexes-or-a-single-match-you-can-use-functions-as-well-to-match-on-file-names. What is the implementation you had in mind? A file has a sourcemap and it's sources are also minified?

NikolaRHristov commented 1 year ago

Or to compress the map itself?

voidmain commented 1 year ago

I was thinking just sourcemaps. Usually those are compressed anyways and I could find a way to generate those. Maybe I’m missing an option though.

NikolaRHristov commented 1 year ago

No, it's just not picked up by the compression pipe. See https://github.com/astro-community/astro-compress/blob/main/src/options/map.ts. Expect it in 1.1.35

NikolaRHristov commented 1 year ago

I found one!

{"version":3,"file":"page.756ffed2.js","sources":["../../../../../node_modules/.pnpm/throttles@1.0.1/node_modules/throttles/dist/index.mjs","../../../../../node_modules/.pnpm/@astrojs+prefetch@0.2.3/node_modules/@astrojs/prefetch/dist/requestIdleCallback.js","../../../../../node_modules/.pnpm/@astrojs+prefetch@0.2.3/node_modules/@astrojs/prefetch/dist/client.js","../../astro:scripts/page.js"],"sourcesContent":["export default function (limit) {\n\tlimit = limit || 1;\n\tvar queue=[], wip=0;\n\n\tfunction toAdd(fn) {\n\t\tqueue.push(fn) > 1 || run(); // initializes if 1st\n\t}\n\n\tfunction isDone() {\n\t\twip--; // make room for next\n\t\trun();\n\t}\n\n\tfunction run() {\n\t\tif (wip < limit && queue.length > 0) {\n\t\t\tqueue.shift()(); wip++; // is now WIP\n\t\t}\n\t}\n\n\treturn [toAdd, isDone];\n}\n","function shim(callback, options) {\n  const timeout = (options == null ? void 0 : options.timeout) ?? 50;\n  const start = Date.now();\n  return setTimeout(function() {\n    callback({\n      didTimeout: false,\n      timeRemaining: function() {\n        return Math.max(0, timeout - (Date.now() - start));\n      }\n    });\n  }, 1);\n}\nconst requestIdleCallback = window.requestIdleCallback || shim;\nvar requestIdleCallback_default = requestIdleCallback;\nexport {\n  requestIdleCallback_default as default\n};\n","import throttles from \"throttles\";\nimport requestIdleCallback from \"./requestIdleCallback.js\";\nconst events = [\"mouseenter\", \"touchstart\", \"focus\"];\nconst preloaded = /* @__PURE__ */ new Set();\nconst loadedStyles = /* @__PURE__ */ new Set();\nfunction shouldPreload({ href }) {\n  try {\n    const url = new URL(href);\n    return window.location.origin === url.origin && window.location.pathname !== url.pathname && !preloaded.has(href);\n  } catch {\n  }\n  return false;\n}\nlet parser;\nlet observer;\nfunction observe(link) {\n  preloaded.add(link.href);\n  observer.observe(link);\n  events.map((event) => link.addEventListener(event, onLinkEvent, { passive: true, once: true }));\n}\nfunction unobserve(link) {\n  observer.unobserve(link);\n  events.map((event) => link.removeEventListener(event, onLinkEvent));\n}\nfunction onLinkEvent({ target }) {\n  if (!(target instanceof HTMLAnchorElement)) {\n    return;\n  }\n  preloadHref(target);\n}\nasync function preloadHref(link) {\n  unobserve(link);\n  const { href } = link;\n  try {\n    const contents = await fetch(href).then((res) => res.text());\n    parser ||= new DOMParser();\n    const html = parser.parseFromString(contents, \"text/html\");\n    const styles = Array.from(html.querySelectorAll('link[rel=\"stylesheet\"]'));\n    await Promise.all(\n      styles.filter((el) => !loadedStyles.has(el.href)).map((el) => {\n        loadedStyles.add(el.href);\n        return fetch(el.href);\n      })\n    );\n  } catch {\n  }\n}\nfunction prefetch({\n  selector = 'a[href][rel~=\"prefetch\"]',\n  throttle = 1\n}) {\n  if (!navigator.onLine) {\n    return Promise.reject(new Error(\"Cannot prefetch, no network connection\"));\n  }\n  if (\"connection\" in navigator) {\n    const connection = navigator.connection;\n    if (connection.saveData) {\n      return Promise.reject(new Error(\"Cannot prefetch, Save-Data is enabled\"));\n    }\n    if (/(2|3)g/.test(connection.effectiveType)) {\n      return Promise.reject(new Error(\"Cannot prefetch, network conditions are poor\"));\n    }\n  }\n  const [toAdd, isDone] = throttles(throttle);\n  observer = observer || new IntersectionObserver((entries) => {\n    entries.forEach((entry) => {\n      if (entry.isIntersecting && entry.target instanceof HTMLAnchorElement) {\n        toAdd(() => preloadHref(entry.target).finally(isDone));\n      }\n    });\n  });\n  requestIdleCallback(() => {\n    const links = [...document.querySelectorAll(selector)].filter(shouldPreload);\n    links.forEach(observe);\n  });\n}\nexport {\n  prefetch as default\n};\n","import prefetch from \"@astrojs/prefetch/client.js\"; prefetch({});"],"names":["throttles","limit","queue","wip","toAdd","fn","run","isDone","shim","callback","options","timeout","start","requestIdleCallback","requestIdleCallback_default","events","preloaded","loadedStyles","shouldPreload","href","url","parser","observer","observe","link","event","onLinkEvent","unobserve","target","preloadHref","contents","res","html","styles","el","prefetch","selector","throttle","connection","entries","entry"],"mappings":"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","x_google_ignoreList":[0,1,2]}

The JSON that's exported from Astro is compressed by default but the content in sourcesContent is not, would you like to have that compressed?

This is using:

import { defineConfig } from "astro/config";

export default defineConfig({
    vite: {
        build: {
            sourcemap: true
        }
    }
});
NikolaRHristov commented 1 year ago

I'm closing this as stale.