@webjourney/vite-plugins 1.2.10-0 → 1.2.10-2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/build.js +73 -39
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +14 -10
- package/package.json +1 -1
package/dist/build.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
+
import { JSDOM } from 'jsdom';
|
|
1
2
|
import { execSync } from 'node:child_process';
|
|
2
|
-
import { createRequire } from 'node:module';
|
|
3
3
|
import fs from 'node:fs';
|
|
4
|
+
import { createRequire } from 'node:module';
|
|
4
5
|
import path from 'node:path';
|
|
5
|
-
import { JSDOM } from 'jsdom';
|
|
6
6
|
export async function buildWithSSR(options = {}) {
|
|
7
7
|
const { projectRoot = process.cwd(), appPath = 'src/App.tsx', clientBuildOptions = '--base=\'./\'' } = options;
|
|
8
8
|
const toAbsolute = (p) => path.resolve(projectRoot, p);
|
|
@@ -86,6 +86,7 @@ async function prerender(projectRoot) {
|
|
|
86
86
|
// Setup globals for React SSR
|
|
87
87
|
const originalWindow = global.window;
|
|
88
88
|
const originalDocument = global.document;
|
|
89
|
+
const originalConsoleError = console.error;
|
|
89
90
|
Object.defineProperty(global, 'window', {
|
|
90
91
|
writable: true,
|
|
91
92
|
configurable: true,
|
|
@@ -96,6 +97,32 @@ async function prerender(projectRoot) {
|
|
|
96
97
|
configurable: true,
|
|
97
98
|
value: dom.window.document,
|
|
98
99
|
});
|
|
100
|
+
// Track if we're in a warning block (for multi-line warnings with stack traces)
|
|
101
|
+
let suppressingWarning = false;
|
|
102
|
+
// Suppress known SSR warnings from React and Radix UI
|
|
103
|
+
const filterWarnings = (...args) => {
|
|
104
|
+
const message = args[0]?.toString() || '';
|
|
105
|
+
// Filter out common SSR warnings
|
|
106
|
+
const ignoredWarnings = [
|
|
107
|
+
'Warning: ',
|
|
108
|
+
];
|
|
109
|
+
if (ignoredWarnings.some(warning => message.includes(warning))) {
|
|
110
|
+
suppressingWarning = true;
|
|
111
|
+
return true; // Suppress the warning
|
|
112
|
+
}
|
|
113
|
+
// Check if this looks like a stack trace continuation (indented lines starting with "at")
|
|
114
|
+
if (suppressingWarning && message.trim().startsWith('at ')) {
|
|
115
|
+
return true; // Suppress stack trace lines
|
|
116
|
+
}
|
|
117
|
+
// Reset suppression for non-stack-trace lines
|
|
118
|
+
suppressingWarning = false;
|
|
119
|
+
return suppressingWarning;
|
|
120
|
+
};
|
|
121
|
+
console.error = (...args) => {
|
|
122
|
+
if (!filterWarnings(...args)) {
|
|
123
|
+
originalConsoleError(...args);
|
|
124
|
+
}
|
|
125
|
+
};
|
|
99
126
|
// Import the server entry after setting up globals
|
|
100
127
|
const entryServerPath = toAbsolute('dist-ssr/.webjourney-entry-server.js');
|
|
101
128
|
const { render } = await import(entryServerPath);
|
|
@@ -103,44 +130,51 @@ async function prerender(projectRoot) {
|
|
|
103
130
|
const require = createRequire(path.join(projectRoot, 'package.json'));
|
|
104
131
|
const reactDomServerPath = require.resolve('react-dom/server');
|
|
105
132
|
const { renderToString } = await import(reactDomServerPath);
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
fs.
|
|
133
|
+
try {
|
|
134
|
+
// Extract routes from App.tsx
|
|
135
|
+
const routes = await extractRoutes(projectRoot);
|
|
136
|
+
console.log(` Found ${routes.length} route(s): ${routes.join(', ')}`);
|
|
137
|
+
for (const route of routes) {
|
|
138
|
+
// Render the app HTML
|
|
139
|
+
const appHtml = renderToString(render(route));
|
|
140
|
+
// Replace the empty root div with the rendered content
|
|
141
|
+
let html = template.replace('<div id="root"></div>', `<div id="root">${appHtml}</div>`);
|
|
142
|
+
// Adjust asset paths based on route depth
|
|
143
|
+
if (route !== '/') {
|
|
144
|
+
const depth = route.split('/').filter(Boolean).length;
|
|
145
|
+
const prefix = '../'.repeat(depth);
|
|
146
|
+
// Replace asset references: ./assets/ -> ../assets/ or ../../assets/ etc
|
|
147
|
+
html = html.replace(/\.\/assets\//g, `${prefix}assets/`);
|
|
148
|
+
}
|
|
149
|
+
// Write the pre-rendered HTML
|
|
150
|
+
const filePath = route === '/'
|
|
151
|
+
? toAbsolute('dist/index.html')
|
|
152
|
+
: toAbsolute(`dist${route}/index.html`);
|
|
153
|
+
// Ensure directory exists
|
|
154
|
+
const dir = path.dirname(filePath);
|
|
155
|
+
if (!fs.existsSync(dir)) {
|
|
156
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
157
|
+
}
|
|
158
|
+
fs.writeFileSync(filePath, html);
|
|
159
|
+
console.log(` Pre-rendered: ${route}`);
|
|
129
160
|
}
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
}
|
|
133
|
-
// Clean up
|
|
134
|
-
if (originalWindow !== undefined) {
|
|
135
|
-
global.window = originalWindow;
|
|
136
|
-
}
|
|
137
|
-
else {
|
|
138
|
-
delete global.window;
|
|
161
|
+
// Wait for any pending console messages to flush
|
|
162
|
+
await new Promise(resolve => setTimeout(resolve, 10));
|
|
139
163
|
}
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
164
|
+
finally {
|
|
165
|
+
// Clean up - always restore console methods even if there's an error
|
|
166
|
+
console.error = originalConsoleError;
|
|
167
|
+
if (originalWindow !== undefined) {
|
|
168
|
+
global.window = originalWindow;
|
|
169
|
+
}
|
|
170
|
+
else {
|
|
171
|
+
delete global.window;
|
|
172
|
+
}
|
|
173
|
+
if (originalDocument !== undefined) {
|
|
174
|
+
global.document = originalDocument;
|
|
175
|
+
}
|
|
176
|
+
else {
|
|
177
|
+
delete global.document;
|
|
178
|
+
}
|
|
145
179
|
}
|
|
146
180
|
}
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAeA,wBAAgB,uBAAuB;;;oBAKnB,MAAM,MAAM,MAAM;;;;EA6OrC;AAED,wBAAgB,sBAAsB;;;6BAKT,MAAM;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAeA,wBAAgB,uBAAuB;;;oBAKnB,MAAM,MAAM,MAAM;;;;EA6OrC;AAED,wBAAgB,sBAAsB;;;6BAKT,MAAM;EAoBlC;AAED,wBAAgB,iBAAiB;;;oBA1Qb,MAAM,MAAM,MAAM;;;;;;;6BAoPT,MAAM;KA0BlC"}
|
package/dist/index.js
CHANGED
|
@@ -116,13 +116,13 @@ export function webjourneyElementTagger() {
|
|
|
116
116
|
modified = true;
|
|
117
117
|
}
|
|
118
118
|
}
|
|
119
|
-
// Handle anchor elements
|
|
120
|
-
if (tagName === 'a') {
|
|
121
|
-
// Check if anchor has href attribute
|
|
122
|
-
const
|
|
119
|
+
// Handle anchor elements and Link components
|
|
120
|
+
if (tagName === 'a' || tagName === 'Link') {
|
|
121
|
+
// Check if anchor has href attribute or Link has to attribute
|
|
122
|
+
const hasHrefOrTo = openingElement.attributes.some((attr) => t.isJSXAttribute(attr) &&
|
|
123
123
|
t.isJSXIdentifier(attr.name) &&
|
|
124
|
-
attr.name.name === 'href');
|
|
125
|
-
if (
|
|
124
|
+
(attr.name.name === 'href' || attr.name.name === 'to'));
|
|
125
|
+
if (hasHrefOrTo) {
|
|
126
126
|
// Generate unique ID: filename:line
|
|
127
127
|
const elementId = `${relativePath}:${lineNumber}`;
|
|
128
128
|
openingElement.attributes.push(t.jsxAttribute(t.jsxIdentifier('data-wj-file'), t.stringLiteral(relativePath)), t.jsxAttribute(t.jsxIdentifier('data-wj-line'), t.stringLiteral(String(lineNumber))), t.jsxAttribute(t.jsxIdentifier('data-wj-type'), t.stringLiteral('link')), t.jsxAttribute(t.jsxIdentifier('data-wj-id'), t.stringLiteral(elementId)));
|
|
@@ -156,13 +156,17 @@ export function webjourneyPluginScript() {
|
|
|
156
156
|
name: 'webjourney-plugin-script',
|
|
157
157
|
enforce: 'pre',
|
|
158
158
|
transformIndexHtml(html) {
|
|
159
|
-
// Get project ID from environment
|
|
159
|
+
// Get project ID and badge visibility from environment variables
|
|
160
160
|
const projectId = process.env.WEBJOURNEY_PROJECT_ID;
|
|
161
|
-
|
|
162
|
-
|
|
161
|
+
const hideBadge = process.env.WEBJOURNEY_HIDE_BADGE === 'true';
|
|
162
|
+
// Build the meta tags
|
|
163
|
+
const projectIdTag = projectId
|
|
163
164
|
? `<meta name="webjourney-project-id" content="${projectId}">\n `
|
|
164
165
|
: '';
|
|
165
|
-
|
|
166
|
+
const hideBadgeTag = hideBadge
|
|
167
|
+
? `<meta name="webjourney-hide-badge" content="true">\n `
|
|
168
|
+
: '';
|
|
169
|
+
return html.replace('</head>', `${projectIdTag}${hideBadgeTag}<script src="${webjourneyPluginScriptHost}/plugins/plugin.iife.js"></script></head>`);
|
|
166
170
|
}
|
|
167
171
|
};
|
|
168
172
|
}
|