googlechromelabs / application-shell Goto Github PK
View Code? Open in Web Editor NEWService Worker Application Shell Architecture
Home Page: https://app-shell.appspot.com/
License: Apache License 2.0
Service Worker Application Shell Architecture
Home Page: https://app-shell.appspot.com/
License: Apache License 2.0
Two things:
Because we inline CSS, a css change should restart the server.
Verify that the current docs are correct and improve if we can.
There is a lot of stuff going on in this repo. I think it would be really helpful to have at least a few sentences at the start of files such as Dockerfile
, app.yaml
and gulpfile.js
(and probably many other files) to clarify what they do.
I think that would really help people trying to orient their way around this and work out what to modify / rip out for their own variation.
Unless there's a good reason not to. If there is a good reason not to, I'd like to try to address it in the library.
As it stands, the SW implementation will end up trying to re-fetch all the static resources each time the version is bumped, and there's no cache-busting URL parameter to protect against stale resources being returned from the HTTP cache during the install
phase.
Depending on what the HTTP cache expiration is for the static resources, you'll either end up making unnecessary network requests (if your cache expiration is very short) or risk serving stale content from your service worker's fetch
handler (if your cache expiration is longer).
sw-precache
will version each resource automatically and only re-fetch those that change, appending a cache-busting URL parameter.
steve@steve-FX6800-09h:~/javascript/service_worker/ver1/application-shell$ gulp
/home/steve/javascript/service_worker/ver1/application-shell/gulp-tasks/service-worker.js:57
.catch(() => {
^
SyntaxError: Unexpected token )
at exports.runInThisContext (vm.js:73:16)
at Module._compile (module.js:443:25)
at Object.Module._extensions..js (module.js:478:10)
at Module.load (module.js:355:32)
at Function.Module._load (module.js:310:12)
at Module.require (module.js:365:17)
at require (module.js:384:17)
at requireDir (/home/steve/javascript/service_worker/ver1/application-shell/node_modules/require-dir/index.js:116:33)
at Object.<anonymous> (/home/steve/javascript/service_worker/ver1/application-shell/gulpfile.js:40:23)
at Module._compile (module.js:460:26)
steve@steve-FX6800-09h:~/javascript/service_worker/ver1/application-shell$ gulp dev
/home/steve/javascript/service_worker/ver1/application-shell/gulp-tasks/service-worker.js:57
.catch(() => {
^
SyntaxError: Unexpected token )
at exports.runInThisContext (vm.js:73:16)
at Module._compile (module.js:443:25)
at Object.Module._extensions..js (module.js:478:10)
at Module.load (module.js:355:32)
at Function.Module._load (module.js:310:12)
at Module.require (module.js:365:17)
at require (module.js:384:17)
at requireDir (/home/steve/javascript/service_worker/ver1/application-shell/node_modules/require-dir/index.js:116:33)
at Object.<anonymous> (/home/steve/javascript/service_worker/ver1/application-shell/gulpfile.js:40:23)
at Module._compile (module.js:460:26)
I'm sure I'm making a mistake on my end, but I'm a js
neophyte and the build process/ecosystem can be overwhelming. I thought you guys might appreciate being made aware of this error as I followed -- as far as I can tell -- the exact instruction from the Readme. That and node told me to tell you lel
npm ERR! Linux 3.13.0-63-generic
npm ERR! argv "/home/steve/.nvm/versions/node/v0.12.7/bin/node" "/home/steve/.nvm/versions/node/v0.12.7/bin/npm" "install"
npm ERR! node v0.12.7
npm ERR! npm v2.11.3
npm ERR! code ELIFECYCLE
npm ERR! [email protected] postinstall: `gulp`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] postinstall script 'gulp'.
npm ERR! This is most likely a problem with the app-shell package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR! gulp
npm ERR! You can get their info via:
npm ERR! npm owner ls app-shell
npm ERR! There is likely additional logging output above.
This makes testing the other views quite difficult there. Verified it works fine on desktop Safari 9.0. Going to update my iOS devices to iOS9 and check with Safari 9.0 in case the situation is better there.
The latest version of Babel moved over to a more modular architecture that requires a few changes.
We already made these changes in Web Starter Kit over in google/web-starter-kit@ab2e709 and the changes for app-shell should be roughly equivalent.
List of things we've discussed that need doing on app-shell
It would be good to use this repo to host a few other demos, including one based on https://github.com/GoogleChrome/sw-helpers/
I'm going to port over https://github.com/GoogleChrome/sw-precache/tree/master/app-shell-demo to use the new libraries and try to find a place for it here, which might mean rearranging some of the other files to structure things so that each demo is independent.
While installing application-shell, I am getting following error:
C:\Users\cl\Documents\programs\reactjs\application-shell\application-shell\node_modules\sse4_crc32>if not defined npm_config_node_gyp (node "C:\Users\cl\Documents\softwares\node-v8.1.2-win-x64
\node_modules\npm\bin\node-gyp-bin\\..\..\node_modules\node-gyp\bin\node-gyp.js" rebuild ) else (node "" rebuild )
Building the projects in this solution one at a time. To enable parallel build, please add the "/m" switch.
C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V140\Microsoft.CppCommon.targets(356,5): error MSB6006: "CL.exe" exited with code -1073741515. [C:\Users\cl\Documents\programs\reactjs\applic
ation-shell\application-shell\node_modules\sse4_crc32\build\crc32c_sse42.vcxproj]
gyp ERR! build error
gyp ERR! stack Error: `C:\Program Files (x86)\MSBuild\14.0\bin\msbuild.exe` failed with exit code: 1
gyp ERR! stack at ChildProcess.onExit (C:\Users\cl\Documents\softwares\node-v8.1.2-win-x64\node_modules\npm\node_modules\node-gyp\lib\build.js:285:23)
gyp ERR! stack at emitTwo (events.js:125:13)
gyp ERR! stack at ChildProcess.emit (events.js:213:7)
gyp ERR! stack at Process.ChildProcess._handle.onexit (internal/child_process.js:197:12)
gyp ERR! System Windows_NT 10.0.14393
gyp ERR! command "C:\\Users\\cl\\Documents\\softwares\\node-v8.1.2-win-x64\\node.exe" "C:\\Users\\cl\\Documents\\softwares\\node-v8.1.2-win-x64\\node_modules\\npm\\node_modules\\node-gyp\\bin\
\node-gyp.js" "rebuild"
gyp ERR! cwd C:\Users\cl\Documents\programs\reactjs\application-shell\application-shell\node_modules\sse4_crc32
gyp ERR! node -v v8.1.2
gyp ERR! node-gyp -v v3.6.0
gyp ERR! not ok
Please help !
Quite sorry if this is the wrong place for this, not sure where to report this as a Chrome dev tools bug.
For incognito tabs, breakpoints are not saved when you close and reopen them. Incognito mode is quite helpful for developers as it saves us having to clear cookies after each look at the page, but the fact that it removes break points anytime you close the tab is a major impediment.
This may be by design, in which case I would like to hear the argument for this "feature." Thank you!
Why isn't there any index.html page huh?
I don't have any experience with terminal and doesn't like it.
Can I use this template/Shell without node.js/nom?
Can I host it, without terminal?
I found screenshot of this web app, from a website. And being interested on it. Please help, I really need this shell. And I cannot use terminal.
Atm, we revert to full static page reloads for browsers without Service Worker support. We can probably switch to a more SPA-like model without too much difficulty. We're otherwise opting for simplicity with the current approach with a focus on fast initial paint.
--updated --
workaround
commit/0eb960cff1c7fee021f9c67b9a484248accf51ae works fine . this module's syntax OK
application-shell$ gulp --version
[11:27:13] CLI version 3.9.1
[11:27:13] Local version 3.9.1
rob@ application-shell$ gulp clean
/home/rob/tmp/application-shell/gulp-tasks/service-worker.js:57
.catch(() => {
^
SyntaxError: Unexpected token )
at exports.runInThisContext (vm.js:73:16)
at Module._compile (module.js:443:25)
at Object.Module._extensions..js (module.js:478:10)
at Module.load (module.js:355:32)
at Function.Module._load (module.js:310:12)
at Module.require (module.js:365:17)
at require (module.js:384:17)
at requireDir (/home/rob/tmp/application-shell/node_modules/require-dir/index.js:116:33)
at Object. (/home/rob/tmp/application-shell/gulpfile.js:40:23)
at Module._compile (module.js:460:26)
--- i have no idea why it does not like that syntax ..
We should no longer require this afaik.
I just tried it on an iOS 8.3 device and the menu do not work.
@gauntface I've pinged the OSS team about whether or not a complete launch calendar entry will be required given we're reusing voice-memo source files. Will take care of launch process if we need to go through that.
In reference to: https://github.com/GoogleChrome/application-shell/blob/9f56fd016ced3807b83b1f61a7ec03c97811ed1a/server/views/partials/async-css.handlebars#L28
noscript
in an architecture depending on fetch
supportPage(s) will include inline CSS styles in the document to provide a fast first paint of the application shell
I'm using SW precache v2 in my React App and webpack. However, I am not getting the same results. My app works offline but on page reload(offline or online) everything from the DOM disappears and gets fetched again, the results do come from the service worker: (see photo below). In contrast, this app shell demo, react-hn app, and thesession.org app dont even make a request on page reload. What I'm I missing?
Mainly PHP. My assumption (and I think it'd be good to have data around this) is that many people are on shared architectures where PHP is the predominant env.
We should just need a small subset for our needs ๐
Since we don't declare to the dev that they are running a SW they might think something is broken.
Suggestions:
Thinking this would be a great utility to have, and we could demonstrate how to use console.time
to instrument interactions, making for Big Rig-friendly timeline files. Just a thought. Feel free to close :D
Possible Options:
1.) Don't - just inline CSS
2.) Enforce some kind of naming convention
- Default file is index_inline.scss and index_remote.scss if they exists
- for a url, use the name after the origin. For example: localhost:9000/home would look for home_inline.scss and home_remote.scss
3.) Make some better helper methods to wrap request and response parameters (these would take in the response, a css name and view. Ensure safe defaults.
@addyosmani - thoughts? Other options?
That's from Voice Memos ๐
Sorry, real newbie question.
I cloned the 1.x version of this project to have a look. All went fine. Of course, the application shell is cached in Chrome. So now any other project using localhost:8080 is diverted to the application shell. Perhaps I'm missing something simple, but I'd like to remove the cached shell, but don't know how and don't see an obvious reference to that action in the READ.ME. Could I trouble you for some help?
Apologies for what I'm guessing is a real naive question ...
Got this running gulp:
macedo@macedo-Z97-D3H:~/w/application-shell$ gulp
/home/macedo/w/application-shell/gulp-tasks/service-worker.js:56
.catch(() => {
^
SyntaxError: Unexpected token )
at exports.runInThisContext (vm.js:73:16)
at Module._compile (module.js:443:25)
at Object.Module._extensions..js (module.js:478:10)
at Module.load (module.js:355:32)
at Function.Module._load (module.js:310:12)
at Module.require (module.js:365:17)
at require (module.js:384:17)
at requireDir (/home/macedo/w/application-shell/node_modules/require-dir/index.js:116:33)
at Object.<anonymous> (/home/macedo/w/application-shell/gulpfile.js:23:23)
at Module._compile (module.js:460:26)
Matt's going to take a look at this. Just throwing together an issue so we can ๐ฃ
Unnecessary for the shell, I guess :'(
It would be great to explain the concepts in more depth. Perhaps using diagrams/graphs. We can use this as a seed for a more detailed write-up on Web Fundamentals.
Hello,
We are deploying react application generated using crate-react-app to Apache Tomcat-8.
We have homepage: "/chat" in package.json
we generate a chat.war file and deploy to Tomcat, When we access app, now we are getting an error to register service worker with the below error.
Navigated to https://localhost:8000/chat/
An unknown error occurred when fetching the script.
serviceWorker.js:97 Error during service worker registration: DOMException: Failed to register a ServiceWorker for scope ('https://localhost:8000/chat/') with script ('https://localhost:8000/chat/service-worker.js'): An unknown error occurred when fetching the script.
Can someone help me with this why this is failing.
Thanks,
Raghu.
As of #63 there's a different service worker generated based on whether you're in the 'dev' or 'prod' environments. When working on similar setups, I've found it useful to use a different port number for your server depending on the environment as well. That way your 'dev' SW registration will remain separate from your 'prod' SW registration, and you won't keep triggering the SW update flow every time you switch from 'dev' to 'prod'.
Hi, first of all, sorry because this is not an issue but a question.
I have an angular 2 web application with its application shell, push notifications, offline access, etc and everything works like a charm
Now I am trying to render it using angular universal and asp.net core but I don't know how to get the web app working offline.
I build my service worker with sw-precache and I tried with "dynamicUrlToDependencies", which works partially.
Could you please give me any guidance or resources?
Thank you.
We should make it easy to deploy the current setup to at least one of the above.
Answer from Jake:
in the last I've populated
<title>
using a best guess from the url, then use js to set it properly later
Answer from me:
I think we've previously done not too different (default to site-wide
<title>
, later switch when can)
We verified this morning that presence of <title>
in <head>
followed by <title>
later in <body>
is not a workaround folks can rely on. That only works if there's no <title>
defined in <head>
previously. I think the idea of a best guess or default set using JS later is prolly a good answer.
@gauntface could you take a look at this one? Might be something we do before #4.
We would โค๏ธ to get your eyes on the current approach we've taken whenever you have time.
I believe I know the answer why:
This is part the code for nav in the master:
this.rootElement = document.querySelector('.js-side-nav');
this.sideNavContent = this.rootElement
.querySelector('.js-side-nav-content');
this.sideNavBody = this.rootElement.querySelector('.side-nav__body');
this.rootElement.addEventListener('click', () => {
this.close();
});
this.sideNavContent.addEventListener('click', (e) => {
e.stopPropagation();
});
this.hasUnprefixedTransform = 'transform' in document.documentElement.style;
if (this.hasUnprefixedTransform) {
// Touch slop is a variable that is defined to suggest anything larger
// than this value was an intended gesture by the user.
// 8 is a value from Android platform.
// 3 was added as a factor made up from what felt right.
var TOUCH_SLOP = 8 * window.devicePixelRatio * 3;
var touchStartX;
var sideNavTransform;
var onSideNavTouchStart = (e) => {
e.preventDefault();
touchStartX = e.touches[0].pageX;
};
var onSideNavTouchMove = (e) => {
e.preventDefault();
var newTouchX = e.touches[0].pageX;
sideNavTransform = Math.min(0, newTouchX - touchStartX);
this.sideNavContent.style.transform =
'translateX(' + sideNavTransform + 'px)';
};
var onSideNavTouchEnd = (e) => {
if (sideNavTransform < -TOUCH_SLOP) {
this.close();
return;
}
this.open();
};
this.sideNavContent.addEventListener('touchstart', onSideNavTouchStart);
this.sideNavContent.addEventListener('touchmove', onSideNavTouchMove);
this.sideNavContent.addEventListener('touchend', onSideNavTouchEnd);
However this code from current demo, although obscured slightly, does not look similar but shortened, optimized and fixed the bug in master:
this.rootElement = document.querySelector(".js-side-nav"),
this.sideNavContent = this.rootElement.querySelector(".js-side-nav-content");
var n, r, i = function(e) {
n = e.touches[0].pageX
}, a = function(e) {
var o = e.touches[0].pageX;
r = Math.min(0, o - n),
0 > r && e.preventDefault(),
t.sideNavContent.style.transform = "translateX(" + r + "px)"
}, s = function(e) {
-1 > r && t.closeSideNav()
};
this.rootElement.addEventListener("click", function() {
t.close()
}),
this.sideNavContent.addEventListener("click", function(e) {
e.stopPropagation()
}),
this.sideNavContent.addEventListener("touchstart", i),
this.sideNavContent.addEventListener("touchmove", a),
this.sideNavContent.addEventListener("touchend", s)
If I spent the time to decode it and refactor the code and then do a pull request, seems not as efficient as someone who already seems to have a fix to push theirs to master?
For giggles I have the compiled version of the master code that also looks different from what is running on the demo:
this.rootElement = document.querySelector(".js-side-nav"),
this.sideNavContent = this.rootElement.querySelector(".js-side-nav-content"),
this.sideNavBody = this.rootElement.querySelector(".side-nav__body"),
this.rootElement.addEventListener("click", function() {
t.close()
}),
this.sideNavContent.addEventListener("click", function(e) {
e.stopPropagation()
}),
this.hasUnprefixedTransform = "transform"in document.documentElement.style,
this.hasUnprefixedTransform) {
var n, i, r = 8 * window.devicePixelRatio * 3, s = function(e) {
e.preventDefault(),
n = e.touches[0].pageX
}, a = function(e) {
e.preventDefault();
var o = e.touches[0].pageX;
i = Math.min(0, o - n),
t.sideNavContent.style.transform = "translateX(" + i + "px)"
}, u = function(e) {
return i < -r ? void t.close() : void t.open()
};
this.sideNavContent.addEventListener("touchstart", s),
this.sideNavContent.addEventListener("touchmove", a),
this.sideNavContent.addEventListener("touchend", u)
Please and thank you for fixing and looking at this :)
https://github.com/googlechrome/voice-memos could be rewritten to use the refreshed base we've created here. Some things we'll need to add back:
@gauntface I've seen a little flakiness when testing the latest build locally and was wondering if you could find it in your :heart to do a little cross-browser testing on your end in case it's just me.
This is so that outgoing views can transition before incoming views start.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.