@dev-to/react-plugin 0.2.0 → 0.4.0

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.
@@ -1 +1 @@
1
- {"version":3,"file":"debugHtml.d.ts","sourceRoot":"","sources":["../src/debugHtml.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAEhE,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,OAAO,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,KAAK,EAAE,OAAO,CAAA;CACf;AAED,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,iBAAiB,CAAA;IACxB,uBAAuB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC/C,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACrC,KAAK,EAAE,WAAW,CAAA;IAClB,gBAAgB,EAAE,oBAAoB,CAAA;IACtC,gBAAgB,EAAE,MAAM,EAAE,CAAA;IAC1B,UAAU,EAAE,MAAM,GAAG,SAAS,CAAA;IAC9B,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,qBAAqB,UAyf5D"}
1
+ {"version":3,"file":"debugHtml.d.ts","sourceRoot":"","sources":["../src/debugHtml.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAEhE,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,OAAO,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,KAAK,EAAE,OAAO,CAAA;CACf;AAED,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,iBAAiB,CAAA;IACxB,uBAAuB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC/C,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACrC,KAAK,EAAE,WAAW,CAAA;IAClB,gBAAgB,EAAE,oBAAoB,CAAA;IACtC,gBAAgB,EAAE,MAAM,EAAE,CAAA;IAC1B,UAAU,EAAE,MAAM,GAAG,SAAS,CAAA;IAC9B,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,qBAAqB,UAskB5D"}
@@ -1 +1 @@
1
- {"version":3,"file":"debugTools.d.ts","sourceRoot":"","sources":["../src/debugTools.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,MAAM,CAAA;AAEzC,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,0BAA0B,EAAE,MAAM,YAAY,CAAA;AAG/H,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,cAAc,CAAA;IACxB,KAAK,EAAE,WAAW,CAAA;IAClB,KAAK,EAAE,iBAAiB,CAAA;IACxB,cAAc,EAAE,0BAA0B,CAAA;IAC1C,SAAS,EAAE,MAAM,CAAA;IACjB,IAAI,CAAC,EAAE,OAAO,CAAA;CACf;AAqFD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,aAAa,EAAE,GAAG,EAAE,iBAAiB,EAAE,KAAK,EAAE,iBAAiB,QAuSxG"}
1
+ {"version":3,"file":"debugTools.d.ts","sourceRoot":"","sources":["../src/debugTools.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,MAAM,CAAA;AAEzC,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,0BAA0B,EAAE,MAAM,YAAY,CAAA;AAG/H,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,cAAc,CAAA;IACxB,KAAK,EAAE,WAAW,CAAA;IAClB,KAAK,EAAE,iBAAiB,CAAA;IACxB,cAAc,EAAE,0BAA0B,CAAA;IAC1C,SAAS,EAAE,MAAM,CAAA;IACjB,IAAI,CAAC,EAAE,OAAO,CAAA;CACf;AAqFD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,aAAa,EAAE,GAAG,EAAE,iBAAiB,EAAE,KAAK,EAAE,iBAAiB,QAwUxG"}
package/dist/index.js CHANGED
@@ -4,6 +4,7 @@ import node_path from "node:path";
4
4
  import picocolors from "picocolors";
5
5
  import { mergeConfig } from "vite";
6
6
  import { exec } from "node:child_process";
7
+ import { fileURLToPath } from "node:url";
7
8
  import node_os from "node:os";
8
9
  import typescript from "typescript";
9
10
  const PLUGIN_NAME = DEV_TO_REACT_NAMESPACE;
@@ -237,17 +238,14 @@ function renderDebugHtml(params) {
237
238
 
238
239
  ${hasConfig ? `
239
240
  <table>
240
- <thead><tr><th>组件名称 <small class="muted">(Component Name)</small></th><th>映射入口 <small class="muted">(Short Path)</small></th></tr></thead>
241
+ <thead><tr><th>组件名称 <small class="muted">(Component Name)</small></th><th>映射入口 <small class="muted">(Short Path)</small></th><th>包装地址 <small class="muted">(UMD Wrapper)</small></th></tr></thead>
241
242
  <tbody>
242
243
  ${Object.entries(resolvedDevComponentMap).map(([name, entry])=>{
243
244
  const abs = entryPathMap[name];
244
245
  const displayPath = abs ? getShortPath(abs) : entry;
245
- return `<tr>
246
- <td><code class="code-name">${name}</code></td>
247
- <td>
248
- ${abs ? `<a href="${toVsCodeUrl(abs)}" class="link-code" title="点击在 IDE 中打开"><code>${escapeHtml(displayPath)}</code></a>` : `<code>${escapeHtml(entry)}</code>`}
249
- </td>
250
- </tr>`;
246
+ const wrapperUrl = (originCandidates[0] || 'http://localhost:5173') + '/__dev_to_react__/loader/' + name + '.js';
247
+ const entryHtml = abs ? '<a href="' + toVsCodeUrl(abs) + '" class="link-code" title="点击在 IDE 中打开"><code>' + escapeHtml(displayPath) + '</code></a>' : '<code>' + escapeHtml(entry) + '</code>';
248
+ return '<tr><td><code class="code-name">' + name + "</code></td><td>" + entryHtml + '</td><td><div style="display: flex; align-items: center; gap: 6px;"><code style="flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 12px;">' + escapeHtml(wrapperUrl) + '</code><button class="copy-wrapper-btn" data-url="' + wrapperUrl + '" style="padding: 2px 8px; font-size: 11px; border: 1px solid var(--b); background: #fff; border-radius: 4px; cursor: pointer; color: var(--t); transition: .2s;" title="复制包装地址">\uD83D\uDCCB</button></div></td></tr>';
251
249
  }).join('')}
252
250
  </tbody>
253
251
  </table>
@@ -329,6 +327,56 @@ reactHmrHostPlugin(<span class="str">'Demo'</span>, { open: <span class="kw">tru
329
327
  </details>
330
328
  </div>
331
329
 
330
+ <div class="card">
331
+ <h3>🎁 UMD 动态包装器 (Auto-Generated Wrapper)</h3>
332
+ <p class="muted">无需额外配置,每个组件都自动生成一个轻量级 UMD 包装器,可直接在无 React 框架支持的宿主环境中使用。</p>
333
+
334
+ <div class="info-grid">
335
+ <div class="info-label">端点:</div>
336
+ <div class="info-value"><code>/__dev_to_react__/loader/{ComponentName}.js</code></div>
337
+ <div class="info-label">作用:</div>
338
+ <div class="info-value">自动将组件导出为 React 组件实例,无需宿主集成 @dev-to/react-loader</div>
339
+ <div class="info-label">依赖:</div>
340
+ <div class="info-value"><code>react</code> &amp; <code>react-dom@18</code> (CDN 或本地)</div>
341
+ </div>
342
+
343
+ <details>
344
+ <summary>包装器工作原理与集成示例</summary>
345
+ <div style="margin-top: 12px;">
346
+ <h4 style="color: var(--t); font-size: 14px; margin-top: 0; margin-bottom: 8px;">🔧 什么是包装器?</h4>
347
+ <p class="muted" style="margin-bottom: 12px;">
348
+ 包装器是一个自动生成的 UMD 模块,它包装了原始的 render 函数并导出为 React 组件。
349
+ 这样,无论宿主是否集成了 ReactLoader,都能直接作为 React 组件使用。
350
+ </p>
351
+
352
+ <h4 style="color: var(--t); font-size: 14px; margin-top: 16px; margin-bottom: 8px;">📖 集成方式</h4>
353
+ <pre style="font-size: 12px; line-height: 1.7;">
354
+ <span class="cmt">// 1. 加载 React 和 ReactDOM</span>
355
+ <span class="kw">&lt;script&gt;</span> <span class="kw">src</span>=<span class="str">"https://unpkg.com/react@18/umd/react.production.min.js"</span> <span class="kw">&lt;/script&gt;</span>
356
+ <span class="kw">&lt;script&gt;</span> <span class="kw">src</span>=<span class="str">"https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"</span> <span class="kw">&lt;/script&gt;</span>
357
+
358
+ <span class="cmt">// 2. 加载包装器脚本</span>
359
+ <span class="kw">&lt;script&gt;</span> <span class="kw">src</span>=<span class="str">"\${originCandidates[0] || 'http://localhost:5173'}/__dev_to_react__/loader/{ComponentName}.js"</span> <span class="kw">&lt;/script&gt;</span>
360
+
361
+ <span class="cmt">// 3. 直接作为 React 组件使用</span>
362
+ <span class="kw">const</span> root = ReactDOM.createRoot(document.getElementById(<span class="str">'app'</span>));
363
+ root.render(React.createElement(window.ComponentName, { prop1: <span class="str">'value1'</span> }));
364
+
365
+ <span class="cmt">// 或在宿主 React 组件中使用</span>
366
+ <span class="kw">const</span> Component = window.ComponentName;
367
+ <span class="kw">&lt;&gt;</span>&lt;Component prop1=<span class="str">"value1"</span> /&gt;<span class="kw">&lt;/&gt;</span></pre>
368
+
369
+ <h4 style="color: var(--t); font-size: 14px; margin-top: 16px; margin-bottom: 8px;">⚡ 关键特性</h4>
370
+ <ul class="muted" style="margin: 8px 0; padding-left: 20px;">
371
+ <li><b>零配置</b>:自动为每个组件生成包装器,无需手动编写</li>
372
+ <li><b>兼容现有宿主</b>:支持 CommonJS、AMD、浏览器全局三种模式</li>
373
+ <li><b>自动依赖管理</b>:若未加载 React,包装器会自动从 CDN 加载(可配置)</li>
374
+ <li><b>轻量级</b>:仅包含加载逻辑,核心渲染由 ReactLoader 负责</li>
375
+ </ul>
376
+ </div>
377
+ </details>
378
+ </div>
379
+
332
380
  <div class="card">
333
381
  <h3>📦 构建与部署</h3>
334
382
  <p class="muted">执行 <code>vite build --mode lib</code> 将组件打包为 UMD 格式以供发布。</p>
@@ -467,6 +515,27 @@ CSS: <span class="str">dist/&lt;name&gt;/&lt;name&gt;.css</span></pre>
467
515
  setTimeout(() => { copyFullBtn.textContent = '复制原始命令'; }, 2000);
468
516
  });
469
517
 
518
+ // 绑定包装地址复制按钮事件
519
+ document.querySelectorAll('.copy-wrapper-btn').forEach(btn => {
520
+ btn.onclick = (e) => {
521
+ e.preventDefault();
522
+ const url = btn.getAttribute('data-url');
523
+ copy(url, () => {
524
+ const originalText = btn.textContent;
525
+ btn.textContent = '✓';
526
+ btn.style.borderColor = '#10b981';
527
+ btn.style.color = '#10b981';
528
+ setTimeout(() => {
529
+ btn.textContent = originalText;
530
+ btn.style.borderColor = '';
531
+ btn.style.color = '';
532
+ }, 1500);
533
+ });
534
+ };
535
+ btn.onmouseover = () => { btn.style.borderColor = 'var(--p)'; btn.style.color = 'var(--p)'; };
536
+ btn.onmouseout = () => { btn.style.borderColor = ''; btn.style.color = ''; };
537
+ });
538
+
470
539
  const serverActualPort = ${'number' == typeof actualPort ? actualPort : 'null'};
471
540
  document.getElementById('actualPortDisplay').textContent = serverActualPort || location.port || '-';
472
541
  })();
@@ -814,34 +883,49 @@ function generateLibBuildNextConfig(params) {
814
883
  };
815
884
  }
816
885
  function createLoaderUmdWrapper(options) {
817
- const { componentName, origin, contractEndpoint = constants_STABLE_CONTRACT_PATH } = options;
886
+ const { componentName, origin, contractEndpoint = constants_STABLE_CONTRACT_PATH, reactLoaderUrl = 'https://cdn.jsdelivr.net/npm/@dev-to/react-loader@latest/dist/index.umd.js' } = options;
818
887
  const globalName = toSafeUmdName(componentName);
819
888
  const code = `/**
820
889
  * UMD Loader Wrapper for component: ${componentName}
821
890
  * Global name: ${globalName}
822
891
  * Generated by ${constants_PLUGIN_LOG_PREFIX}
823
892
  *
824
- * This wrapper uses @dev-to/react-loader to dynamically load and render the component.
893
+ * This wrapper automatically exports a React component that can be used in any React environment.
894
+ * No need to manually integrate @dev-to/react-loader.
895
+ *
896
+ * ============= Quick Start =============
825
897
  *
826
- * Usage:
827
898
  * 1. Load React and ReactDOM:
828
899
  * <script crossorigin src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
829
900
  * <script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script>
830
901
  *
831
- * 2. Load ReactLoader:
832
- * <script src="https://cdn.jsdelivr.net/npm/@dev-to/react-loader@latest/dist/index.umd.js"></script>
833
- *
834
- * 3. Load this wrapper:
902
+ * 2. Load this wrapper:
835
903
  * <script src="${origin}/__dev_to_react__/loader/${componentName}.js"></script>
836
904
  *
837
- * 4. Render the component:
838
- * <div id="app"></div>
839
- * <script>
840
- * window.${globalName}.render(
841
- * document.getElementById('app'),
842
- * { /* your props */ }
843
- * );
844
- * </script>
905
+ * 3. Use as a React component:
906
+ *
907
+ * // Option A: Direct React rendering
908
+ * const Component = window.${globalName};
909
+ * const root = ReactDOM.createRoot(document.getElementById('app'));
910
+ * root.render(React.createElement(Component, { prop1: 'value1' }));
911
+ *
912
+ * // Option B: Use in JSX (if using Babel)
913
+ * const Component = window.${globalName};
914
+ * root.render(<Component prop1="value1" />);
915
+ *
916
+ * // Option C: Direct function call (legacy compatibility)
917
+ * window.${globalName}(document.getElementById('app'), { prop1: 'value1' })
918
+ * .then(root => console.log('Rendered'))
919
+ * .catch(err => console.error('Error:', err));
920
+ *
921
+ * ============= Features =============
922
+ * ✓ Zero configuration required
923
+ * ✓ Automatic React/ReactDOM detection
924
+ * ✓ Supports CommonJS, AMD, and global scope
925
+ * ✓ Auto-loads ReactLoader from CDN if needed
926
+ * ✓ Works in any React environment
927
+ *
928
+ * Note: Make sure React v18+ and react-dom/client are available globally.
845
929
  */
846
930
  (function (root, factory) {
847
931
  if (typeof exports === 'object' && typeof module !== 'undefined') {
@@ -853,20 +937,65 @@ function createLoaderUmdWrapper(options) {
853
937
  } else {
854
938
  // Browser globals
855
939
  var globalObj = typeof globalThis !== 'undefined' ? globalThis : (typeof self !== 'undefined' ? self : root);
856
- factory((globalObj.${globalName} = {}), globalObj.React, globalObj.ReactDOM, globalObj.DevToReactLoader);
940
+ var tempExports = {};
941
+ factory(tempExports, globalObj.React, globalObj.ReactDOM, globalObj.DevToReactLoader);
942
+ globalObj.${globalName} = tempExports.default;
857
943
  }
858
944
  })(this, function (exports, React, ReactDOM, ReactLoaderModule) {
859
945
  'use strict';
860
946
 
861
- // Get ReactLoader component from the module
862
- var ReactLoader = ReactLoaderModule && ReactLoaderModule.ReactLoader;
947
+ var ReactLoader = null;
948
+ var loadingPromise = null;
949
+
950
+ // Helper function to load a script dynamically
951
+ function loadScript(src) {
952
+ return new Promise(function(resolve, reject) {
953
+ var script = document.createElement('script');
954
+ script.src = src;
955
+ script.onload = resolve;
956
+ script.onerror = reject;
957
+ document.head.appendChild(script);
958
+ });
959
+ }
960
+
961
+ // Helper function to ensure ReactLoader is loaded
962
+ function ensureReactLoaderLoaded() {
963
+ if (ReactLoader) {
964
+ return Promise.resolve();
965
+ }
966
+
967
+ if (!loadingPromise) {
968
+ loadingPromise = (function() {
969
+ // First, try to get ReactLoader from the global scope
970
+ if (typeof window !== 'undefined' && window.DevToReactLoader && window.DevToReactLoader.ReactLoader) {
971
+ ReactLoader = window.DevToReactLoader.ReactLoader;
972
+ return Promise.resolve();
973
+ }
863
974
 
864
- if (!ReactLoader) {
865
- throw new Error(
866
- '${constants_PLUGIN_LOG_PREFIX} ReactLoader not found. ' +
867
- 'Please load @dev-to/react-loader before this script: ' +
868
- '<script src="https://cdn.jsdelivr.net/npm/@dev-to/react-loader@latest/dist/index.umd.js"></script>'
869
- );
975
+ // If not available, load it from URL
976
+ console.log('${constants_PLUGIN_LOG_PREFIX} Loading @dev-to/react-loader...');
977
+ return loadScript(${JSON.stringify(reactLoaderUrl)})
978
+ .then(function() {
979
+ if (typeof window !== 'undefined' && window.DevToReactLoader && window.DevToReactLoader.ReactLoader) {
980
+ ReactLoader = window.DevToReactLoader.ReactLoader;
981
+ console.log('${constants_PLUGIN_LOG_PREFIX} ReactLoader loaded successfully');
982
+ } else {
983
+ throw new Error('${constants_PLUGIN_LOG_PREFIX} ReactLoader not found after loading');
984
+ }
985
+ })
986
+ .catch(function(error) {
987
+ console.error('${constants_PLUGIN_LOG_PREFIX} Failed to load ReactLoader:', error);
988
+ throw error;
989
+ });
990
+ })();
991
+ }
992
+
993
+ return loadingPromise;
994
+ }
995
+
996
+ // Try to get ReactLoader from the module if available
997
+ if (ReactLoaderModule && ReactLoaderModule.ReactLoader) {
998
+ ReactLoader = ReactLoaderModule.ReactLoader;
870
999
  }
871
1000
 
872
1001
  // Component configuration
@@ -892,28 +1021,59 @@ function createLoaderUmdWrapper(options) {
892
1021
  throw new Error('${constants_PLUGIN_LOG_PREFIX} ReactDOM is not loaded');
893
1022
  }
894
1023
 
895
- // Create ReactLoader component props
896
- var loaderProps = {
897
- origin: config.origin,
898
- name: config.name,
899
- contractEndpoint: config.contractEndpoint,
900
- componentProps: componentProps || {}
901
- };
1024
+ // Ensure ReactLoader is available before rendering
1025
+ return ensureReactLoaderLoaded().then(function() {
1026
+ if (!ReactLoader) {
1027
+ throw new Error('${constants_PLUGIN_LOG_PREFIX} ReactLoader initialization failed');
1028
+ }
1029
+
1030
+ // Create ReactLoader component props
1031
+ var loaderProps = {
1032
+ origin: config.origin,
1033
+ name: config.name,
1034
+ contractEndpoint: config.contractEndpoint,
1035
+ componentProps: componentProps || {}
1036
+ };
902
1037
 
903
- // Render using ReactLoader
904
- var root = ReactDOM.createRoot(targetElement);
905
- root.render(React.createElement(ReactLoader, loaderProps));
1038
+ // Render using ReactLoader
1039
+ var root = ReactDOM.createRoot(targetElement);
1040
+ root.render(React.createElement(ReactLoader, loaderProps));
906
1041
 
907
- return root;
1042
+ return root;
1043
+ });
908
1044
  }
909
1045
 
910
- // Export the API
911
- exports.render = render;
912
- exports.config = config;
913
- exports.default = { render: render, config: config };
1046
+ // Create a React component wrapper for the render function
1047
+ function ComponentWrapper(props) {
1048
+ var containerRef = React.useRef(null);
1049
+ var isFirstRender = React.useRef(true);
914
1050
 
915
- // Mark as ES module
916
- Object.defineProperty(exports, '__esModule', { value: true });
1051
+ React.useEffect(function() {
1052
+ if (!containerRef.current) return;
1053
+
1054
+ render(containerRef.current, props).catch(function(err) {
1055
+ console.error('${constants_PLUGIN_LOG_PREFIX} Failed to render ${componentName}:', err);
1056
+ console.error('${constants_PLUGIN_LOG_PREFIX} Props:', props);
1057
+ });
1058
+
1059
+ if (isFirstRender.current) {
1060
+ isFirstRender.current = false;
1061
+ if (typeof console !== 'undefined' && console.info) {
1062
+ console.info(
1063
+ '%c${constants_PLUGIN_LOG_PREFIX}%c Successfully loaded and rendered component: %c${componentName}',
1064
+ 'color: #10b981; font-weight: bold;',
1065
+ 'color: #64748b;',
1066
+ 'color: #3b82f6; font-weight: bold;'
1067
+ );
1068
+ }
1069
+ }
1070
+ }, [props]);
1071
+
1072
+ return React.createElement('div', { ref: containerRef });
1073
+ }
1074
+
1075
+ // Export the API
1076
+ exports.default = ComponentWrapper;
917
1077
  });
918
1078
  `;
919
1079
  return code;
@@ -1113,6 +1273,27 @@ function installDebugTools(server, ctx, state) {
1113
1273
  }, null, 2));
1114
1274
  return;
1115
1275
  }
1276
+ if (pathname === `${STABLE_BASE_PATH}/react-loader.js`) try {
1277
+ const __filename = fileURLToPath(import.meta.url);
1278
+ const __dirname = node_path.dirname(__filename);
1279
+ const reactLoaderUmdPath = node_path.resolve(__dirname, '../../react-loader/dist/index.umd.js');
1280
+ if (node_fs.existsSync(reactLoaderUmdPath)) {
1281
+ const umdCode = node_fs.readFileSync(reactLoaderUmdPath, 'utf-8');
1282
+ res.statusCode = 200;
1283
+ res.setHeader('Content-Type', "application/javascript; charset=utf-8");
1284
+ res.setHeader('Access-Control-Allow-Origin', '*');
1285
+ res.setHeader('Cache-Control', 'no-cache, no-store, must-revalidate');
1286
+ res.end(umdCode);
1287
+ return;
1288
+ }
1289
+ res.statusCode = 404;
1290
+ res.end(`react-loader UMD not found at ${reactLoaderUmdPath}. Run 'pnpm build' in react-loader package.`);
1291
+ return;
1292
+ } catch (error) {
1293
+ res.statusCode = 500;
1294
+ res.end(`Error loading react-loader UMD: ${error}`);
1295
+ return;
1296
+ }
1116
1297
  if (pathname.startsWith(STABLE_LOADER_BASE_PATH)) {
1117
1298
  const loaderPathPattern = new RegExp(`^${STABLE_LOADER_BASE_PATH}/([^/]+)\\.js$`);
1118
1299
  const match = pathname.match(loaderPathPattern);
@@ -1127,7 +1308,8 @@ function installDebugTools(server, ctx, state) {
1127
1308
  const code = createLoaderUmdWrapper({
1128
1309
  componentName,
1129
1310
  origin,
1130
- contractEndpoint: constants_STABLE_CONTRACT_PATH
1311
+ contractEndpoint: constants_STABLE_CONTRACT_PATH,
1312
+ reactLoaderUrl: `${origin}${STABLE_BASE_PATH}/react-loader.js`
1131
1313
  });
1132
1314
  res.statusCode = 200;
1133
1315
  res.setHeader('Content-Type', "application/javascript; charset=utf-8");
@@ -2,6 +2,7 @@ interface CreateLoaderUmdWrapperOptions {
2
2
  componentName: string;
3
3
  origin: string;
4
4
  contractEndpoint?: string;
5
+ reactLoaderUrl?: string;
5
6
  }
6
7
  /**
7
8
  * Generate a lightweight UMD wrapper that uses @dev-to/react-loader to load the component.
@@ -1 +1 @@
1
- {"version":3,"file":"loaderUmdWrapper.d.ts","sourceRoot":"","sources":["../src/loaderUmdWrapper.ts"],"names":[],"mappings":"AAGA,UAAU,6BAA6B;IACrC,aAAa,EAAE,MAAM,CAAA;IACrB,MAAM,EAAE,MAAM,CAAA;IACd,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAC1B;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,6BAA6B,GAAG,MAAM,CA2GrF"}
1
+ {"version":3,"file":"loaderUmdWrapper.d.ts","sourceRoot":"","sources":["../src/loaderUmdWrapper.ts"],"names":[],"mappings":"AAGA,UAAU,6BAA6B;IACrC,aAAa,EAAE,MAAM,CAAA;IACrB,MAAM,EAAE,MAAM,CAAA;IACd,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,6BAA6B,GAAG,MAAM,CA2MrF"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dev-to/react-plugin",
3
- "version": "0.2.0",
3
+ "version": "0.4.0",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -31,7 +31,7 @@
31
31
  "dependencies": {
32
32
  "picocolors": "^1.1.0",
33
33
  "typescript": "^5.4.5",
34
- "@dev-to/react-shared": "0.1.1"
34
+ "@dev-to/react-shared": "0.1.2"
35
35
  },
36
36
  "scripts": {
37
37
  "build": "rslib build",