-
Notifications
You must be signed in to change notification settings - Fork 491
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
Serve assets with compression #69
Comments
If it helps, i updated my patch file to work with the nitropack package .yarn/patches/nitropack-npm-0.2.4-598f2e4fe6
package.json {
"resolutions": {
"nitropack": "patch:nitropack@npm:0.2.4#.yarn/patches/nitropack-npm-0.2.4-598f2e4fe6"
}
} |
I was just looking for a solution to serve assets (
|
@nathanchase I don't know if you used my solution but if you want to, here are some up to date instructions with a new patch for nitro version 0.4.12. Add the patch to your repo and use it with your package manager. diff --git a/dist/chunks/prerender.mjs b/dist/chunks/prerender.mjs
index 5af8310adc4b4773d459cd231fbade416da65492..c23e6f3270abfcf1174fd38e057ccfb15054c37b 100644
--- a/dist/chunks/prerender.mjs
+++ b/dist/chunks/prerender.mjs
@@ -527,15 +527,19 @@ function publicAssets(nitro) {
}
return virtual({
"#internal/nitro/virtual/public-assets-data": `export default ${JSON.stringify(assets, null, 2)};`,
+ "#internal/nitro/virtual/public-assets-config": readFileSync(resolve(nitro.options.rootDir, nitro.options.static), 'utf8'),
"#internal/nitro/virtual/public-assets-node": `
import { promises as fsp } from 'fs'
import { resolve } from 'pathe'
import { dirname } from 'pathe'
import { fileURLToPath } from 'url'
import assets from '#internal/nitro/virtual/public-assets-data'
-export function readAsset (id) {
+import { hook } from '#internal/nitro/virtual/public-assets-config'
+export async function readAsset (id, res) {
const serverDir = dirname(fileURLToPath(import.meta.url))
- return fsp.readFile(resolve(serverDir, assets[id].path))
+ let assetPath = resolve(serverDir, assets[id].path)
+ if (hook) assetPath = await hook(assetPath, res)
+ return fsp.readFile(assetPath);
}`,
"#internal/nitro/virtual/public-assets": `
import assets from '#internal/nitro/virtual/public-assets-data'
diff --git a/dist/runtime/static.mjs b/dist/runtime/static.mjs
index 5b19f1fc9ff8a3d975766a3ba82d05291901c138..85fd2df47e3671b7de72d5141b4d3d73341588a2 100644
--- a/dist/runtime/static.mjs
+++ b/dist/runtime/static.mjs
@@ -1,6 +1,7 @@
import { eventHandler, createError } from "h3";
import { withoutTrailingSlash, withLeadingSlash, parseURL } from "ufo";
import { getAsset, readAsset, isPublicAssetURL } from "#internal/nitro/virtual/public-assets";
+import { maxAge } from "#internal/nitro/virtual/public-assets-config";
const METHODS = ["HEAD", "GET"];
export default eventHandler(async (event) => {
if (event.req.method && !METHODS.includes(event.req.method)) {
@@ -48,6 +49,9 @@ export default eventHandler(async (event) => {
if (asset.mtime) {
event.res.setHeader("Last-Modified", asset.mtime);
}
- const contents = await readAsset(id);
+ if (maxAge) {
+ event.res.setHeader("Cache-Control", `max-age=${maxAge}, immutable`);
+ }
+ const contents = await readAsset(id, event.res);
event.res.end(contents);
}); Install the Update your import { defineNuxtConfig } from 'nuxt';
import viteCompression from 'vite-plugin-compression';
export default defineNuxtConfig({
nitro: {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
static: './staticConfig.mjs'
},
vite: {
plugins: [viteCompression({ algorithm: 'brotliCompress' })]
}
}); Create the import { promises, constants } from 'fs';
export const maxAge = 60 * 60 * 24 * 365;
export async function hook(assetPath, res) {
if (assetPath.endsWith('.mjs') || assetPath.endsWith('.css')) {
try {
await promises.access(`${assetPath}.br`, constants.R_OK | constants.W_OK);
assetPath = `${assetPath}.br`;
res.setHeader('Content-Encoding', 'br');
} catch {}
}
return assetPath;
} What all this is doing, is first patch the nitro package to let you hook into the static assets and manipulate the response, which we can then use inside our Currently there is no other way to do that as far as i know but it works perfectly fine for me and i also use it in production like that. |
Thanks! I'm using pnpm, so I'm not sure exactly how to apply this patch.
and I copy/pasted your patch to but I get a |
@nathanchase Which nuxt version are you using? If you are using the latest This is how my package.json looks like: {
"pnpm": {
"patchedDependencies": {
"nitropack@0.4.12": "patches/nitropack@0.4.12.patch"
}
}
} The path to my patch file is |
@nathanchase i just saw that |
This worked! I think specifying the version of nitropack ( "pnpm": {
"patchedDependencies": {
"nitropack@0.4.12": "patches/nitropack-npm-0.2.4-598f2e4fe6.patch"
}
}, |
@nathanchase did you check if all the brotli files are available on your production server? |
that is weird because you said that it worked on your local machine. it looks like it tries to read a file but instead got a directory. there is probably no way you can provide a reproduction? |
OK. I figured it out. I had to delete nitro: {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
static: './staticConfig.mjs',
},
vite: {
plugins: [viteCompression({ algorithm: 'brotliCompress' })],
}, |
glad i could help and it works now! I hope that they soon add something like a hook and we can update the https://github.com/nuxt-modules/compression package |
@exreplay How would I achieve this with yarn? I am a little confused about how this needs to be added to package.json
|
@CatalinGheorghiu what yarn version are you using? With yarn your package.json should look like this {
"resolutions": {
"nitropack": "patch:nitropack@npm:0.4.12#.yarn/patches/nitropack-npm-0.4.12-0dce97461d"
}
} |
Yarn version: 1.22.19 |
afaik the patch command is not available in yarn version 1, you need at least version 2. if you want to use the current stable yarn version in a project you can run the following command in the root of your project. yarn set version stable If that doesn't work, you can head to https://yarnpkg.com/getting-started/install to see how you can install it. This should create a |
I found another way to make all this work without the need for a patch and everything else. I wrote a module real quick for everyone to use. You can find the package here https://github.com/exreplay/nuxt-compression. I already tried it locally and in my production environment with success. |
Can confirm it works for me locally and in production. Great work! |
Another bump for https://github.com/exreplay/nuxt-compression to be considered as a default, zero-config option in Nitro, to automatically enable gzip/brotli compression for all static assets and set Cache-Control/maxAge values. |
Hi there and sorry it took long to add this feature. Generally, I would recommend you use a CDN that can natively support compression. It is much more efficient to handle best compression with long term caching. nuxt/framework#449 adds a new option To enable this option for Nuxt 3, use edge channel (or wait for rc.9) and: defineNuxtConfig({
nitro: { compressPublicAssets: true }
}) |
Hi @pi0, thanks for the release. The nitro compression is working only in build mode. In generate mode it doesn't work, am I miss something? |
@fedeweb Can you please explain more? Generate mode should behave similarly and generate |
@pi0 I attached here 2 screenshots of some of the files generated with "generate" and "build" |
Thanks! I can locally reproduce. Moved to nuxt/nuxt#14794 |
Environment
macOS
v16.14.0
0.2.1
yarn@3.1.1
Reproduction
n/a
Describe the bug
It would be a nice addition to nitro if there is be a possibility to change the response of static assets. Then it would also be possible to implement content encoding like
brotli
orgzip
.Additional context
There does exist a discussion in the nuxt repo. https://github.com/nuxt/framework/discussions/3472
In addition to the discussion i already found the corresponding lines, which i changed in nuxt, in the nitro package:
https://github.com/unjs/nitro/blob/main/src/runtime/static.ts#L68
https://github.com/unjs/nitro/blob/main/src/rollup/plugins/public-assets.ts#L44
Logs
No response
Update 21.07.2022
I wrote a module which can handle the compression https://github.com/exreplay/nuxt-compression. This is still no official way and messes with the internal nitro code but there is no need to use patches.
The text was updated successfully, but these errors were encountered: