From 27d1d4f56184bcb0fe32199d3568b3d989618e45 Mon Sep 17 00:00:00 2001 From: alchaincyf <127714341+alchaincyf@users.noreply.github.com> Date: Sat, 28 Dec 2024 15:52:34 +0800 Subject: [PATCH 1/4] Create nextjs.yml --- .github/workflows/nextjs.yml | 93 ++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 .github/workflows/nextjs.yml diff --git a/.github/workflows/nextjs.yml b/.github/workflows/nextjs.yml new file mode 100644 index 0000000..ed74736 --- /dev/null +++ b/.github/workflows/nextjs.yml @@ -0,0 +1,93 @@ +# Sample workflow for building and deploying a Next.js site to GitHub Pages +# +# To get started with Next.js see: https://nextjs.org/docs/getting-started +# +name: Deploy Next.js site to Pages + +on: + # Runs on pushes targeting the default branch + push: + branches: ["main"] + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages +permissions: + contents: read + pages: write + id-token: write + +# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. +# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. +concurrency: + group: "pages" + cancel-in-progress: false + +jobs: + # Build job + build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Detect package manager + id: detect-package-manager + run: | + if [ -f "${{ github.workspace }}/yarn.lock" ]; then + echo "manager=yarn" >> $GITHUB_OUTPUT + echo "command=install" >> $GITHUB_OUTPUT + echo "runner=yarn" >> $GITHUB_OUTPUT + exit 0 + elif [ -f "${{ github.workspace }}/package.json" ]; then + echo "manager=npm" >> $GITHUB_OUTPUT + echo "command=ci" >> $GITHUB_OUTPUT + echo "runner=npx --no-install" >> $GITHUB_OUTPUT + exit 0 + else + echo "Unable to determine package manager" + exit 1 + fi + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: "20" + cache: ${{ steps.detect-package-manager.outputs.manager }} + - name: Setup Pages + uses: actions/configure-pages@v5 + with: + # Automatically inject basePath in your Next.js configuration file and disable + # server side image optimization (https://nextjs.org/docs/api-reference/next/image#unoptimized). + # + # You may remove this line if you want to manage the configuration yourself. + static_site_generator: next + - name: Restore cache + uses: actions/cache@v4 + with: + path: | + .next/cache + # Generate a new cache whenever packages or source files change. + key: ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json', '**/yarn.lock') }}-${{ hashFiles('**.[jt]s', '**.[jt]sx') }} + # If source files changed but packages didn't, rebuild from a prior cache. + restore-keys: | + ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json', '**/yarn.lock') }}- + - name: Install dependencies + run: ${{ steps.detect-package-manager.outputs.manager }} ${{ steps.detect-package-manager.outputs.command }} + - name: Build with Next.js + run: ${{ steps.detect-package-manager.outputs.runner }} next build + - name: Upload artifact + uses: actions/upload-pages-artifact@v3 + with: + path: ./out + + # Deployment job + deploy: + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + runs-on: ubuntu-latest + needs: build + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 From bad35e4dee72122f02c5633abfd7aff98ea2ad58 Mon Sep 17 00:00:00 2001 From: alchain Date: Tue, 21 Jan 2025 11:10:21 +0700 Subject: [PATCH 2/4] Update ClientSideTutorialTree.tsx --- app/[language]/ClientSideTutorialTree.tsx | 36 +++++++++++++++++------ 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/app/[language]/ClientSideTutorialTree.tsx b/app/[language]/ClientSideTutorialTree.tsx index de8efab..19a5eab 100644 --- a/app/[language]/ClientSideTutorialTree.tsx +++ b/app/[language]/ClientSideTutorialTree.tsx @@ -29,21 +29,39 @@ function TutorialTreeItem({ item, language, currentPath }: { item: TutorialItem, const encodedPath = encodeURIComponent(item.path).replace(/%2F/g, '%2F'); const isActive = currentPath === `/${language}/${encodedPath}`; + // 如果是目录(有子项目) + if (item.items && item.items.length > 0) { + return ( +
+
setIsOpen(!isOpen)} + > + + {isOpen ? '▼' : '▶'} + + + {item.title} + +
+ {isOpen && ( + + )} +
+ ); + } + + // 如果是具体文章(没有子项目) return (
- {item.items && ( - - )} - + {item.title}
- {isOpen && item.items && ( - - )}
); } From ed4ebd87686543e75bc6353b796e1ab2bf32a9af Mon Sep 17 00:00:00 2001 From: alchain Date: Mon, 22 Sep 2025 20:50:59 +0800 Subject: [PATCH 3/4] Update 001_Bootstrap.md --- .../001_Bootstrap.md" | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git "a/tutorials/Bootstrap/01. \345\237\272\347\241\200\345\205\245\351\227\250/001_Bootstrap.md" "b/tutorials/Bootstrap/01. \345\237\272\347\241\200\345\205\245\351\227\250/001_Bootstrap.md" index 3ed78e9..90d1982 100644 --- "a/tutorials/Bootstrap/01. \345\237\272\347\241\200\345\205\245\351\227\250/001_Bootstrap.md" +++ "b/tutorials/Bootstrap/01. \345\237\272\347\241\200\345\205\245\351\227\250/001_Bootstrap.md" @@ -18,7 +18,7 @@ keywords: ## 概述 -Bootstrap 是一个流行的前端框架,由 Twitter 的两位工程师 Mark Otto 和 Jacob Thornton 在 2011 年创建。它旨在简化响应式网页设计和开发过程,使开发者能够快速构建美观且功能丰富的网站。Bootstrap 提供了丰富的 CSS 和 JavaScript 组件,以及一套强大的网格系统,帮助开发者轻松实现跨设备的响应式设计。 +Bootstrap 是一个流行的前端框架,由 Twitter 的两位工程师 Mark Otto 和 Jacob Thornton 在 2011 年创建。它旨在简化响应式网页设计和开发过程,使开发者能够快速构建美观且功能丰富的网站。Bootstrap 提供了丰富的 CSS 和 JavaScript 组件,以及一套强大的网格系统,帮助开发者轻松实现跨设备的响应式设计. ## 历史背景 @@ -43,7 +43,7 @@ Bootstrap 提供了大量的预构建组件,如导航栏、按钮、表单、 Bootstrap 确保了跨浏览器和设备的一致性,减少了兼容性问题。 ### 4. 社区支持 -Bootstrap 拥有庞大的开发者社区,提供了丰富的文档、教程和插件。 +Bootstrap拥有庞大的开发者社区,提供了丰富的文档、教程和插件。 ## 安装和引入 Bootstrap From e39dacee024c9d0fcaaae2bca04948c28059de68 Mon Sep 17 00:00:00 2001 From: alchain Date: Mon, 22 Sep 2025 21:36:33 +0800 Subject: [PATCH 4/4] =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- _headers | 29 ++++++++++++++++++++++++++ edgeone.config.js | 53 +++++++++++++++++++++++++++++++++++++++++++++++ next.config.js | 30 +++++++++++++++++++++++++++ 3 files changed, 112 insertions(+) create mode 100644 _headers create mode 100644 edgeone.config.js diff --git a/_headers b/_headers new file mode 100644 index 0000000..73b478b --- /dev/null +++ b/_headers @@ -0,0 +1,29 @@ +/* + X-Frame-Options: DENY + X-Content-Type-Options: nosniff + Referrer-Policy: strict-origin-when-cross-origin + +/_next/static/* + Cache-Control: public, max-age=31536000, immutable + Content-Type: application/javascript; charset=utf-8 + +/*.css + Content-Type: text/css; charset=utf-8 + Cache-Control: public, max-age=31536000, immutable + +/*.woff + Content-Type: font/woff + Cache-Control: public, max-age=31536000, immutable + +/*.woff2 + Content-Type: font/woff2 + Cache-Control: public, max-age=31536000, immutable + +/*.js + Content-Type: application/javascript; charset=utf-8 + Cache-Control: public, max-age=31536000, immutable + +/api/* + Access-Control-Allow-Origin: * + Access-Control-Allow-Methods: GET,OPTIONS,PATCH,DELETE,POST,PUT + Access-Control-Allow-Headers: X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version \ No newline at end of file diff --git a/edgeone.config.js b/edgeone.config.js new file mode 100644 index 0000000..54dac09 --- /dev/null +++ b/edgeone.config.js @@ -0,0 +1,53 @@ +module.exports = { + build: { + command: 'npm run build', + outputDirectory: '.next', + }, + runtime: 'nodejs18.x', + headers: [ + { + source: '/_next/static/(.*)', + headers: [ + { + key: 'Cache-Control', + value: 'public, max-age=31536000, immutable' + }, + { + key: 'Content-Type', + value: 'application/javascript; charset=utf-8' + } + ] + }, + { + source: '/(.*).css', + headers: [ + { + key: 'Content-Type', + value: 'text/css; charset=utf-8' + } + ] + }, + { + source: '/(.*).woff', + headers: [ + { + key: 'Content-Type', + value: 'font/woff' + } + ] + }, + { + source: '/(.*).woff2', + headers: [ + { + key: 'Content-Type', + value: 'font/woff2' + } + ] + } + ], + env: { + DEEPSEEK_API_KEY: process.env.DEEPSEEK_API_KEY, + NEXT_PUBLIC_GA_MEASUREMENT_ID: process.env.NEXT_PUBLIC_GA_MEASUREMENT_ID, + } +}; \ No newline at end of file diff --git a/next.config.js b/next.config.js index 69d4b2a..ab721b7 100644 --- a/next.config.js +++ b/next.config.js @@ -4,6 +4,10 @@ const nextConfig = { DEEPSEEK_API_KEY: process.env.DEEPSEEK_API_KEY, NEXT_PUBLIC_GA_MEASUREMENT_ID: process.env.NEXT_PUBLIC_GA_MEASUREMENT_ID, }, + compress: false, + generateEtags: false, + poweredByHeader: false, + assetPrefix: '', async headers() { return [ { @@ -14,10 +18,36 @@ const nextConfig = { { key: 'Access-Control-Allow-Headers', value: 'X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version' }, ], }, + { + source: '/_next/static/:path*', + headers: [ + { key: 'Cache-Control', value: 'public, max-age=31536000, immutable' }, + { key: 'Content-Type', value: 'application/javascript; charset=utf-8' }, + ], + }, + { + source: '/:path*.css', + headers: [ + { key: 'Content-Type', value: 'text/css; charset=utf-8' }, + ], + }, + { + source: '/:path*.woff', + headers: [ + { key: 'Content-Type', value: 'font/woff' }, + ], + }, + { + source: '/:path*.woff2', + headers: [ + { key: 'Content-Type', value: 'font/woff2' }, + ], + }, ]; }, images: { domains: ['www.codewithai.com'], // 添加你的图片域名 + unoptimized: true, }, };