GitHub Pages 上的离线 Web 应用

Service Workers 是针对 Application Cache 问题 的解决方案,它是一种强大而优雅的方式来实现您的 Web 应用离线功能。但它们在实现和维护方面也更加复杂。

与此同时,GitHub Pages 是一个很棒的、简单的静态托管服务,适用于 离线优先应用。但是,将应用程序部署到 GitHub Pages 需要手动配置,特别是如果您与团队合作开发、使用 GitHub Flow 的某种变体,并且想要设置持续部署。

Oghliner 是一个 npm 包,它简化了使用 Service Workers 使应用程序离线以及将应用程序部署到 GitHub Pages(包括使用 Travis CI 进行持续部署)这两个步骤。Oghliner 的目标是使离线化和部署 Web 应用程序变得尽可能简单。

要开始使用 Oghliner,请全局安装它。

> npm install --global oghliner

如果您在 GitHub 存储库中有一个现有的应用程序,请调用 integrate 命令来配置它。该命令会将一个 offline-manager.js 脚本(它会注册 Service Worker)复制到您的应用程序中,并提醒您在应用程序的页面/模板(Oghliner 还没有自动执行的少数步骤之一)中加载该脚本。

> oghliner integrate
Integrating Oghliner into the app in the current directory…

 Copying offline-manager.js to ./… done!

Oghliner has been integrated into the app!

The app needs to load the script offline-manager.js in order to register
the service worker that offlines the app. To load the script, add this line to 
the app's HTML page(s)/template(s):

<script src="offline-manager.js"></script>

And commit the changes and push the commit to the origin/master branch:

git commit -m"integrate Oghliner" --all
git push origin master

Then you can offline and deploy the app using the offline and deploy commands.

ℹ For more information about offlining and deployment, see:
    https://mozilla.github.io/oghliner/

如果您还没有现有的应用程序,可以通过 创建新的 GitHub 存储库、将它克隆到您的本地机器,并从它的工作目录中调用 bootstrap 命令来启动一个新的应用程序。

> git clone git@github.com:mykmelez/offline-app.git
Cloning into 'offline-app'...
…
> cd offline-app/
> oghliner bootstrap
Bootstrapping current directory as Oghliner app…

Your app's configuration is:

Name: offline-app
Repository: git@github.com:mykmelez/offline-app.git
Description: A template app bootstrapped with oghliner.
License: Apache-2.0

Would you like to change its configuration (y/N)? 

Creating files…
 Creating README.md
 Creating .gitignore
 Creating gulpfile.js
 Creating package.json
 Creating app/favicon.ico
 Creating app/fonts
 Creating app/index.html
 Creating app/robots.txt
 Creating app/images/apple-touch-icon-114x114.png
 Creating app/images/apple-touch-icon-120x120.png
 Creating app/images/apple-touch-icon-144x144.png
 Creating app/images/apple-touch-icon-152x152.png
 Creating app/images/apple-touch-icon-57x57.png
 Creating app/images/apple-touch-icon-60x60.png
 Creating app/images/apple-touch-icon-72x72.png
 Creating app/images/apple-touch-icon-76x76.png
 Creating app/images/favicon-128x128.png
 Creating app/images/favicon-16x16.png
 Creating app/images/favicon-196x196.png
 Creating app/images/favicon-32x32.png
 Creating app/images/favicon-96x96.png
 Creating app/images/mstile-144x144.png
 Creating app/images/mstile-150x150.png
 Creating app/images/mstile-310x150.png
 Creating app/images/mstile-310x310.png
 Creating app/images/mstile-70x70.png
 Creating app/scripts/main.js
 Creating app/scripts/offline-manager.js
 Creating app/styles/stylesheet.css

 Creating files… done!
 Installing npm dependencies… done!

Your app has been bootstrapped! Just commit the changes and push the commit
to the origin/master branch:

git add --all && git commit -m"initial version of Oghliner app"
git push origin master

Then you can build, offline, and deploy the app using gulp commands.

ℹ For more information about building, offlining and deployment, see:
    https://mozilla.github.io/oghliner/

最后,提交更改以完成配置。

> git add --all && git commit -m"initial version of Oghliner app"

现在您的应用程序已配置,您可以构建、离线化并部署它。引导的应用程序包括一个 gulpfile.js 构建脚本。要构建它们,请全局安装 Gulp。

> npm install --global gulp

然后只需调用 gulp

> gulp

要离线化您的应用程序,请调用 offline 命令生成离线化应用程序的 Service Worker,并指定包含要离线化的文件的目录。

> oghliner offline dist/
Offlining dist/ to dist/offline-worker.js…

 Caching "dist/favicon.ico" (384 B)
 Caching "dist/images/apple-touch-icon-114x114.png" (278 B)
 Caching "dist/images/apple-touch-icon-120x120.png" (285 B)
 Caching "dist/images/apple-touch-icon-144x144.png" (321 B)
 Caching "dist/images/apple-touch-icon-152x152.png" (320 B)
 Caching "dist/images/apple-touch-icon-57x57.png" (242 B)
 Caching "dist/images/apple-touch-icon-60x60.png" (242 B)
 Caching "dist/images/apple-touch-icon-72x72.png" (247 B)
 Caching "dist/images/apple-touch-icon-76x76.png" (247 B)
 Caching "dist/images/favicon-128x128.png" (298 B)
 Caching "dist/images/favicon-16x16.png" (216 B)
 Caching "dist/images/favicon-196x196.png" (380 B)
 Caching "dist/images/favicon-32x32.png" (232 B)
 Caching "dist/images/favicon-96x96.png" (269 B)
 Caching "dist/images/mstile-144x144.png" (323 B)
 Caching "dist/images/mstile-150x150.png" (316 B)
 Caching "dist/images/mstile-310x150.png" (411 B)
 Caching "dist/images/mstile-310x310.png" (610 B)
 Caching "dist/images/mstile-70x70.png" (246 B)
 Caching "dist/index.html" (3.08 kB)
 Caching "dist/robots.txt" (102 B)
 Caching "dist/scripts/main.js" (151 B)
 Caching "dist/scripts/offline-manager.js" (1.1 kB)
 Caching "dist/styles/stylesheet.css" (107 B)
Total precache size is about 10.41 kB for 24 resources.

要将应用程序(包括 Service Worker)部署到 GitHub Pages,请调用 deploy 命令,同样指定包含应用程序文件的目录。

> oghliner deploy dist/
Deploying "initial version of Oghliner app" to GitHub Pages…

 Cloning git@github.com:mykmelez/offline-app.git into .gh-pages-cache… done!
 Cleaning… done!
 Fetching origin… done!
 Checking out origin/gh-pages… done!
 Removing files… done!
 Copying files… done!
 Adding all… done!
 Committing… done!
 Pushing… done!

所有 Oghliner 命令也可以通过模块接口使用,因此您可以使用 Grunt 和 Gulp 等工具将它们集成到您的 Node-based 构建脚本中。如果您使用 Oghliner 启动了应用程序,它的 gulpfile.js 已经包含 offlinedeploy 任务(您也可以将它们用作前面命令的替代方法)。

最后,调用 configure 命令来配置应用程序,使其在您将更改合并到应用程序的 master 分支时自动部署到 GitHub Pages(当然,前提是构建成功完成并且测试通过!)。

> oghliner configure

Configuring Travis to auto-deploy to GitHub Pages…

Your repository has a single remote, origin.
Ok, I'll configure Travis to auto-deploy the origin remote (mykmelez/offline-app).

To check the status of your repository in Travis and authorize Travis to push
to it, I'll create GitHub personal access tokens, for which I need your GitHub
username and password (and two-factor authentication code, if appropriate).

ℹ For more information about GitHub personal access tokens, see:
    https://github.com/settings/tokens

Username: mykmelez
Password: 

× Checking credentials… error!

You're using two-factor authentication with GitHub.
Please enter the code provided by your authentication software.

Auth Code: 123456

 Checking credentials… done!
 Creating temporary GitHub token for getting Travis token… done!
 Getting Travis token… done!
 Deleting temporary GitHub token for getting Travis token… done!
  Creating permanent GitHub token for Travis to push to the repository…
 Creating permanent GitHub token for Travis to push to the repository… done!

ℹ You had an existing token for this app, so we deleted and recreated it.

 Checking the status of your repository in Travis… done!

Good news, your repository is active in Travis!

 Encrypting permanent GitHub token… done!
 Writing configuration to .travis.yml file… done!

⚠ You didn't already have a .travis.yml file, so I created one for you.
  For more information about the file, see:
    https://docs.travis-ci.cn/user/customizing-the-build/

You're ready to auto-deploy using Travis!  Just commit the changes
in .travis.yml and push the commit to the origin/master branch:

git add .travis.yml
git commit -m"configure Travis to auto-deploy to GitHub Pages" .travis.yml
git push origin master

Then visit https://travis-ci.org/mykmelez/offline-app/builds to see the build status.

然后,Travis 会部署成功的构建(在 master 分支上)。

Travis auto-deploys to GitHub Pages

需要注意一些注意事项

  • 部署有时需要几分钟才能在 GitHub Pages 上显示。
  • Service Workers 要求您通过加密的 (HTTPS) 连接加载应用程序。所有 GitHub Pages 都可以通过这种连接加载,即使 GitHub 并没有正式支持它。
  • Service Workers 在 Chrome、Opera 和 Firefox 开发者版中可用。它们将在 Firefox 44 中发布。

Mozilla 的 Web 应用程序开发者计划 工程团队创建了 Oghliner,因为我们认为 Service Workers 是离线化 Web 应用程序的好方法,而 GitHub Pages 是部署它们的好方法,所以我们想看看将两者结合在一起能有多好。

我们在自己的项目中使用了 Oghliner,比如 这个演示Platatus,我们希望您能发现它很令人愉快。所以,了解更多信息,试用一下,让我们知道它对您有什么作用吧!

关于 Myk Melez

Myk 是 Mozilla 的首席软件架构师和内部企业家。自 1999 年以来,他一直是 Mozilla 的成员,为 Web 应用程序开发者计划、PluotSorbet、开放 Web 应用程序、Firefox OS 模拟器、Jetpack、Raindrop、Snowl、Personas、Firefox、Thunderbird 和 Bugzilla 做出了贡献。他只是一个厨师。他所有的泡泡糖都用完了。

Myk Melez 的更多文章…

关于 Marco Castelluccio

Marco 是一个充满热情的 Mozilla hackeneer(黑客和工程师的奇特混合体),他为 Firefox、PluotSorbet、开放 Web 应用程序做出了贡献,并继续做出贡献。最近,他一直在研究将机器学习和数据挖掘技术用于软件工程(测试、崩溃处理、错误管理等)。

Marco Castelluccio 的更多文章…


7 条评论

  1. Sergey Lukin

    非常感谢您!我对此感到非常兴奋。

    > Service Workers 要求您通过加密的 (HTTPS) 连接加载应用程序。所有 GitHub Pages 都可以通过这种连接加载,即使 GitHub 并没有正式支持它。

    这意味着 oghliner 无法在使用自定义域的 GitHub Pages 中使用吗?

    谢谢

    2015 年 11 月 24 日 13:44

    1. Myk Melez

      Oghliner 可以在通过不安全的 HTTP 加载的自定义域中使用,因为它设计为在 Service Worker 不可用时优雅降级,包括不安全的连接、旧版浏览器等。在这种情况下,应用程序仍然可以正常加载和运行,只是不会离线缓存自身,因此您必须在线才能重新加载它。

      Oghliner 也可以在使用 CloudFlare 作为 CDN 的自定义域和安全的 HTTPS 中使用,因为 CloudFlare 支持 SSL,包括在他们的免费计划中。有一些注意事项,但我已经成功地使用它离线化了 https://eggtimer.org/ 和 Oghliner,Fred Wenzel 也用它离线化了 https://firekey.org/,这两个网站都托管在 GitHub Pages 上。

      这是一篇有用的博客文章,解释了设置 CloudFlare 以使用自定义域为 GitHub Pages 网站提供服务的流程:https://www.benburwell.com/posts/configuring-cloudflare-universal-ssl/

      2015 年 11 月 24 日 14:15

  2. Sergey Lukin

    感谢您快速回复。感谢您提到 CloudFlare 免费 SSL 解决方案 + GitHub Pages 设置指南。但是,据我所知,CloudFlare 的灵活 SSL + GitHub Pages 设置不是一个完全有效的 SSL 解决方案,它只是看起来连接是安全的,而实际上并非如此。不过,我可以看到它可以作为最后的手段,以便让 oghliner 在带有自定义域的 GHP 中正常工作。

    2015 年 11 月 24 日 14:34

    1. Myk Melez

      您与 CloudFlare 之间的交易是加密的,但 CloudFlare 与 GitHub Pages 之间的交易不是加密的。正如 Jonathan J. Hunt 在 https://me.net.nz/blog/github-pages-secure-with-cloudflare/ 中指出的那样,后者“通常是在高速回程连接上进行的,攻击者很难获取这些连接(与咖啡馆中的 WiFi 连接相比)。”

      尽管如此,您说得对,它并不完全安全。为此,我们必须等待 GitHub Pages 支持使用自定义域的 SSL。也许 https://letsencrypt.openssl.ac.cn/ 会有所帮助?

      2015 年 11 月 24 日 14:40

  3. Sergey Lukin

    +1 支持 https://letsencrypt.openssl.ac.cn,非常期待!

    2015 年 11 月 24 日 14:52

  4. Mikko Paderes

    我使用的是单页 Web 应用程序,它通过指纹识别我的资产来实现 AppCache 清除机制。这种结构与所有现代浏览器兼容,效果很好。

    Service Workers 有什么优势,能让我想要从当前结构切换到它呢?就目前而言,我认为非单页 Web 应用程序是 Service Workers 的主要受益者。

    2015 年 11 月 24 日 23:43

    1. Myk Melez

      如果您的当前配置对您来说效果很好,而且您不打算添加 Service Workers 独有的功能(比如推送通知),那么就没有充分的理由进行切换。正如您所指出的,AppCache 在现代主要浏览器上运行,在正确实现时可以使您的应用程序离线。Kenneth Ormandy 在 https://davidwalsh.name/dont-wait-serviceworker-adding-offline-support-oneline 中阐述了坚持使用 AppCache 的理由(至少目前是这样)。

      但是对于新开发的项目,我建议从 Service Workers 开始,因为 AppCache 很难正确实现(正如 Jake Archibald 在 http://alistapart.com/article/application-cache-is-a-douchebag 中指出的那样),Service Worker 的支持会随着时间的推移而改进(Firefox 将于 1 月份发布它),这项技术可以作为渐进式增强来实现(因此您的应用程序在没有它的情况下仍然可以在所有浏览器中正常运行),并且它将使您能够利用其他新兴的 Web 平台功能(比如推送通知和后台同步)。

      2015 年 11 月 25 日 08:34

本文评论已关闭。