class SWHelper

Constants

WORKBOX_VERSION

Public Class Methods

new(site, config) click to toggle source
# File lib/jekyll-pwa-workbox.rb, line 3
def initialize(site, config)
    @site = site
    @config = config
    @sw_filename = @config['sw_dest_filename'] || 'service-worker.js'
    @sw_src_filepath = @config['sw_src_filepath'] || 'service-worker.js'
end

Public Instance Methods

generate_workbox_precache() click to toggle source
# File lib/jekyll-pwa-workbox.rb, line 22
def generate_workbox_precache()
    directory = @config['precache_glob_directory'] || '/'
    directory = @site.in_dest_dir(directory)
    patterns = @config['precache_glob_patterns'] || ['**/*.{html,js,css,ttf,woff}']
    ignores = @config['precache_glob_ignores'] || []
    recent_posts_num = @config['precache_recent_posts_num']

    # according to workbox precache {url: 'main.js', revision: 'xxxx'}
    @precache_list = []

    # find precache files with glob
    precache_files = []
    patterns.each do |pattern|
        Dir.glob(File.join(directory, pattern)) do |filepath|
            precache_files.push(filepath)
        end
    end
    precache_files = precache_files.uniq

    # precache recent n posts
    posts_path_url_map = {}
    if recent_posts_num
        precache_files.concat(
            @site.posts.docs
                .reverse.take(recent_posts_num)
                .map do |post|
                    posts_path_url_map[post.path] = post.url
                    post.path
                end
        )
    end

    # filter with ignores
    ignores.each do |pattern|
        Dir.glob(File.join(directory, pattern)) do |ignored_filepath|
            precache_files.delete(ignored_filepath)
        end
    end

    # generate md5 for each precache file
    md5 = Digest::MD5.new
    precache_files.each do |filepath|
        md5.reset
        md5 << File.read(filepath)
        if posts_path_url_map[filepath]
            url = posts_path_url_map[filepath]
        else
            url = filepath.sub(@site.dest, '')
        end
        @precache_list.push({
            url: @site.baseurl.to_s + url,
            revision: md5.hexdigest
        })
    end
end
write_sw() click to toggle source
# File lib/jekyll-pwa-workbox.rb, line 78
    def write_sw()

        dest_js_directory = @config['dest_js_directory'] || 'js'

        # copy polyfill & workbox.js to js/
        script_directory = @site.in_dest_dir(dest_js_directory)
        FileUtils.mkdir_p(script_directory) unless Dir.exist?(script_directory)
        FileUtils.cp_r(File.expand_path('../vendor/', __FILE__) + '/.', script_directory)

        # generate precache list
        precache_list_str = @precache_list.map do |precache_item|
            precache_item.to_json
        end
        .join(",")

        # write service-worker.js
        sw_src_file_str = File.read(@site.in_source_dir(@sw_src_filepath))
        workbox_dir = File.join(@site.baseurl.to_s, dest_js_directory, "workbox-#{SWHelper::WORKBOX_VERSION}")
        import_scripts_str = 
<<-SCRIPT
importScripts("#{workbox_dir}/workbox-sw.js");
workbox.setConfig({modulePathPrefix: "#{workbox_dir}"});
SCRIPT
        sw_dest_file = File.new(@site.in_dest_dir(@sw_filename), 'w')
        sw_dest_file.puts(
<<-SCRIPT
#{import_scripts_str}
self.__precacheManifest = [#{precache_list_str}];

#{sw_src_file_str}
SCRIPT
        )
        sw_dest_file.close
    end
write_sw_register() click to toggle source
# File lib/jekyll-pwa-workbox.rb, line 10
    def write_sw_register()
        sw_register_filename = 'sw-register.js'
        sw_register_file = File.new(@site.in_dest_dir(sw_register_filename), 'w')
        # add build version in url params
        sw_register_file.puts(
<<-SCRIPT
"serviceWorker"in navigator&&navigator.serviceWorker.register("#{@site.baseurl.to_s}/#{@sw_filename}?v=#{@site.time.to_i.to_s}").then(function(e){e.onupdatefound=function(){var r=e.installing;r.onstatechange=function(){switch(r.state){case"installed":var e;navigator.serviceWorker.controller&&(e=new Event("sw.update"),window.dispatchEvent(e))}}}}).catch(function(e){console.error("Error during service worker registration:",e)});
SCRIPT
        )
        sw_register_file.close
    end