@4399ywkf/cli 2.0.4 → 2.0.6

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/index.js CHANGED
@@ -334,6 +334,9 @@ Git\u6A21\u677F: ${gitTemplate}
334
334
  };
335
335
  if (!useExternalTemplate) {
336
336
  await injectInternalTemplateFiles();
337
+ if (microRole !== "none" /* none */) {
338
+ await injectMicroFrontendPages(target, microRole);
339
+ }
337
340
  }
338
341
  const context = {
339
342
  target,
@@ -452,5 +455,392 @@ async function getPnpmVersion() {
452
455
  throw new Error("Please install pnpm first", { cause: e });
453
456
  }
454
457
  }
458
+ async function injectMicroFrontendPages(target, role, appName) {
459
+ const pagesDir = path.join(target, "src/pages");
460
+ if (role === "master" /* master */) {
461
+ await injectMasterAppPages(pagesDir);
462
+ } else if (role === "sub" /* sub */) {
463
+ await injectSubAppPages(pagesDir);
464
+ }
465
+ }
466
+ async function writeFile(filePath, content) {
467
+ await utils.fsExtra.ensureDir(path.dirname(filePath));
468
+ await utils.fsExtra.writeFile(filePath, content, "utf-8");
469
+ }
470
+ async function injectMasterAppPages(pagesDir, appName) {
471
+ await writeFile(
472
+ path.join(pagesDir, "layout.tsx"),
473
+ MASTER_LAYOUT
474
+ );
475
+ await writeFile(
476
+ path.join(pagesDir, "micro/page.tsx"),
477
+ MASTER_MICRO_PAGE
478
+ );
479
+ await writeFile(
480
+ path.join(pagesDir, "micro/layout.tsx"),
481
+ MASTER_MICRO_LAYOUT
482
+ );
483
+ await writeFile(
484
+ path.join(pagesDir, "micro/$.tsx"),
485
+ MASTER_MICRO_CATCHALL
486
+ );
487
+ await writeFile(
488
+ path.join(pagesDir, "page.tsx"),
489
+ MASTER_HOME_PAGE
490
+ );
491
+ }
492
+ async function injectSubAppPages(pagesDir, appName) {
493
+ await writeFile(
494
+ path.join(pagesDir, "layout.tsx"),
495
+ SUB_LAYOUT
496
+ );
497
+ await writeFile(
498
+ path.join(pagesDir, "page.tsx"),
499
+ SUB_HOME_PAGE
500
+ );
501
+ }
502
+ const MASTER_LAYOUT = `import { Outlet, Link, useLocation } from "react-router";
503
+ import { Layout, Menu } from "antd";
504
+
505
+ const { Header, Content, Footer } = Layout;
506
+
507
+ const NAV_ITEMS = [
508
+ { key: "/", label: <Link to="/">\u9996\u9875</Link> },
509
+ { key: "/dashboard", label: <Link to="/dashboard">\u5DE5\u4F5C\u53F0</Link> },
510
+ { key: "/micro", label: <Link to="/micro">\u5FAE\u524D\u7AEF\u7BA1\u7406</Link> },
511
+ { key: "/user", label: <Link to="/user">\u7528\u6237\u7BA1\u7406</Link> },
512
+ ];
513
+
514
+ export default function RootLayout() {
515
+ const { pathname } = useLocation();
516
+ const activeKey =
517
+ NAV_ITEMS.find((item) => pathname.startsWith(item.key) && item.key !== "/")?.key
518
+ || (pathname === "/" ? "/" : "");
519
+
520
+ return (
521
+ <Layout style={{ minHeight: "100vh" }}>
522
+ <Header style={{ display: "flex", alignItems: "center" }}>
523
+ <div style={{ color: "#fff", fontWeight: 700, fontSize: 16, marginRight: 32 }}>
524
+ Micro Master
525
+ </div>
526
+ <Menu
527
+ theme="dark"
528
+ mode="horizontal"
529
+ selectedKeys={[activeKey]}
530
+ style={{ flex: 1 }}
531
+ items={NAV_ITEMS}
532
+ />
533
+ </Header>
534
+ <Content style={{ padding: "24px 48px" }}>
535
+ <Outlet />
536
+ </Content>
537
+ <Footer style={{ textAlign: "center" }}>
538
+ YWKF Framework \xB7 \u4E3B\u5E94\u7528\uFF08\u57FA\u5EA7\uFF09 \xA9{new Date().getFullYear()}
539
+ </Footer>
540
+ </Layout>
541
+ );
542
+ }
543
+ `;
544
+ const MASTER_HOME_PAGE = `import { Typography, Space, Card, Alert, Tag } from "antd";
545
+ import { Link } from "react-router";
546
+
547
+ const { Title, Paragraph } = Typography;
548
+
549
+ export default function HomePage() {
550
+ return (
551
+ <div style={{ maxWidth: 720, margin: "0 auto" }}>
552
+ <Title>
553
+ \u4E3B\u5E94\u7528\uFF08\u57FA\u5EA7\uFF09 <Tag color="blue">Garfish</Tag>
554
+ </Title>
555
+
556
+ <Alert
557
+ type="info"
558
+ showIcon
559
+ message="\u5FAE\u524D\u7AEF\u4E3B\u5E94\u7528\u6A21\u5F0F\u5DF2\u542F\u7528"
560
+ description="\u5F53\u524D\u9879\u76EE\u4F5C\u4E3A\u57FA\u5EA7\u5E94\u7528\uFF0C\u8D1F\u8D23\u5B50\u5E94\u7528\u7684\u6CE8\u518C\u3001\u52A0\u8F7D\u548C\u751F\u547D\u5468\u671F\u7BA1\u7406\u3002"
561
+ style={{ marginBottom: 24 }}
562
+ />
563
+
564
+ <Space direction="vertical" size="middle" style={{ width: "100%" }}>
565
+ <Card title="\u5982\u4F55\u63A5\u5165\u5B50\u5E94\u7528">
566
+ <Paragraph>
567
+ 1. \u5728 <code>ywkf.config.ts</code> \u4E2D\u7684 <code>garfishPlugin</code> \u914D\u7F6E\u5B50\u5E94\u7528\u5217\u8868\uFF1A
568
+ </Paragraph>
569
+ <pre style={{ background: "#f5f5f5", padding: 12, borderRadius: 6, fontSize: 13 }}>
570
+ {
571
+ \`garfishPlugin({
572
+ master: true,
573
+ apps: [
574
+ {
575
+ name: "sub-app",
576
+ entry: "http://localhost:3001",
577
+ activeRule: "/micro/sub-app",
578
+ },
579
+ ],
580
+ })\`
581
+ }
582
+ </pre>
583
+ <Paragraph>
584
+ 2. \u8BBF\u95EE <Link to="/micro">\u5FAE\u524D\u7AEF\u7BA1\u7406</Link> \u9875\u9762\u67E5\u770B\u5B50\u5E94\u7528\u5BB9\u5668\u3002
585
+ </Paragraph>
586
+ <Paragraph>
587
+ 3. \u5B50\u5E94\u7528\u5339\u914D <code>activeRule</code> \u540E\u4F1A\u81EA\u52A8\u6302\u8F7D\u5230\u5BB9\u5668\u4E2D\u3002
588
+ </Paragraph>
589
+ </Card>
590
+
591
+ <Card title="\u672C\u6A21\u677F\u5305\u542B\u7684\u793A\u4F8B\u8DEF\u7531">
592
+ <ul>
593
+ <li><Link to="/">/</Link> \u2014 \u9996\u9875\uFF08\u5F53\u524D\u9875\u9762\uFF09</li>
594
+ <li><Link to="/dashboard">/dashboard</Link> \u2014 \u5DE5\u4F5C\u53F0</li>
595
+ <li><Link to="/micro">/micro</Link> \u2014 \u5FAE\u524D\u7AEF\u5B50\u5E94\u7528\u5BB9\u5668</li>
596
+ <li><Link to="/user">/user</Link> \u2014 \u7528\u6237\u5217\u8868</li>
597
+ </ul>
598
+ </Card>
599
+ </Space>
600
+ </div>
601
+ );
602
+ }
603
+ `;
604
+ const MASTER_MICRO_LAYOUT = `import { Outlet } from "react-router";
605
+
606
+ export default function MicroLayout() {
607
+ return (
608
+ <div>
609
+ <Outlet />
610
+ {/* Garfish \u5B50\u5E94\u7528\u6302\u8F7D\u5BB9\u5668 */}
611
+ <div id="subapp-container" style={{ minHeight: 400 }} />
612
+ </div>
613
+ );
614
+ }
615
+ `;
616
+ const MASTER_MICRO_PAGE = `import { Typography, Card, Empty, Space, Tag, Descriptions } from "antd";
617
+
618
+ const { Title, Paragraph } = Typography;
619
+
620
+ export default function MicroPage() {
621
+ return (
622
+ <div style={{ maxWidth: 800, margin: "0 auto" }}>
623
+ <Title level={2}>
624
+ \u5FAE\u524D\u7AEF\u7BA1\u7406 <Tag color="green">Garfish</Tag>
625
+ </Title>
626
+
627
+ <Space direction="vertical" size="middle" style={{ width: "100%" }}>
628
+ <Card title="\u5B50\u5E94\u7528\u5BB9\u5668">
629
+ <Empty
630
+ description={
631
+ <Paragraph type="secondary">
632
+ \u6682\u672A\u6CE8\u518C\u5B50\u5E94\u7528\u3002\u8BF7\u5728 <code>ywkf.config.ts</code> \u4E2D\u914D\u7F6E <code>garfishPlugin</code> \u7684 apps \u5217\u8868\u3002
633
+ </Paragraph>
634
+ }
635
+ />
636
+ </Card>
637
+
638
+ <Card title="\u63A5\u5165\u8BF4\u660E">
639
+ <Descriptions bordered column={1} size="small">
640
+ <Descriptions.Item label="\u5B50\u5E94\u7528\u6CE8\u518C">
641
+ <code>garfishPlugin({'{'} master: true, apps: [...] {'}'})</code>
642
+ </Descriptions.Item>
643
+ <Descriptions.Item label="\u6302\u8F7D\u5BB9\u5668">
644
+ <code>&lt;div id="subapp-container" /&gt;</code>\uFF08\u5DF2\u5185\u7F6E\u5728\u5F53\u524D\u5E03\u5C40\u4E2D\uFF09
645
+ </Descriptions.Item>
646
+ <Descriptions.Item label="\u8DEF\u7531\u524D\u7F00">
647
+ \u5B50\u5E94\u7528 <code>activeRule</code> \u5EFA\u8BAE\u4EE5 <code>/micro/xxx</code> \u5F00\u5934
648
+ </Descriptions.Item>
649
+ <Descriptions.Item label="\u72EC\u7ACB\u8C03\u8BD5">
650
+ \u5B50\u5E94\u7528\u53EF\u5355\u72EC\u542F\u52A8\u5F00\u53D1\u670D\u52A1\u5668\u8FDB\u884C\u8C03\u8BD5\uFF0C\u53EA\u9700\u5728\u5F53\u524D\u4E3B\u5E94\u7528\u4E2D\u6CE8\u518C\u5176\u5165\u53E3\u5730\u5740\u5373\u53EF
651
+ </Descriptions.Item>
652
+ </Descriptions>
653
+ </Card>
654
+ </Space>
655
+ </div>
656
+ );
657
+ }
658
+ `;
659
+ const MASTER_MICRO_CATCHALL = `import { Typography, Spin, Alert } from "antd";
660
+ import { useLocation } from "react-router";
661
+
662
+ const { Paragraph } = Typography;
663
+
664
+ export default function MicroCatchAll() {
665
+ const { pathname } = useLocation();
666
+
667
+ return (
668
+ <div style={{ maxWidth: 720, margin: "0 auto", padding: "40px 0" }}>
669
+ <Alert
670
+ type="warning"
671
+ showIcon
672
+ message="\u5B50\u5E94\u7528\u8DEF\u7531\u533A\u57DF"
673
+ description={
674
+ <>
675
+ <Paragraph>
676
+ \u5F53\u524D\u8DEF\u5F84 <code>{pathname}</code> \u9884\u671F\u7531 Garfish \u5B50\u5E94\u7528\u63A5\u7BA1\u3002
677
+ </Paragraph>
678
+ <Paragraph type="secondary">
679
+ \u5982\u679C\u4F60\u770B\u5230\u6B64\u9875\u9762\uFF0C\u8BF4\u660E\u5BF9\u5E94\u7684\u5B50\u5E94\u7528\u5C1A\u672A\u6CE8\u518C\u6216\u672A\u542F\u52A8\u3002
680
+ \u8BF7\u68C0\u67E5 <code>ywkf.config.ts</code> \u4E2D <code>garfishPlugin</code> \u7684 apps \u914D\u7F6E\u3002
681
+ </Paragraph>
682
+ </>
683
+ }
684
+ />
685
+ <div style={{ textAlign: "center", marginTop: 24 }}>
686
+ <Spin tip="\u7B49\u5F85\u5B50\u5E94\u7528\u52A0\u8F7D..." />
687
+ </div>
688
+ </div>
689
+ );
690
+ }
691
+ `;
692
+ const SUB_LAYOUT = `import { Outlet, Link, useLocation } from "react-router";
693
+ import { Layout, Menu, Tag } from "antd";
694
+ import { useEffect, useState } from "react";
695
+
696
+ const { Header, Content, Footer } = Layout;
697
+
698
+ const NAV_ITEMS = [
699
+ { key: "/", label: <Link to="/">\u9996\u9875</Link> },
700
+ { key: "/dashboard", label: <Link to="/dashboard">\u5DE5\u4F5C\u53F0</Link> },
701
+ { key: "/user", label: <Link to="/user">\u7528\u6237\u7BA1\u7406</Link> },
702
+ ];
703
+
704
+ function useIsMicroEnv(): boolean {
705
+ const [isMicro, setIsMicro] = useState(false);
706
+
707
+ useEffect(() => {
708
+ const inGarfish = !!(window as Record<string, unknown>).__GARFISH__;
709
+ const inQiankun = !!(window as Record<string, unknown>).__POWERED_BY_QIANKUN__;
710
+ setIsMicro(inGarfish || inQiankun);
711
+ }, []);
712
+
713
+ return isMicro;
714
+ }
715
+
716
+ export default function SubAppLayout() {
717
+ const { pathname } = useLocation();
718
+ const isMicro = useIsMicroEnv();
719
+
720
+ const activeKey =
721
+ NAV_ITEMS.find((item) => pathname.startsWith(item.key) && item.key !== "/")?.key
722
+ || (pathname === "/" ? "/" : "");
723
+
724
+ if (isMicro) {
725
+ return (
726
+ <div style={{ padding: 16 }}>
727
+ <Outlet />
728
+ </div>
729
+ );
730
+ }
731
+
732
+ return (
733
+ <Layout style={{ minHeight: "100vh" }}>
734
+ <Header style={{ display: "flex", alignItems: "center" }}>
735
+ <div style={{ color: "#fff", fontWeight: 700, fontSize: 16, marginRight: 16 }}>
736
+ Sub App
737
+ </div>
738
+ <Tag color="orange" style={{ marginRight: 16 }}>\u72EC\u7ACB\u8FD0\u884C</Tag>
739
+ <Menu
740
+ theme="dark"
741
+ mode="horizontal"
742
+ selectedKeys={[activeKey]}
743
+ style={{ flex: 1 }}
744
+ items={NAV_ITEMS}
745
+ />
746
+ </Header>
747
+ <Content style={{ padding: "24px 48px" }}>
748
+ <Outlet />
749
+ </Content>
750
+ <Footer style={{ textAlign: "center" }}>
751
+ YWKF Framework \xB7 \u5B50\u5E94\u7528\uFF08\u72EC\u7ACB\u8FD0\u884C\u6A21\u5F0F\uFF09\xA9{new Date().getFullYear()}
752
+ </Footer>
753
+ </Layout>
754
+ );
755
+ }
756
+ `;
757
+ const SUB_HOME_PAGE = `import { Typography, Space, Card, Alert, Tag, Descriptions } from "antd";
758
+ import { Link } from "react-router";
759
+ import { useEffect, useState } from "react";
760
+
761
+ const { Title, Paragraph } = Typography;
762
+
763
+ function useRuntimeInfo() {
764
+ const [info, setInfo] = useState({
765
+ isMicro: false,
766
+ env: "\u72EC\u7ACB\u8FD0\u884C",
767
+ });
768
+
769
+ useEffect(() => {
770
+ const inGarfish = !!(window as Record<string, unknown>).__GARFISH__;
771
+ const inQiankun = !!(window as Record<string, unknown>).__POWERED_BY_QIANKUN__;
772
+ const isMicro = inGarfish || inQiankun;
773
+
774
+ setInfo({
775
+ isMicro,
776
+ env: inGarfish ? "Garfish" : inQiankun ? "Qiankun" : "\u72EC\u7ACB\u8FD0\u884C",
777
+ });
778
+ }, []);
779
+
780
+ return info;
781
+ }
782
+
783
+ export default function SubAppHomePage() {
784
+ const { isMicro, env } = useRuntimeInfo();
785
+
786
+ return (
787
+ <div style={{ maxWidth: 720, margin: "0 auto" }}>
788
+ <Title>
789
+ \u5B50\u5E94\u7528 <Tag color={isMicro ? "green" : "orange"}>{env}</Tag>
790
+ </Title>
791
+
792
+ <Alert
793
+ type={isMicro ? "success" : "info"}
794
+ showIcon
795
+ message={
796
+ isMicro
797
+ ? "\u5F53\u524D\u8FD0\u884C\u5728\u5FAE\u524D\u7AEF\u73AF\u5883\u4E2D\uFF08\u7531\u4E3B\u5E94\u7528\u52A0\u8F7D\uFF09"
798
+ : "\u5F53\u524D\u4E3A\u72EC\u7ACB\u8FD0\u884C\u6A21\u5F0F\uFF08\u53EF\u72EC\u7ACB\u5F00\u53D1\u8C03\u8BD5\uFF09"
799
+ }
800
+ style={{ marginBottom: 24 }}
801
+ />
802
+
803
+ <Space direction="vertical" size="middle" style={{ width: "100%" }}>
804
+ <Card title="\u8FD0\u884C\u73AF\u5883\u4FE1\u606F">
805
+ <Descriptions bordered column={1} size="small">
806
+ <Descriptions.Item label="\u8FD0\u884C\u6A21\u5F0F">
807
+ <Tag color={isMicro ? "green" : "orange"}>{env}</Tag>
808
+ </Descriptions.Item>
809
+ <Descriptions.Item label="window.__GARFISH__">
810
+ <code>{String(!!(window as Record<string, unknown>).__GARFISH__)}</code>
811
+ </Descriptions.Item>
812
+ <Descriptions.Item label="\u5F53\u524D URL">
813
+ <code>{typeof location !== "undefined" ? location.href : "-"}</code>
814
+ </Descriptions.Item>
815
+ </Descriptions>
816
+ </Card>
817
+
818
+ <Card title="\u5B50\u5E94\u7528\u5F00\u53D1\u6307\u5357">
819
+ <Paragraph>
820
+ \u6B64\u9879\u76EE\u5DF2\u914D\u7F6E\u4E3A Garfish \u5FAE\u524D\u7AEF\u5B50\u5E94\u7528\uFF0C\u652F\u6301<strong>\u72EC\u7ACB\u8FD0\u884C</strong>\u4E0E<strong>\u5D4C\u5165\u4E3B\u5E94\u7528</strong>\u4E24\u79CD\u6A21\u5F0F\u3002
821
+ </Paragraph>
822
+ <ul>
823
+ <li>\u72EC\u7ACB\u8FD0\u884C\uFF1A\u76F4\u63A5 <code>pnpm dev</code>\uFF0C\u5B8C\u6574\u529F\u80FD\u53EF\u7528\u3002</li>
824
+ <li>
825
+ \u5D4C\u5165\u4E3B\u5E94\u7528\uFF1A\u4E3B\u5E94\u7528\u5728 <code>garfishPlugin</code> \u4E2D\u6CE8\u518C\u672C\u5E94\u7528\u5165\u53E3\u5373\u53EF\u81EA\u52A8\u52A0\u8F7D\u3002
826
+ </li>
827
+ <li>
828
+ \u6784\u5EFA\u4EA7\u7269\u81EA\u52A8\u8F93\u51FA\u4E3A UMD \u683C\u5F0F\uFF08\u7531\u6846\u67B6 garfishPlugin \u5904\u7406\uFF09\uFF0C\u65E0\u9700\u624B\u52A8\u914D\u7F6E\u3002
829
+ </li>
830
+ </ul>
831
+ </Card>
832
+
833
+ <Card title="\u672C\u6A21\u677F\u5305\u542B\u7684\u793A\u4F8B\u8DEF\u7531">
834
+ <ul>
835
+ <li><Link to="/">/</Link> \u2014 \u9996\u9875\uFF08\u5F53\u524D\u9875\u9762\uFF09</li>
836
+ <li><Link to="/dashboard">/dashboard</Link> \u2014 \u5DE5\u4F5C\u53F0</li>
837
+ <li><Link to="/user">/user</Link> \u2014 \u7528\u6237\u5217\u8868</li>
838
+ </ul>
839
+ </Card>
840
+ </Space>
841
+ </div>
842
+ );
843
+ }
844
+ `;
455
845
 
456
846
  module.exports = index;
@@ -19,7 +19,7 @@
19
19
  "antd": "^6.1.1",
20
20
  "axios": "^1.9.0",
21
21
  {{#enableMicro}}
22
- "garfish": "^1.22.3",
22
+ "garfish": "^1.19.8",
23
23
  {{/enableMicro}}
24
24
  "react": "^19.1.0",
25
25
  "react-dom": "^19.1.0",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@4399ywkf/cli",
3
- "version": "2.0.4",
3
+ "version": "2.0.6",
4
4
  "description": "运维开发部脚手架",
5
5
  "main": "dist/index.js",
6
6
  "bin": {