{"id":629,"date":"2020-03-10T17:27:01","date_gmt":"2020-03-10T17:27:01","guid":{"rendered":"https:\/\/www.haoyuan.info\/?p=629"},"modified":"2020-03-10T17:27:01","modified_gmt":"2020-03-10T17:27:01","slug":"%e4%bd%bf%e7%94%a8github-actions%e8%87%aa%e5%8a%a8%e7%bc%96%e8%af%91%e3%80%81%e6%89%93%e5%8c%85%e3%80%81%e5%8f%91%e5%b8%83vue%e9%a1%b9%e7%9b%ae%ef%bc%8c%e5%b9%b6%e4%bd%bf%e7%94%a8jsdelivr%e4%bd%9c","status":"publish","type":"post","link":"https:\/\/haoyuan.info\/?p=629","title":{"rendered":"\u4f7f\u7528Github Actions\u81ea\u52a8\u7f16\u8bd1\u3001\u6253\u5305\u3001\u53d1\u5e03Vue\u9879\u76ee\uff0c\u5e76\u4f7f\u7528JSDelivr\u4f5c\u4e3aCDN\u52a0\u901f"},"content":{"rendered":"<p>\u53bb\u5e745\u6708CUPOJ\u524d\u7aef\u4f7f\u7528Vue\u8fdb\u884c\u4e86\u91cd\u6784\uff0c\u56e0\u6b64\u4f7f\u7528Vue-CLI\u6253\u5305\u53d8\u6210\u4e86\u6bcf\u6b21\u53d1\u5e03\u65b0\u7684\u53d8\u66f4\u5fc5\u4e0d\u53ef\u5c11\u7684\u4e00\u4e2a\u4efb\u52a1\u3002<\/p>\n<p>\u7531\u4e8e\u524d\u7aef\u9879\u76ee\u672c\u8eab\u4ee3\u7801\u91cf\u8f83\u5927\uff0c\u903b\u8f91\u4e5f\u6bd4\u8f83\u590d\u6742\uff0c\u6253\u5305\u8d77\u6765\u5bf9\u6027\u80fd\u8981\u6c42\u76f8\u5bf9\u8f83\u9ad8\u3002\u5e73\u65f6\u90fd\u662f\u5728\u5b66\u6821\u670d\u52a1\u5668\u76f4\u63a5\u6253\u5305\u540e\u590d\u5236<code>dist<\/code>\u76ee\u5f55\u4e0b\u7684\u6587\u4ef6\u5230\u6307\u5b9a\u6587\u4ef6\u5939\u6765\u90e8\u7f72\u3002<\/p>\n<p>\u6bcf\u6b21\u90fd\u6267\u884c\u540c\u6837\u7684\u4ee3\u7801\u6bd4\u8f83\u75db\u82e6\uff0c\u4fbf\u5199\u4e86\u4e00\u4e2a\u7b80\u5355\u7684\u811a\u672c\uff0c\u628a\u6574\u4e2a\u8fc7\u7a0b\u53d8\u6210\u4e86\u4e00\u952e\u90e8\u7f72\u3002\u82e5\u662f\u80fd\u591f\u628a\u6574\u4e2a\u8fc7\u7a0bCI\u5316\uff0c\u4f1a\u5927\u5927\u63d0\u5347\u5e73\u65f6\u53d1\u5e03\u7684\u6548\u7387\u3002<\/p>\n<p>\u4e8e\u662f\u5b66\u4e60\u4e86Lucien\u7684Github Actions\u4ee5\u53ca\u90e8\u7f72CDN\u7684\u65b9\u5f0f\uff0c\u8fdb\u884c\u4e86\u4e00\u4e0b\u6539\u9020\u3002<\/p>\n<h2>\u76ee\u6807<\/h2>\n<ul>\n<li>\u4f7f\u7528CI\u81ea\u52a8\u7f16\u8bd1\u5e76\u53d1\u5e03Release\u7248\u672c<\/li>\n<li>\u81ea\u52a8\u90e8\u7f72\u4ee3\u7801\u5230\u751f\u4ea7\u73af\u5883<\/li>\n<li>CDN\u52a0\u901f\u9759\u6001\u8d44\u6e90<\/li>\n<\/ul>\n<h2>\u6784\u5efaGithub Actions\u5de5\u4f5c\u6d41<\/h2>\n<p>\u6839\u636e\u7ed9\u51fa\u7684\u6587\u6863\uff0cGithub Actions\u4f1a\u81ea\u52a8\u626b\u63cfrepo\u4e0b<code>.github\/workflows<\/code>\u76ee\u5f55\u4e0b\u7684<code>*.yml<\/code>\u6587\u4ef6\uff0c\u8f7d\u5165Actions workflow\u4e2d\u3002<\/p>\n<p>\u7531\u4e8e\u8bb8\u591a\u7684\u6d41\u7a0b\u662f\u5171\u901a\u7684\uff0c\u56e0\u6b64\u5b98\u65b9\u628a\u8fd9\u4e9b\u5171\u901a\u7684\u6d41\u7a0b\u53d1\u5e03\u6210\u4e3a\u4e00\u4e2a\u6a21\u5757\uff0c\u79f0\u4f5c<code>action<\/code>\u3002\u6bcf\u4e2a\u7528\u6237\u90fd\u53ef\u4ee5\u4f7f\u7528\u522b\u4eba\u53d1\u5e03\u7684<code>action<\/code>,\u4e5f\u53ef\u4ee5\u81ea\u5df1\u53d1\u5e03<code>action<\/code>\u3002\u8fd9\u4e00\u70b9\u6211\u4e0d\u5728\u8fd9\u91cc\u5c55\u5f00\uff0c\u8fd9\u91cc\u91cd\u70b9\u5c06\u5982\u4f55\u5229\u7528\u5b83\u4eec\u8fdb\u884c\u53d1\u5e03\u3002<\/p>\n<p>\u53c2\u8003\u5b98\u65b9\u6587\u6863\u7ed9\u51fa\u7684\u8bed\u6cd5\uff0c\u6211\u4eec\u603b\u7ed3\u51fa\u4e00\u4e2a\u5927\u81f4\u7684yml\u683c\u5f0f\u3002<\/p>\n<p>\u5bf9\u4e8e\u4e00\u4e2a<code>workflow<\/code>,\u6211\u4eec\u8981\u5148\u5bf9\u5b83\u547d\u540d:<\/p>\n<pre><code class=\"language-yml \">name: Publish releases to CDN repository\n<\/code><\/pre>\n<p>\u7ed9\u51fa<code>workflow<\/code>\u7684\u89e6\u53d1\u6761\u4ef6:<\/p>\n<pre><code class=\"language-yml \">on:\n  push:\n    branches:\n      - typescript\n    paths:\n      - 'package.json'\n      - 'src\/**'\n      - 'public\/**'\n<\/code><\/pre>\n<p>\u9700\u8981\u5b8c\u6210\u7684\u5de5\u4f5c:<br \/>\n\u5176\u4e2d<code>publish<\/code>\u662f<code>jobs<\/code>\u7684\u540d\u79f0\uff0c\u4f60\u53ef\u4ee5\u968f\u610f\u547d\u540d\u3002\u4e00\u4e2a<code>jobs<\/code>\u53ef\u4ee5\u6709\u591a\u4e2a\u6267\u884c\u7684<code>job<\/code>\u3002<br \/>\n\u82e5<code>job<\/code>\u5b58\u5728<code>if<\/code>\u8bed\u53e5\uff0c\u5219\u6761\u4ef6\u6210\u7acb\u65f6\u6267\u884c<code>job<\/code>\u3002<br \/>\n<code>if<\/code>\u8bed\u53e5\u7684\u903b\u8f91\u8bf7\u53c2\u8003\u5b98\u65b9\u6587\u6863\u3002<\/p>\n<p><code>step<\/code>\u662f<code>workflow<\/code>\u6267\u884c\u7684\u6b65\u9aa4\u3002 \u6309\u7f16\u5199\u987a\u5e8f\u6267\u884c\u3002<\/p>\n<p>\u8fd9\u91cc\u7b80\u5355\u4ecb\u7ecd\u4e00\u4e0b<code>step<\/code>\u5305\u542b\u7684\u5185\u5bb9:<br \/>\n\u4e00\u4e2a<code>step<\/code>\u53ef\u4ee5\u662f\u5f15\u7528\u522b\u4eba\u7684<code>action<\/code>,\u5982\u4e0b\u9762\u7684<code>Checkout code<\/code>\u3002<br \/>\n\u6839\u636e<code>action<\/code>\u8981\u6c42\u586b\u5165\u7684<code>with<\/code>\u5c5e\u6027\uff0c\u8f93\u5165\u9700\u8981\u586b\u5199\u7684\u5185\u5bb9\u3002<\/p>\n<p>\u5bf9\u4e8e\u6bcf\u4e2a<code>step<\/code>\uff0c\u7ed9\u51fa\u5bf9\u5e94\u7684<code>name<\/code>\u4e3a\u8be5\u64cd\u4f5c\u547d\u540d\u3002<\/p>\n<p>\u53ef\u4ee5\u7528<code>if<\/code>\u6761\u4ef6\u8bed\u53e5\u51b3\u5b9a<code>step<\/code>\u662f\u5426\u6267\u884c\u3002<br \/>\n\u8be5\u8bed\u53e5\u76f8\u5173\u8bed\u6cd5\u8bf7\u53c2\u8003\u5b98\u65b9\u6587\u6863\u3002<\/p>\n<p><code>run<\/code>\u8bed\u6cd5\u53ef\u4ee5\u6267\u884c\u4e00\u81f3\u591a\u884c\u547d\u4ee4\u3002<\/p>\n<pre><code class=\"language-yml \">run: # \u5355\u884c\u547d\u4ee4\n<\/code><\/pre>\n<pre><code class=\"language-yml \">run: |\n    # \u591a\n    # \u884c\n    # \u547d\n    # \u4ee4\n<\/code><\/pre>\n<p><code>env<\/code>: \u4e3a\u6bcf\u4e2a<code>step<\/code>\u52a0\u5165\u73af\u5883\u53d8\u91cf\u3002<\/p>\n<p>\u7531\u4e8e\u6211\u4eec\u9700\u8981\u81ea\u52a8\u7f16\u8bd1\u5e76\u53d1\u5e03\uff0c\u56e0\u6b64\u6211\u9700\u8981\u5efa\u7acb\u4e00\u4e2a\u63d0\u4f9bNode.js\u7684\u53d1\u5e03\u73af\u5883\uff0c\u5e76\u4ecerepo\u62c9\u53d6\u4ee3\u7801\uff0c\u5b89\u88c5\u4f9d\u8d56\u5e76\u7f16\u8bd1\u540e\uff0c\u53d1\u5e03\u5230\u76ee\u6807\u7684\u4ed3\u5e93\u3002<\/p>\n<p>\u4e3a\u4e86\u80fd\u591f\u53d1\u5e03\u5230\u76ee\u6807\u7684\u4ed3\u5e93\uff0c\u6211\u4eec\u9700\u8981\u751f\u6210token\uff0c\u7528\u4e8epush\u64cd\u4f5c\u9a8c\u8bc1\u8eab\u4efd\u3002<\/p>\n<blockquote><p>\n  \u524d\u5f80<a class=\"wp-editor-md-post-content-link\" href=\"https:\/\/github.com\/settings\/tokens\">https:\/\/github.com\/settings\/tokens<\/a>\u53ef\u751f\u6210token\u3002\n<\/p><\/blockquote>\n<p>\u7531\u4e8etoken\u9700\u8981\u88ab\u4fdd\u5bc6\uff0c\u6211\u4eec\u5728Github\u4e2d\u4f60\u9700\u8981\u6267\u884cAction\u7684\u4ed3\u5e93\u70b9\u51fb<code>Settings<\/code>,\u5728\u5de6\u8fb9\u7684\u83dc\u5355\u627e\u5230<code>Secrets<\/code>\u586b\u5165\u4f60\u521a\u624d\u751f\u6210\u7684token, \u547d\u540d\u4e3a<code>GITHUB_ACTIONS_TOKEN<\/code>\u3002\u4f60\u4e5f\u53ef\u4ee5\u547d\u540d\u4e3a\u5176\u4ed6\u7684\u53d8\u91cf\u540d\u3002\u540e\u9762\u4f1a\u5728\u6587\u4ef6\u4e2d\u4f7f\u7528\u3002<\/p>\n<p>\u51c6\u5907\u5de5\u4f5c\u5c31\u7eea\u4ee5\u540e\uff0c\u5728<code>.github\/workflows<\/code>\u76ee\u5f55\u521b\u5efa\u4e00\u4e2ayml\u6587\u4ef6\uff0c\u7f16\u5199action<\/p>\n<pre><code class=\"language-yml \">name: Publish releases to CDN repository\n\non:\n  push:\n    branches:\n      - typescript\n    paths:\n      - 'package.json'\n      - 'src\/**'\n      - 'public\/**'\n\njobs:\n  publish:\n    if: github.repository == 'ryanlee2014\/CUP-Online-Judge-NG-FrontEnd'\n    runs-on: ubuntu-latest\n\n    strategy:\n      matrix:\n        node-version: [12.x]\n\n    steps:\n      - uses: actions\/checkout@v2\n        name: Checkout code\n        with:\n          persist-credentials: false # otherwise, the token used is the GITHUB_TOKEN, instead of your personal token\n          fetch-depth: 0 # otherwise, you will failed to push refs to dest repo\n\n      - name: Build env\n        run: |\n          echo \"::set-env name=NEED_BUILD::$(cat NEED_BUILD)\"\n\n      - name: Use Node.js environment\n        if: env.NEED_BUILD == 'true'\n        uses: actions\/setup-node@v1\n        with:\n          node-version: ${{ matrix.node-version }}\n\n      - name: Build distribution if needed\n        if: env.NEED_BUILD == 'true'\n        run: |\n          npm i\n          npm run modern\n\n      - name: Update dist folder to current repository\n        if: env.NEED_BUILD == 'true'\n        run: |\n          git config --local user.email \"gxlhybh@gmail.com\"\n          git config --local user.name \"Ryan Lee\"\n          git add dist\n          git commit -m \"Auto commit version $(cat public\/VERSION)\"\n          git push -f https:\/\/ryanlee2014:$GITHUB_TOKEN@github.com\/ryanlee2014\/CUP-Online-Judge-NG-FrontEnd.git typescript\n        env:\n          GITHUB_TOKEN: ${{ secrets.GITHUB_ACTIONS_TOKEN }}\n\n\n      - uses: actions\/checkout@v2\n        name: Checkout CDN Repository\n        with:\n          repository: ryanlee2014\/CUP-Online-Judge-CDN\n          path: cdn\n          persist-credentials: false # otherwise, the token used is the GITHUB_TOKEN, instead of your personal token\n          fetch-depth: 0 # otherwise, you will failed to push refs to dest repo\n\n      - name: Move file to another repository\n        run: cp -r dist\/* cdn\/\n\n\n      - name: Commit files and push\n        run: |\n          cd cdn\n          git config --local user.email \"gxlhybh@gmail.com\"\n          git config --local user.name \"Ryan Lee\"\n          git add --all\n          git commit -m \"deploy `TZ=UTC-8 date +'%Y-%m-%d %H:%M:%S'`\"\n          git tag \"v`cat VERSION`\"\n          git push -f https:\/\/ryanlee2014:$GITHUB_TOKEN@github.com\/ryanlee2014\/CUP-Online-Judge-CDN.git master\n          git push --tags https:\/\/ryanlee2014:$GITHUB_TOKEN@github.com\/ryanlee2014\/CUP-Online-Judge-CDN.git\n        env:\n          GITHUB_TOKEN: ${{ secrets.GITHUB_ACTIONS_TOKEN }}\n<\/code><\/pre>\n<p>\u8fd9\u4e2a\u8fc7\u7a0b\u7684\u5173\u952e\u5728\u4e8e\u6700\u540e\u7684<code>Commit files and push<\/code>\u3002\u521a\u624d\u6211\u4eec\u751f\u6210\u4e86token, \u5e76\u547d\u540d\u4e3a<code>GITHUB_ACTIONS_TOKEN<\/code>\u3002\u8fd9\u91cc\u53ef\u4ee5\u901a\u8fc7${{}}\u8bed\u6cd5\u5f15\u5165yml\u6587\u4ef6\u4e2d\uff0c\u901a\u8fc7secret.GITHUB_ACTIONS_TOKEN\u8bbf\u95ee\u5230\u3002<\/p>\n<p>\u5982\u4e0a\u6240\u793a\uff0c\u901a\u8fc7\u5c06GITHUB_TOKEN\u4f5c\u4e3a\u73af\u5883\u53d8\u91cf\u5f15\u5165\uff0c\u4fbf\u53efpush\u5230\u76ee\u6807\u7684\u4ed3\u5e93\u4e2d\u3002<\/p>\n<h2>\u53d1\u5e03Release<\/h2>\n<p>\u7531\u4e8eGithub\u53ef\u4ee5\u901a\u8fc7tag\u53d1\u5e03Release, \u56e0\u6b64\u53ea\u9700\u8981\u5728\u6267\u884c\u5b8c\u6253\u5305\u540e\u6dfb\u52a0\u4e00\u4e2atag\u5e76push\u5230\u76ee\u6807repo\u5373\u53ef\u3002\u6838\u5fc3\u4ee3\u7801\u5982\u4e0b:<\/p>\n<pre><code class=\"language-shell \">git config --local user.email \"gxlhybh@gmail.com\"\ngit config --local user.name \"Ryan Lee\"\ngit add --all\ngit commit -m \"deploy `TZ=UTC-8 date +'%Y-%m-%d %H:%M:%S'`\"\ngit tag \"v`cat VERSION`\"\ngit push -f https:\/\/ryanlee2014:$GITHUB_TOKEN@github.com\/ryanlee2014\/CUP-Online-Judge-CDN.git master\ngit push --tags https:\/\/ryanlee2014:$GITHUB_TOKEN@github.com\/ryanlee2014\/CUP-Online-Judge-CDN.git\n<\/code><\/pre>\n<p>\u8fd9\u90e8\u5206\u4ee3\u7801\u4fbf\u662f\u4e0a\u9762yml\u6587\u4ef6\u7684\u6700\u540e\u4e00\u4e2a<code>step<\/code>\u3002<\/p>\n<h2>\u81ea\u52a8\u90e8\u7f72\u5230\u76ee\u6807\u73af\u5883<\/h2>\n<p>Github\u63d0\u4f9b\u4e86webhook\u529f\u80fd\uff0c\u53ef\u4ee5\u5728<code>Settings<\/code> -> <code>Webhook<\/code>\u4e2d\u8bbe\u7f6e\u3002<\/p>\n<p>\u70b9\u51fb<code>Add Webhook<\/code>, \u4fbf\u53ef\u8fdb\u5165\u6dfb\u52a0webhook\u754c\u9762\u3002<\/p>\n<p>\u901a\u8fc7\u8bbe\u7f6eWebhook\u89e6\u53d1\u7684URL\u548cpath\u548c\u89e6\u53d1Secret(\u968f\u4fbf\u8bbe\u7f6e\u4e00\u4e2a\u5e76\u8bb0\u5f55\u4e0b\u6765), \u8bbe\u7f6eContent-type\u4e3aapplication\/json\uff0c\u4fbf\u5b8c\u6210\u521d\u671f\u5de5\u4f5c\u3002<\/p>\n<blockquote><p>\n  URL\u683c\u5f0f:${href}${pathname}, \u5982http:\/\/oj.cupacm.com\/webhook \u4e2d http:\/\/oj.cupacm.com\u662fhref, \/webhook \u662fpathname\n<\/p><\/blockquote>\n<p>\u63a5\u7740\u6211\u4eec\u53ef\u4ee5\u901a\u8fc7\u4e00\u4e2awebhook daemon\u670d\u52a1\u6765\u54cd\u5e94Github\u7684POST\u64cd\u4f5c\u3002\u8fd9\u91cc\u53c2\u8003<a class=\"wp-editor-md-post-content-link\" href=\"https:\/\/github.com\/ryanlee2014\/CUP-Online-Judge-Webhook-Service\">CUP-Online-Judge-Webhook-Service<\/a><\/p>\n<p>\u5728<code>src\/config.json<\/code>\u4e2d\u6709\u56db\u4e2a\u53c2\u6570\u9879\uff0c\u5206\u522b\u662f<\/p>\n<pre><code class=\"language-json \">{\n    \"secret\": \"#\u521a\u624d\u8bbe\u7f6e\u7684secret\",\n    \"path\": \"#\u89e6\u53d1webhook\u7684pathname\",\n    \"port\": #\u76d1\u542c\u7684\u7aef\u53e3,\n    \"shell\": \"#\u6267\u884cshell\u6587\u4ef6\u7684\u547d\u4ee4\"\n}\n<\/code><\/pre>\n<p>\u4f7f\u7528nginx\u6216\u5176\u4ed6Web Server\u5c06webhook\u7684pathname\u53cd\u4ee3\u5230\u670d\u52a1\u7aef\u53e3\uff0c\u5373\u53ef\u89e6\u53d1Webhook, \u7a0b\u5e8f\u4f1a\u81ea\u52a8\u6267\u884cshell\u6587\u4ef6\u3002<br \/>\n\u53ea\u9700\u8981\u5728shell\u6587\u4ef6\u4e2d\u7f16\u5199\u597d\u81ea\u52a8\u90e8\u7f72\u7684\u811a\u672c\u5373\u53ef\u5b8c\u6210\u5168\u81ea\u52a8\u90e8\u7f72\u5de5\u4f5c\u3002<\/p>\n<h2>\u4f7f\u7528JSDelivr\u4f5c\u4e3aCDN\u52a0\u901f<\/h2>\n<p>\u524d\u9762\u6211\u4eec\u4f7f\u7528CI\u53d1\u5e03\u4e86Release, \u56e0\u6b64\u6211\u4eec\u53ef\u4ee5\u901a\u8fc7JSDelivr\u7ed9\u51fa\u7684Github Release\u5305\u8bbf\u95ee\u7684\u6587\u6863\uff0c\u4eceJSDelivr CDN\u4e0a\u62c9\u53d6\u9759\u6001\u8d44\u6e90\u3002<\/p>\n<p>\u6839\u636e\u5b98\u7f51\u7ed9\u51fa\u7684\u8bbf\u95ee\u65b9\u5f0f\u5982\u4e0b:<\/p>\n<pre><code class=\"\">\/\/ load any GitHub release, commit, or branch\n\/\/ note: we recommend using npm for projects that support it\nhttps:\/\/cdn.jsdelivr.net\/gh\/user\/repo@version\/file\n\n\n\/\/ load jQuery v3.2.1\nhttps:\/\/cdn.jsdelivr.net\/gh\/jquery\/jquery@3.2.1\/dist\/jquery.min.js\n\n\n\/\/ use a version range instead of a specific version\nhttps:\/\/cdn.jsdelivr.net\/gh\/jquery\/jquery@3.2\/dist\/jquery.min.js\nhttps:\/\/cdn.jsdelivr.net\/gh\/jquery\/jquery@3\/dist\/jquery.min.js\n\n\/\/ omit the version completely to get the latest one\n\/\/ you should NOT use this in production\nhttps:\/\/cdn.jsdelivr.net\/gh\/jquery\/jquery\/dist\/jquery.min.js\n\n\/\/ add \".min\" to any JS\/CSS file to get a minified version\n\/\/ if one doesn't exist, we'll generate it for you\nhttps:\/\/cdn.jsdelivr.net\/gh\/jquery\/jquery@3.2.1\/src\/core.min.js\n\n\/\/ add \/ at the end to get a directory listing\nhttps:\/\/cdn.jsdelivr.net\/gh\/jquery\/jquery\/\n<\/code><\/pre>\n<p>\u7136\u800c\u8fd9\u5e76\u4e0d\u80fd\u5b8c\u5168\u628a\u8bf7\u6c42\u8f6c\u5411CDN\u3002<br \/>\n\u53c2\u8003<a class=\"wp-editor-md-post-content-link\" href=\"https:\/\/github.com\/ryanlee2014\/CUP-Online-Judge-NG-FrontEnd\">CUP-Online-Judge-NG-FrontEnd<\/a><br \/>\n\u524d\u9762\u53d1\u5e03\u7684\u6307\u4ee4\u4e2d\uff0c\u5bf9\u4e8e\u6bcf\u4e2aRelease\u5305\uff0c\u5747\u4ece<code>VERSION<\/code>\u6587\u4ef6\u4e2d\u8bfb\u53d6Release\u7248\u672c\uff0c\u800c\u6839\u636erepo\u4e2d\u7ed9\u51fa\u7684\u6253\u5305\u8fc7\u7a0b\uff0c\u6211\u4eec\u53d1\u73b0<code>VERSION<\/code>\u6587\u4ef6\u7248\u672c\u662f\u4ece<code>package.json<\/code>\u4e2d\u8bfb\u53d6<code>version<\/code>\u5b57\u6bb5\u751f\u6210\u7684\u3002\u56e0\u6b64\u6211\u4eec\u53ef\u4ee5\u6839\u636e\u6b64\u4fee\u6539<code>vue.config.js<\/code>\u6587\u4ef6\uff0c\u4f7fVue-Router\u4f7f\u7528CDN\u8d44\u6e90<\/p>\n<p>\u7ed9\u51fa\u5982\u4e0b\u4f8b\u5b50<\/p>\n<pre><code class=\"language-javascript \">const version = require(\".\/package.json\").version;\nconst webPath = `https:\/\/cdn.jsdelivr.net\/gh\/ryanlee2014\/CUP-Online-Judge-CDN@v${version}\/`;\n\nmodule.exports = {\n    publicPath: process.env.NODE_ENV === \"production\" &amp;&amp; !process.env.DISABLE_CDN ? webPath : \"\/\"\n};\n\n<\/code><\/pre>\n<p>\u901a\u8fc7\u8bbe\u7f6epublicPath, \u6211\u4eec\u53ef\u4ee5\u628a\u8bf7\u6c42\u8f6c\u5230CDN\u6587\u4ef6\u4e0a\uff0c\u5b9e\u73b0\u9759\u6001\u8d44\u6e90CDN\u5316\u7684\u76ee\u6807\u3002<\/p>\n<p><del>\u6211\u4f30\u8ba1\u4e0a\u9762\u7684\u5185\u5bb9\u6ca1\u51e0\u4e2a\u4eba\u80fd\u770b\u5f97\u61c2\uff0c\u4e0d\u8fc7\u6211\u8fd8\u662f\u8981\u5148\u5199\u4e0b\u6765\u5907\u5fd8<\/del><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u53bb\u5e745\u6708CUPOJ\u524d\u7aef\u4f7f\u7528Vue\u8fdb\u884c\u4e86\u91cd\u6784\uff0c\u56e0\u6b64\u4f7f\u7528Vue-CLI\u6253\u5305\u53d8\u6210\u4e86\u6bcf\u6b21\u53d1\u5e03\u65b0\u7684\u53d8\u66f4\u5fc5\u4e0d\u53ef\u5c11\u7684\u4e00\u4e2a\u4efb\u52a1 [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"spay_email":"","footnotes":"","jetpack_publicize_message":"","jetpack_is_tweetstorm":false},"categories":[65,37,72,59,62],"tags":[73,9,8],"class_list":["post-629","post","type-post","status-publish","format-standard","hentry","category-git","category-node-js","category-online-judge","category-59","category-62","tag-ci","tag-github","tag-javascript"],"jetpack_featured_media_url":"","jetpack_publicize_connections":[],"jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p8UC2c-a9","jetpack_likes_enabled":true,"jetpack-related-posts":[],"_links":{"self":[{"href":"https:\/\/haoyuan.info\/index.php?rest_route=\/wp\/v2\/posts\/629","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/haoyuan.info\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/haoyuan.info\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/haoyuan.info\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/haoyuan.info\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=629"}],"version-history":[{"count":0,"href":"https:\/\/haoyuan.info\/index.php?rest_route=\/wp\/v2\/posts\/629\/revisions"}],"wp:attachment":[{"href":"https:\/\/haoyuan.info\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=629"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/haoyuan.info\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=629"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/haoyuan.info\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=629"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}