Giter Club home page Giter Club logo

fusion-plugin-service-worker's Introduction

Modern framework for fast, powerful React apps

Build status fusion-core Downloads

What is it?

fu·sionnoun

The process or result of joining two or more things together to form a single entity.

Fusion.js, Uber’s open source universal web framework, represents the fusion of the client and the server. It's geared for server-side rendering out of the box, and its plugin-driven architecture allows for complex frontend and backend logic to be encapsulated in a single plugin:

import App from 'fusion-react';
import Router from 'fusion-plugin-react-router';

export default () => {
  const app = new App(<div>...</div>);

  /*
  One line of code sets up everything you need for routing:
  - Server rendering
  - React Providers on both server and browser
  - Bundle splitting integration
  - Hot module reloading support
  */
  app.register(Router);

  return app;
}

We initially built Fusion.js to make our own websites easier to maintain, but were so impressed with the benefits that we decided to offer it to the community as an open source project!

Try it out

If you're interested in giving Fusion.js a shot, Overview and Core Concepts are great places to start.

Contributing

This is a monorepo of all open source Fusion.js packages maintained using Yarn v2. Take a look at CONTRIBUTING.md for info on how to develop in this repo.

License

MIT

fusion-plugin-service-worker's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

fusion-plugin-service-worker's Issues

Assign precacehePaths and cacheablePaths to ctx

  • precachePaths is an array of core asset paths (usually main.js and vendor.js)
  • cacheablePaths is a concatenation of precachePaths and all other static assets (could just be JS bundles for phase 1)

Update README to reflect webpack issue

Type of issue

Description

Current behavior

Expected behavior

Steps to reproduce

Your environment

  • fusion-plugin-service-worker version:

  • Node.js version (node --version):

  • npm version (npm --version):

  • Operating System:

Use template to generate sw.js

Type of issue

Description

Current behavior

Expected behavior

Steps to reproduce

Your environment

  • fusion-plugin-service-worker version:

  • Node.js version (node --version):

  • npm version (npm --version):

  • Operating System:

Dependency deprecation warning: @types/redux (npm)

On registry https://registry.yarnpkg.com/, the "latest" version (v3.6.0) of dependency @types/redux has the following deprecation notice:

This is a stub types definition for Redux (https://github.com/reactjs/redux). Redux provides its own type definitions, so you don't need @types/redux installed!

Marking the latest version of an npm package as deprecated results in the entire package being considered deprecated, so contact the package author you think this is a mistake.

Affected package file(s): package.json

If you don't care about this, you can close this issue and not be warned about @types/redux's deprecation again. If you would like to completely disable all future deprecation warnings then add the following to your config:

"suppressNotifications": ["deprecationWarningIssues"]

A config to specify service-workers only on particular routes

Type of issue

Feature

Description

Servicer workers are the new hotness. However, introducing them to an entire web app can be too spicy. It would be great if to test the SW, we could apply it only on particular routes, instead of an entire app. This feature could be through a configuration when registering the service worker. Maybe, the configuration could accept a whitelist of certain routes that the webapp has.

Browser field not respected in sw bundle when es2015 and es2017 fields also used

Update webpack config so that module imports from src/sw.js point to the browser and not node.

We want to be populate src/sw.js in apps like this:

import {getHandlers} from "fusion-plugin-service-worker";

export default (assetInfo) => {
  const {onFetch, onInstall} = getHandlers(assetInfo);
  self.addEventListener("install", onInstall);
  self.addEventListener("fetch", onFetch);
}

Currently it has to be long hand like this

// @flow

/* global self, location, fetch, caches, URL */

const cacheName = '0.0.0'; // we don't expect this to change

export default assetInfo => {
  const {cacheablePaths, precachePaths} = assetInfo;
  self.addEventListener('install', event => {
    self.skipWaiting();
    event.waitUntil(
      // remove old cache
      caches
        .open(cacheName)
        .then(cache => {
          return cache
            .addAll(precachePaths)
            .then(() =>
              getOutdatedKeys(cache, cacheablePaths).then(outdatedKeys =>
                removeKeys(cache, outdatedKeys)
              )
            );
        })
        .catch(e => {
          throw new Error('sw: error updating cache' + cacheName + e);
        })
    );
  });

  self.addEventListener('fetch', event => {
    const HTML_TTL = 1 * 24 * 60 * 60 * 1001; // 1 day
    const expectsHtml = requestExpectsHtml(event.request);
    if (
      !expectsHtml &&
      !cacheablePaths.includes(new URL(event.request.url).pathname)
    ) {
      // bypass service worker, use network
      return;
    }
    event.waitUntil(
      event.respondWith(
        caches.match(event.request).then(cachedResponse => {
          if (cachedResponse) {
            if (expectsHtml) {
              const responseCreated = new Date(
                cachedResponse.headers.get('date')
              ).valueOf();
              if (Date.now() - responseCreated > HTML_TTL) {
                // html expired: use the cache, but refresh cache for next time
                self.fetchNCache(event.request, expectsHtml);
              }
            }
            return cachedResponse;
          }
          return fetchNCache(event.request, expectsHtml);
        })
      )
    );
  });

  function getOutdatedKeys(cache) {
    return cache.keys().then(requests =>
      requests.filter(request => {
        return !cacheablePaths.find(key => {
          return location.origin + key === request.url;
        });
      })
    );
  }

  function removeKeys(cache, keys) {
    return Promise.all(keys.map(key => cache.delete(key)));
  }

  function fetchNCache(request, expectsHtml) {
    return fetch(request).then(resp => {
      if (resp.status !== 200) {
        return Promise.resolve(resp);
      }
      const clonedResponse = resp.clone();
      caches.open(cacheName).then(cache => {
        if (expectsHtml) {
          // check we got html before caching
          if (!responseIsHtml(clonedResponse)) {
            return Promise.resolve(resp);
          }
        }
        cache.put(request.url, clonedResponse);
      });
      return Promise.resolve(resp);
    });
  }

  function requestExpectsHtml(request) {
    if (!request || !request.headers) {
      return false;
    }
    const acceptHeader = request.headers.get('Accept');
    return acceptHeader && acceptHeader.indexOf('html') > -1;
  }

  function responseIsHtml(response) {
    if (!response || !response.headers) {
      return false;
    }
    const contentType = response.headers.get('content-type');
    return contentType && contentType.indexOf('html') > -1;
  }
};

Make sw.js no-cache

We want browser to default to downloading sw.js each time

Edit: looks life default has changed so SW is no cache by default. Will manually add ctx.set('Cache-Control', 'max-age=0') in case any non-compliant implementations still out there.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.