Skip to content

Commit

Permalink
fix(preload): ignore other urls
Browse files Browse the repository at this point in the history
  • Loading branch information
ThornWalli committed Oct 30, 2023
1 parent a9e28d7 commit 8d65f2f
Show file tree
Hide file tree
Showing 3 changed files with 134 additions and 200 deletions.
138 changes: 31 additions & 107 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,125 +2,49 @@
"version": "0.2.0",
"configurations": [
{
"type": "node",
"presentation": {
"group": "nuxt"
},
"command": "npm run dev",
"name": "Debug: dev",
"request": "launch",
"name": "Express-Server (build/dist)",
"runtimeVersion": "19.5.0",
"program": "${workspaceFolder}/tools/express-server",
"outputCapture": "std",
"args": [
"--dist",
"playground/.nuxt/nuxt-custom-elements/dist"
]
"type": "node-terminal"
},
{
"type": "node",
"presentation": {
"group": "nuxt"
},
"command": "npm run build",
"name": "Debug: build",
"request": "launch",
"name": "Debug (nuxi:generate)",
"runtimeVersion": "19.5.0",
"runtimeArgs": [
"--inspect"
],
"program": "${workspaceFolder}/node_modules/.bin/nuxi",
"outputCapture": "std",
"args": [
"generate",
"playground",
"--target",
"static"
]
"type": "node-terminal"
},
{
"type": "node",
"presentation": {
"group": "nuxt"
},
"command": "npm run generate",
"name": "Debug: generate",
"request": "launch",
"name": "Debug (nuxi:build)",
"runtimeVersion": "19.5.0",
"runtimeArgs": [
"--inspect"
],
"program": "${workspaceFolder}/node_modules/.bin/nuxi",
"outputCapture": "std",
"args": [
"build",
"playground"
]
"type": "node-terminal"
},
{
"type": "node",
"presentation": {
"group": "tests"
},
"command": "npm run vitest:dev",
"name": "Debug: vitest:dev",
"request": "launch",
"name": "Debug (nuxi:dev)",
"runtimeVersion": "19.5.0",
"runtimeArgs": [
"--inspect"
],
"program": "${workspaceFolder}/node_modules/.bin/nuxi",
"outputCapture": "std",
"args": [
"dev",
"playground"
]
"type": "node-terminal"
},
{
"type": "node",
"presentation": {
"group": "others"
},
"command": "npm run start",
"name": "Serve (dist)",
"request": "launch",
"name": "Debug (nuxt:generate)",
"runtimeVersion": "19.5.0",
"runtimeArgs": [
"--inspect"
],
"program": "${workspaceFolder}/node_modules/.bin/nuxt",
"outputCapture": "std",
"args": [
"generate",
"playground",
"--target",
"static"
]
},
{
"type": "node",
"request": "launch",
"name": "Debug (nuxt:build)",
"runtimeVersion": "19.5.0",
"runtimeArgs": [
"--inspect"
],
"program": "${workspaceFolder}/node_modules/.bin/nuxt",
"outputCapture": "std",
"args": [
"build",
"playground"
]
},
{
"type": "node",
"request": "launch",
"name": "Debug (nuxt:dev)",
"runtimeVersion": "19.5.0",
"runtimeArgs": [
"--inspect"
],
"program": "${workspaceFolder}/node_modules/.bin/nuxt",
"outputCapture": "std",
"args": [
"dev",
"playground"
]
},
{
"type": "node",
"request": "launch",
"name": "Debug (nuxi:prepare)",
"runtimeVersion": "19.5.0",
"runtimeArgs": [
"--inspect"
],
"program": "${workspaceFolder}/node_modules/.bin/nuxt",
"outputCapture": "std",
"args": [
"prepare",
"playground"
]
},
"type": "node-terminal"
}
]
}
100 changes: 100 additions & 0 deletions src/hookFunctions/nitro/init.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import { promises as fsPromises } from 'fs';
import { basename, dirname, join, resolve } from 'path';
import { parseDocument } from 'htmlparser2';
import { load } from 'cheerio';
import { render } from 'dom-serializer';
import { logger } from '../../utils.mjs';

export default (nuxt, disableNuxtCritters = true) =>
nitro => {
nitro.hooks.hook('prerender:generate', async route => {
if (!route.fileName?.endsWith('.html') || !route.contents) {
return;
}

const document = parseDocument(route.contents);
const $ = load(document);

$('[rel="modulepreload"][as="script"]').remove();
$('[rel="prefetch"][as="script"]').remove();

$('[rel="preload"][as="style"]').remove();
$('[rel="prefetch"][as="style"]').remove();

// embed css files
try {
const css = await Promise.all(
Array.from($('link[rel="stylesheet"]'))
.map(el => $(el))
.map(async $el => {
const dir = dirname($el.attr('href'));

// https://nuxt.com/docs/guide/directory-structure/output
const publicDir = join(
nuxt.options.rootDir,
'.output/public',
nuxt.options.vite.build.assetsDir
);
const filepath = join(publicDir, basename($el.attr('href')));
const fileContent = await fsPromises.readFile(filepath, 'utf-8');

Check warning on line 39 in src/hookFunctions/nitro/init.mjs

View workflow job for this annotation

GitHub Actions / Test & Build (ubuntu-latest, 19)

Found readFile from package "fs" with non literal argument at index 0

let urls = getUrlValues(fileContent);
urls = prepareUrls(urls, dir);

if (disableNuxtCritters) {
const css = urls.reduce(
(result, [a, b]) => result.replace(a, b),
fileContent
);

$el.remove();
logger.info(
`Embed CSS File \`${basename($el.attr('href'))}\`; Route: \`${
route.route
}\``
);
return css;
} else {
const matches = fileContent.match(
/\/\*! speedkit-font-faces start \*\/(.*)\/\*! speedkit-font-faces end \*\//
);
if (matches) {
logger.info(
`Embed Font-Faces CSS \`${basename(
$el.attr('href')
)}\`; Route: \`${route.route}\``
);
return matches[1].replace(/url\(.\//g, `url(${dir}/`);
}
}
})
);
if (css.length) {
$('head').append(`<style>${css.join('')}</style>`);
}
} catch (error) {
logger.error("can't embed css file.", error);
}

route.contents = render(document);
});
};

function getUrlValues(css) {
return css.match(/url\(([^)]+)\)/g);
}

function prepareUrls(urls, relativeDir) {
return urls
.map(url => {
const value = url
.trim()
.replace(/^url\((.*)\)$/, '$1')
.trim();
if (value.startsWith('http') || value.startsWith('data')) {
return false;
}
return [url, `url(${resolve(relativeDir, value)})`];
})
.filter(Boolean);
}
96 changes: 3 additions & 93 deletions src/utils/preload.mjs
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
import { promises as fsPromises } from 'fs';
import { basename, dirname, join, resolve } from 'path';
import { parseDocument } from 'htmlparser2';
import { load } from 'cheerio';
import { render } from 'dom-serializer';
import { isViteBuild, logger } from '../utils.mjs';
import initHook from '../hookFunctions/nitro/init.mjs';
import { isViteBuild } from '../utils.mjs';

// eslint-disable-next-line sonarjs/cognitive-complexity
export function optimizePreloads(moduleOptions, nuxt) {
const disableNuxtCritters = moduleOptions.disableNuxtCritters;

Expand All @@ -18,90 +13,5 @@ export function optimizePreloads(moduleOptions, nuxt) {

nuxt.options.experimental.inlineSSRStyles = false;

nuxt.hook('nitro:init', nitro => {
nitro.hooks.hook('prerender:generate', async route => {
if (!route.fileName?.endsWith('.html') || !route.contents) {
return;
}

const document = parseDocument(route.contents);
const $ = load(document);

$('[rel="modulepreload"][as="script"]').remove();
$('[rel="prefetch"][as="script"]').remove();

$('[rel="preload"][as="style"]').remove();
$('[rel="prefetch"][as="style"]').remove();

// embed css files
try {
const css = await Promise.all(
Array.from($('link[rel="stylesheet"]'))
.map(el => $(el))
.map(async $el => {
const dir = dirname($el.attr('href'));

// https://nuxt.com/docs/guide/directory-structure/output
const publicDir = join(
nuxt.options.rootDir,
'.output/public',
nuxt.options.vite.build.assetsDir
);
const filepath = join(publicDir, basename($el.attr('href')));
const fileContent = await fsPromises.readFile(filepath, 'utf-8');

let urls = getUrlValues(fileContent);
urls = prepareUrls(urls, dir);

if (disableNuxtCritters) {
const css = urls.reduce(
(result, [a, b]) => result.replace(a, b),
fileContent
);

$el.remove();
logger.info(
`Embed CSS File \`${basename($el.attr('href'))}\`; Route: \`${
route.route
}\``
);
return css;
} else {
const matches = fileContent.match(
/\/\*! speedkit-font-faces start \*\/(.*)\/\*! speedkit-font-faces end \*\//
);
if (matches) {
logger.info(
`Embed Font-Faces CSS \`${basename(
$el.attr('href')
)}\`; Route: \`${route.route}\``
);
return matches[1].replace(/url\(.\//g, `url(${dir}/`);
}
}
})
);
if (css.length) {
$('head').append(`<style>${css.join('')}</style>`);
}
} catch (error) {
logger.error("can't embed css file.", error);
}

route.contents = render(document);
});
});
}

function getUrlValues(css) {
return css.match(/url\(([^)]+)\)/g);
}

function prepareUrls(urls, relativeDir) {
return urls.map(url => {
return [
url,
`url(${resolve(relativeDir, url.replace(/^url\((.*)\)$/, '$1'))})`
];
});
nuxt.hook('nitro:init', initHook(nuxt, disableNuxtCritters));
}

0 comments on commit 8d65f2f

Please sign in to comment.