diff --git a/.vscode/launch.json b/.vscode/launch.json
index d5d96dbce8..354524dceb 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -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"
+ }
]
}
diff --git a/src/hookFunctions/nitro/init.mjs b/src/hookFunctions/nitro/init.mjs
new file mode 100644
index 0000000000..b8b9885bcc
--- /dev/null
+++ b/src/hookFunctions/nitro/init.mjs
@@ -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');
+
+ 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(``);
+ }
+ } 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);
+}
diff --git a/src/utils/preload.mjs b/src/utils/preload.mjs
index db1033209c..567083da4e 100644
--- a/src/utils/preload.mjs
+++ b/src/utils/preload.mjs
@@ -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;
@@ -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(``);
- }
- } 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));
}