@blocklet/pages-kit-block-studio 0.5.55 → 0.6.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.
@@ -154,7 +154,7 @@ exports.initBlockStudioRouter.get('/', async (req, res) => {
154
154
  return res.json(metadata);
155
155
  }
156
156
  catch (error) {
157
- return res.status(500).json({ error: 'Failed to read file' });
157
+ return res.status(400).json({ error: 'Failed to read file' });
158
158
  }
159
159
  });
160
160
  exports.initBlockStudioRouter.post('/', async (req, res) => {
@@ -202,7 +202,7 @@ exports.initBlockStudioRouter.post('/', async (req, res) => {
202
202
  return res.json({ success: true, content: mergedContent, message: 'Updated' });
203
203
  }
204
204
  catch (error) {
205
- return res.status(500).json({ error: 'Failed to write file' });
205
+ return res.status(400).json({ error: 'Failed to write file' });
206
206
  }
207
207
  });
208
208
  exports.initBlockStudioRouter.post('/create', async (req, res) => {
@@ -264,7 +264,7 @@ exports.initBlockStudioRouter.post('/create', async (req, res) => {
264
264
  }
265
265
  catch (error) {
266
266
  console.error('Failed to create block:', error);
267
- return res.status(500).json({ error: 'Failed to create block' });
267
+ return res.status(400).json({ error: 'Failed to create block' });
268
268
  }
269
269
  });
270
270
  exports.initBlockStudioRouter.get('/resources', async (req, res) => {
@@ -358,7 +358,7 @@ exports.initBlockStudioRouter.post('/properties-to-interface', async (req, res)
358
358
  }
359
359
  catch (conversionError) {
360
360
  console.error('Failed to convert properties to interface:', conversionError);
361
- return res.status(500).json({
361
+ return res.status(400).json({
362
362
  success: false,
363
363
  error: `Failed to convert properties to interface: ${conversionError.message}`,
364
364
  });
@@ -366,7 +366,7 @@ exports.initBlockStudioRouter.post('/properties-to-interface', async (req, res)
366
366
  }
367
367
  catch (error) {
368
368
  console.error('Failed to generate interface:', error);
369
- return res.status(500).json({
369
+ return res.status(400).json({
370
370
  success: false,
371
371
  error: `Failed to generate interface: ${error.message}`,
372
372
  });
@@ -424,7 +424,7 @@ exports.initBlockStudioRouter.post('/interface-to-properties', async (req, res)
424
424
  }
425
425
  catch (conversionError) {
426
426
  console.error('Failed to convert interface to properties:', conversionError);
427
- return res.status(500).json({
427
+ return res.status(400).json({
428
428
  success: false,
429
429
  error: `Failed to convert interface to properties: ${conversionError.message}`,
430
430
  });
@@ -432,7 +432,7 @@ exports.initBlockStudioRouter.post('/interface-to-properties', async (req, res)
432
432
  }
433
433
  catch (error) {
434
434
  console.error('Failed to generate metadata:', error);
435
- return res.status(500).json({
435
+ return res.status(400).json({
436
436
  success: false,
437
437
  error: `Failed to generate metadata: ${error.message}`,
438
438
  });
@@ -494,7 +494,7 @@ exports.initBlockStudioRouter.delete('/delete', async (req, res) => {
494
494
  }
495
495
  catch (deleteError) {
496
496
  console.error('Failed to delete component directory:', deleteError);
497
- return res.status(500).json({
497
+ return res.status(400).json({
498
498
  success: false,
499
499
  error: `Failed to delete component directory: ${deleteError.message}`,
500
500
  });
@@ -502,7 +502,7 @@ exports.initBlockStudioRouter.delete('/delete', async (req, res) => {
502
502
  }
503
503
  catch (error) {
504
504
  console.error('Failed to delete component:', error);
505
- return res.status(500).json({
505
+ return res.status(400).json({
506
506
  success: false,
507
507
  error: `Failed to delete component: ${error.message}`,
508
508
  });
@@ -292,7 +292,7 @@ exports.initResourceRouter.post('/', async (req, res) => {
292
292
  }
293
293
  catch (error) {
294
294
  console.error('Build failed:', error);
295
- res.status(500).json({ error: 'Build failed' });
295
+ res.status(400).json({ error: 'Build failed' });
296
296
  }
297
297
  });
298
298
  exports.default = exports.initResourceRouter;
@@ -246,20 +246,24 @@ const ComparisonPreviewDialog = ({ open, title, leftTitle, leftContent, rightTit
246
246
  Toast_1.default.error(t('themeTranslations.operationFailed'));
247
247
  }
248
248
  };
249
- return ((0, jsx_runtime_1.jsxs)(material_1.Dialog, { open: open, onClose: onClose, maxWidth: "md", fullWidth: true, children: [(0, jsx_runtime_1.jsx)(material_1.DialogTitle, { children: title }), (0, jsx_runtime_1.jsx)(material_1.DialogContent, { children: (0, jsx_runtime_1.jsxs)(material_1.Box, { children: [(0, jsx_runtime_1.jsxs)(material_1.Box, { sx: { display: 'flex', flexDirection: 'row', mb: 2 }, children: [(0, jsx_runtime_1.jsxs)(material_1.Box, { sx: { flex: 1, mr: 1 }, children: [(0, jsx_runtime_1.jsx)(material_1.Typography, { variant: "subtitle2", sx: { mb: 1 }, children: leftTitle }), (0, jsx_runtime_1.jsx)(material_1.TextField, { multiline: true, fullWidth: true, rows: 10, InputProps: {
250
- readOnly: true,
251
- }, value: leftContent, sx: {
249
+ return ((0, jsx_runtime_1.jsxs)(material_1.Dialog, { open: open, onClose: onClose, maxWidth: "md", fullWidth: true, children: [(0, jsx_runtime_1.jsx)(material_1.DialogTitle, { children: title }), (0, jsx_runtime_1.jsx)(material_1.DialogContent, { children: (0, jsx_runtime_1.jsxs)(material_1.Box, { children: [(0, jsx_runtime_1.jsxs)(material_1.Box, { sx: { display: 'flex', flexDirection: 'row', mb: 2 }, children: [(0, jsx_runtime_1.jsxs)(material_1.Box, { sx: { flex: 1, mr: 1 }, children: [(0, jsx_runtime_1.jsx)(material_1.Typography, { variant: "subtitle2", sx: { mb: 1 }, children: leftTitle }), (0, jsx_runtime_1.jsx)(material_1.TextField, { multiline: true, fullWidth: true, rows: 10, value: leftContent, sx: {
252
250
  '& .MuiOutlinedInput-root': {
253
251
  fontFamily: 'monospace',
254
252
  fontSize: '0.875rem',
255
253
  },
256
- } })] }), (0, jsx_runtime_1.jsxs)(material_1.Box, { sx: { flex: 1, ml: 1 }, children: [(0, jsx_runtime_1.jsx)(material_1.Typography, { variant: "subtitle2", sx: { mb: 1 }, children: rightTitle }), (0, jsx_runtime_1.jsx)(material_1.TextField, { multiline: true, fullWidth: true, rows: 10, InputProps: {
257
- readOnly: true,
258
- }, value: rightContent, sx: {
254
+ }, slotProps: {
255
+ input: {
256
+ readOnly: true,
257
+ },
258
+ } })] }), (0, jsx_runtime_1.jsxs)(material_1.Box, { sx: { flex: 1, ml: 1 }, children: [(0, jsx_runtime_1.jsx)(material_1.Typography, { variant: "subtitle2", sx: { mb: 1 }, children: rightTitle }), (0, jsx_runtime_1.jsx)(material_1.TextField, { multiline: true, fullWidth: true, rows: 10, value: rightContent, sx: {
259
259
  '& .MuiOutlinedInput-root': {
260
260
  fontFamily: 'monospace',
261
261
  fontSize: '0.875rem',
262
262
  },
263
+ }, slotProps: {
264
+ input: {
265
+ readOnly: true,
266
+ },
263
267
  } })] })] }), (0, jsx_runtime_1.jsx)(material_1.Typography, { variant: "body2", sx: { mt: 2, color: 'text.secondary' }, children: description })] }) }), (0, jsx_runtime_1.jsxs)(material_1.Box, { sx: { display: 'flex', justifyContent: 'flex-end', p: 2 }, children: [(0, jsx_runtime_1.jsx)(material_1.Button, { variant: "outlined", onClick: onClose, sx: { mr: 1 }, children: t('themeTranslations.cancel') }), (0, jsx_runtime_1.jsx)(material_1.Button, { variant: "contained", onClick: handleConfirm, disabled: loading, children: loading ? (0, jsx_runtime_1.jsx)(material_1.CircularProgress, { size: 24 }) : t('themeTranslations.confirmUpdate') })] })] }));
264
268
  };
265
269
  function Layout({ loadState, loadedData }) {
@@ -521,7 +525,11 @@ function Layout({ loadState, loadedData }) {
521
525
  triggerRerender();
522
526
  }, [JSON.stringify(mergedPropertiesValues), JSON.stringify(mergedAllBlocks), state.metadata.id, locale]);
523
527
  const DraggingSplitPlaceholder = (0, react_1.useMemo)(() => {
524
- return ((0, jsx_runtime_1.jsx)(material_1.Box, { p: 1.5, width: "100%", height: "100%", children: (0, jsx_runtime_1.jsx)(material_1.Skeleton, { variant: "rectangular", height: "100%", sx: { borderRadius: 1 } }) }));
528
+ return ((0, jsx_runtime_1.jsx)(material_1.Box, { sx: {
529
+ p: 1.5,
530
+ width: '100%',
531
+ height: '100%',
532
+ }, children: (0, jsx_runtime_1.jsx)(material_1.Skeleton, { variant: "rectangular", height: "100%", sx: { borderRadius: 1 } }) }));
525
533
  }, []);
526
534
  // Move item function for drag and drop
527
535
  const moveItem = (0, react_1.useCallback)((dragIndex, hoverIndex) => {
@@ -608,7 +616,16 @@ function Layout({ loadState, loadedData }) {
608
616
  if (state.draggingSplitPane) {
609
617
  return DraggingSplitPlaceholder;
610
618
  }
611
- return ((0, jsx_runtime_1.jsxs)(material_1.Stack, { height: "100%", children: [(0, jsx_runtime_1.jsxs)(material_1.Stack, { gap: 1, direction: "row", alignItems: "center", sx: { pt: 2, pr: 1, pl: 0.5, pb: 1 }, children: [(0, jsx_runtime_1.jsx)(material_1.TextField, { placeholder: t('themeTranslations.search'), sx: { minWidth: 60, flex: 1 }, onChange: (e) => {
619
+ return ((0, jsx_runtime_1.jsxs)(material_1.Stack, { sx: {
620
+ height: '100%',
621
+ }, children: [(0, jsx_runtime_1.jsxs)(material_1.Stack, { direction: "row", sx: {
622
+ gap: 1,
623
+ alignItems: 'center',
624
+ pt: 2,
625
+ pr: 1,
626
+ pl: 0.5,
627
+ pb: 1,
628
+ }, children: [(0, jsx_runtime_1.jsx)(material_1.TextField, { placeholder: t('themeTranslations.search'), sx: { minWidth: 60, flex: 1 }, onChange: (e) => {
612
629
  state.searchValue = e.target.value;
613
630
  } }), hasCustomSort && ((0, jsx_runtime_1.jsx)(material_1.Tooltip, { title: t('themeTranslations.resetToAlphabeticalSort'), children: (0, jsx_runtime_1.jsx)(material_1.IconButton, { size: "small", onClick: () => {
614
631
  setCustomSortOrder([]);
@@ -643,12 +660,27 @@ function Layout({ loadState, loadedData }) {
643
660
  }
644
661
  }, onDelete: handleDeleteBlock, index: index, moveItem: moveItem, showDragHandle: true, routes: routes }, route));
645
662
  })
646
- .filter(Boolean) })) : ((0, jsx_runtime_1.jsx)(material_1.Box, { display: "flex", justifyContent: "center", alignItems: "center", height: "100%", sx: { p: 3 }, children: (0, jsx_runtime_1.jsxs)(material_1.Stack, { alignItems: "center", spacing: 3, sx: { textAlign: 'center' }, children: [(0, jsx_runtime_1.jsx)(material_1.Box, { component: "img", src: "https://api.iconify.design/material-symbols:folder-open-outline.svg", sx: {
663
+ .filter(Boolean) })) : ((0, jsx_runtime_1.jsx)(material_1.Box, { sx: {
664
+ display: 'flex',
665
+ justifyContent: 'center',
666
+ alignItems: 'center',
667
+ height: '100%',
668
+ p: 3,
669
+ }, children: (0, jsx_runtime_1.jsxs)(material_1.Stack, { spacing: 3, sx: {
670
+ alignItems: 'center',
671
+ textAlign: 'center',
672
+ }, children: [(0, jsx_runtime_1.jsx)(material_1.Box, { component: "img", src: "https://api.iconify.design/material-symbols:folder-open-outline.svg", sx: {
647
673
  width: 48,
648
674
  height: 48,
649
675
  opacity: 0.5,
650
676
  filter: 'grayscale(100%)',
651
- }, alt: "No components" }), (0, jsx_runtime_1.jsx)(material_1.Typography, { variant: "h6", color: "text.primary", sx: { fontWeight: 600 }, children: t('themeTranslations.noComponentsFound') }), (0, jsx_runtime_1.jsx)(material_1.Typography, { variant: "body2", color: "text.secondary", sx: { maxWidth: 200 }, children: t('themeTranslations.createFirstComponent') }), (0, jsx_runtime_1.jsx)(material_1.Button, { variant: "contained", startIcon: (0, jsx_runtime_1.jsx)(Add_1.default, {}), onClick: () => {
677
+ }, alt: "No components" }), (0, jsx_runtime_1.jsx)(material_1.Typography, { variant: "h6", sx: {
678
+ color: 'text.primary',
679
+ fontWeight: 600,
680
+ }, children: t('themeTranslations.noComponentsFound') }), (0, jsx_runtime_1.jsx)(material_1.Typography, { variant: "body2", sx: {
681
+ color: 'text.secondary',
682
+ maxWidth: 200,
683
+ }, children: t('themeTranslations.createFirstComponent') }), (0, jsx_runtime_1.jsx)(material_1.Button, { variant: "contained", startIcon: (0, jsx_runtime_1.jsx)(Add_1.default, {}), onClick: () => {
652
684
  state.createBlockOpen = true;
653
685
  }, sx: { mt: 2 }, children: t('themeTranslations.createComponent') })] }) }))] }));
654
686
  }, [
@@ -673,7 +705,13 @@ function Layout({ loadState, loadedData }) {
673
705
  return null;
674
706
  }
675
707
  if (loadState.type === 'load-error') {
676
- return ((0, jsx_runtime_1.jsx)(material_1.Box, { width: "100%", height: "100%", display: "flex", justifyContent: "center", alignItems: "center", children: (0, jsx_runtime_1.jsx)(material_1.Alert, { severity: "error", variant: "filled", children: t('themeTranslations.failedLoadCode') }) }));
708
+ return ((0, jsx_runtime_1.jsx)(material_1.Box, { sx: {
709
+ width: '100%',
710
+ height: '100%',
711
+ display: 'flex',
712
+ justifyContent: 'center',
713
+ alignItems: 'center',
714
+ }, children: (0, jsx_runtime_1.jsx)(material_1.Alert, { severity: "error", variant: "filled", children: t('themeTranslations.failedLoadCode') }) }));
677
715
  }
678
716
  // 从 URL 获取初始组件 ID 和语言
679
717
  const url = new URL(window.location.href);
@@ -687,7 +725,13 @@ function Layout({ loadState, loadedData }) {
687
725
  }
688
726
  // 没有匹配到路由,使用欢迎页面
689
727
  if (notSelectedBlock) {
690
- return ((0, jsx_runtime_1.jsxs)(material_1.Box, { width: "100%", height: "100%", display: "flex", flexDirection: "column", justifyContent: "center", alignItems: "center", sx: {
728
+ return ((0, jsx_runtime_1.jsxs)(material_1.Box, { sx: {
729
+ width: '100%',
730
+ height: '100%',
731
+ display: 'flex',
732
+ flexDirection: 'column',
733
+ justifyContent: 'center',
734
+ alignItems: 'center',
691
735
  backgroundColor: 'background.default',
692
736
  p: 3,
693
737
  textAlign: 'center',
@@ -879,12 +923,18 @@ function Layout({ loadState, loadedData }) {
879
923
  justifyContent: 'center',
880
924
  alignItems: 'center',
881
925
  p: 3,
882
- }, children: (0, jsx_runtime_1.jsxs)(material_1.Stack, { alignItems: "center", spacing: 2, sx: {
926
+ }, children: (0, jsx_runtime_1.jsxs)(material_1.Stack, { spacing: 2, sx: {
927
+ alignItems: 'center',
883
928
  textAlign: 'center',
884
929
  bgcolor: 'background.default',
885
930
  borderRadius: 2,
886
931
  p: 3,
887
- }, children: [(0, jsx_runtime_1.jsx)(Settings_1.default, { sx: { fontSize: 48, color: 'primary.main' } }), (0, jsx_runtime_1.jsxs)(material_1.Stack, { spacing: 1, children: [(0, jsx_runtime_1.jsx)(material_1.Typography, { variant: "h6", color: "primary.main", sx: { fontWeight: 600 }, children: t('themeTranslations.componentPropertiesTitle') }), (0, jsx_runtime_1.jsx)(material_1.Typography, { variant: "body2", color: "text.secondary", children: t('themeTranslations.selectComponentToConfigureProperties') })] })] }) })), (0, jsx_runtime_1.jsx)(material_1.ListItem, { children: (0, jsx_runtime_1.jsx)(material_1.Box, { sx: { width: '100%' }, children: (0, jsx_runtime_1.jsx)(components_1.BasicInfo, { config: state.metadata }) }) }), (0, jsx_runtime_1.jsx)(material_1.ListItem, { children: (0, jsx_runtime_1.jsxs)(material_1.Box, { sx: { width: '100%' }, children: [(0, jsx_runtime_1.jsx)(components_1.PropertiesConfig, { config: state.metadata, currentLocale: locale, defaultLocale: defaultLocale, allComponents: mergedAllBlocks, onUpdateConfig: (updater) => {
932
+ }, children: [(0, jsx_runtime_1.jsx)(Settings_1.default, { sx: { fontSize: 48, color: 'primary.main' } }), (0, jsx_runtime_1.jsxs)(material_1.Stack, { spacing: 1, children: [(0, jsx_runtime_1.jsx)(material_1.Typography, { variant: "h6", sx: {
933
+ color: 'primary.main',
934
+ fontWeight: 600,
935
+ }, children: t('themeTranslations.componentPropertiesTitle') }), (0, jsx_runtime_1.jsx)(material_1.Typography, { variant: "body2", sx: {
936
+ color: 'text.secondary',
937
+ }, children: t('themeTranslations.selectComponentToConfigureProperties') })] })] }) })), (0, jsx_runtime_1.jsx)(material_1.ListItem, { children: (0, jsx_runtime_1.jsx)(material_1.Box, { sx: { width: '100%' }, children: (0, jsx_runtime_1.jsx)(components_1.BasicInfo, { config: state.metadata }) }) }), (0, jsx_runtime_1.jsx)(material_1.ListItem, { children: (0, jsx_runtime_1.jsxs)(material_1.Box, { sx: { width: '100%' }, children: [(0, jsx_runtime_1.jsx)(components_1.PropertiesConfig, { config: state.metadata, currentLocale: locale, defaultLocale: defaultLocale, allComponents: mergedAllBlocks, onUpdateConfig: (updater) => {
888
938
  updater(state.metadata);
889
939
  }, useI18nEditor: false }), (0, jsx_runtime_1.jsxs)(material_1.Stack, { direction: "column", spacing: 1, sx: { mt: 1 }, children: [(0, jsx_runtime_1.jsx)(material_1.Button, { variant: "contained", size: "small", color: "primary", onClick: async () => {
890
940
  try {
@@ -60,14 +60,35 @@ const vite_plugin_html_transform_1 = require("./vite-plugin-html-transform");
60
60
  const vite_plugin_import_transform_1 = require("./vite-plugin-import-transform");
61
61
  // const BUILTIN_MODULES_VAR = '__PAGES_KIT_BUILTIN_MODULES__';
62
62
  // logger.log('BUILTIN_MODULES_VAR', BUILTIN_MODULES_VAR);
63
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
64
- const isMatchAfterSlachExternals = (_id) => {
63
+ // 检查模块ID是否匹配外部依赖(包括子路径)
64
+ const isMatchAfterSlachExternals = (id, externals) => {
65
+ // 精确匹配
66
+ if (externals[id]) {
67
+ return true;
68
+ }
69
+ // 子路径匹配,特别处理 React 相关模块
70
+ const reactModules = ['react', 'react-dom', 'react/jsx-runtime', 'react/jsx-dev-runtime', 'react-dom/client'];
71
+ // 检查是否是 React 相关模块的子路径
72
+ for (const reactModule of reactModules) {
73
+ if (id === reactModule || id.startsWith(`${reactModule}/`)) {
74
+ return true;
75
+ }
76
+ }
77
+ // 检查其他外部依赖的子路径
78
+ for (const externalModule of Object.keys(externals)) {
79
+ if (id.startsWith(`${externalModule}/`)) {
80
+ return true;
81
+ }
82
+ }
65
83
  return false;
66
84
  };
67
85
  const defaultBlockExternals = {
68
- // 核心 React 相关
86
+ // 核心 React 相关 - 确保完全外部化
69
87
  react: '@blocklet/pages-kit/builtin/react',
70
88
  'react-dom': '@blocklet/pages-kit/builtin/react-dom',
89
+ 'react-dom/client': '@blocklet/pages-kit/builtin/react-dom',
90
+ 'react/jsx-runtime': '@blocklet/pages-kit/builtin/react',
91
+ 'react/jsx-dev-runtime': '@blocklet/pages-kit/builtin/react',
71
92
  'react-router-dom': '@blocklet/pages-kit/builtin/react-router-dom',
72
93
  'react-hook-form': '@blocklet/pages-kit/builtin/react-hook-form',
73
94
  'react-wrap-balancer': '@blocklet/pages-kit/builtin/react-wrap-balancer',
@@ -139,14 +160,6 @@ function initBlockStudioPlugins(options) {
139
160
  externalMappings = options.blockExternals;
140
161
  }
141
162
  (0, helper_1.setBlockEntryFilesPattern)(entryFilesPattern);
142
- helper_1.logger.log('initBlockStudioPlugins options: ', {
143
- cwd: workingDir,
144
- watchFilesDir,
145
- entryFilesPattern: (0, helper_1.getBlockEntryFilesPattern)(),
146
- pagesDir,
147
- blockExternals: externalMappings, // 添加日志输出
148
- transpileBuiltinModule,
149
- });
150
163
  // 为 globals 创建一个无前缀的版本
151
164
  const pathMappings = Object.fromEntries(Object.entries(externalMappings).filter(([, value]) => !value.startsWith('window.') && value.length > 0));
152
165
  const externalGlobalMappings = Object.fromEntries(Object.entries(externalMappings).filter(([, value]) => value.startsWith('window.') && value.length > 0));
@@ -155,12 +168,32 @@ function initBlockStudioPlugins(options) {
155
168
  if (!value?.length) {
156
169
  return [];
157
170
  }
171
+ // 特殊处理 React 相关模块
172
+ const reactGlobals = {
173
+ react: 'React',
174
+ 'react-dom': 'ReactDOM',
175
+ 'react/jsx-runtime': 'React',
176
+ 'react/jsx-dev-runtime': 'React',
177
+ 'react-dom/client': 'ReactDOM',
178
+ };
179
+ if (reactGlobals[key]) {
180
+ return [key, reactGlobals[key]];
181
+ }
158
182
  // 移除 "window." 前缀并转换为首字母大写的驼峰式
159
183
  const rawName = String(key);
160
184
  const globalName = (0, upperFirst_1.default)((0, camelCase_1.default)(rawName));
161
185
  return [key, globalName];
162
186
  })
163
187
  .filter((item) => item.length > 0));
188
+ helper_1.logger.log('initBlockStudioPlugins options: ', {
189
+ cwd: workingDir,
190
+ watchFilesDir,
191
+ entryFilesPattern: (0, helper_1.getBlockEntryFilesPattern)(),
192
+ pagesDir,
193
+ blockExternals: externalMappings,
194
+ globalsMappings,
195
+ transpileBuiltinModule,
196
+ });
164
197
  const filterModules = process.argv.includes('--filter')
165
198
  ? process.argv[process.argv.indexOf('--filter') + 1]?.split(',')
166
199
  : null;
@@ -239,10 +272,14 @@ function initBlockStudioPlugins(options) {
239
272
  ..._config?.build?.rollupOptions,
240
273
  external: _config?.build?.rollupOptions?.external ||
241
274
  ((id) => {
242
- // 是否匹配后缀
243
- const isMatchAfterSlash = isMatchAfterSlachExternals(id);
275
+ // 使用改进的外部依赖检查
276
+ const isExternal = isMatchAfterSlachExternals(id, externalMappings);
277
+ if (isExternal) {
278
+ return true;
279
+ }
280
+ // 兼容原有逻辑
244
281
  const skipList = [...Object.keys(externalMappings)];
245
- if (skipList.some((item) => (isMatchAfterSlash && id.startsWith(`${item}/`)) || id === item)) {
282
+ if (skipList.some((item) => id === item)) {
246
283
  return true;
247
284
  }
248
285
  return false;