Skip to content

Instantly share code, notes, and snippets.

@arayaryoma
Created October 28, 2019 17:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save arayaryoma/a90fce9203b5be61c56a5c46d959c0b7 to your computer and use it in GitHub Desktop.
Save arayaryoma/a90fce9203b5be61c56a5c46d959c0b7 to your computer and use it in GitHub Desktop.
A background script to enable hot reloading for chrome extension development
const filesInDirectory = async (dir: DirectoryEntry): Promise<File[]> => {
return new Promise(async resolve => {
const entries = await readEntries(dir)
return Promise.all(
entries
.filter(e => e.name[0] !== '.')
.map(e => {
if (isDir(e)) {
return filesInDirectory(e)
} else if (isFile(e)) {
return new Promise(resolve => e.file(resolve))
} else {
throw 'error'
}
})
)
.then(files => [].concat(...(files as any)))
.then(resolve)
})
}
const readEntries = async (dir: DirectoryEntry): Promise<Entry[]> => {
return new Promise(resolve => {
dir.createReader().readEntries(entries => {
resolve(entries)
})
})
}
const isDir = (entry: Entry): entry is DirectoryEntry => {
return entry.isDirectory
}
const isFile = (entry: Entry): entry is FileEntry => {
return entry.isFile
}
const timestampForFilesInDirectory = async (
dir: DirectoryEntry
): Promise<string> => {
const files: File[] = await filesInDirectory(dir)
return files.map(f => f.name + f.lastModified).join()
}
const reload = () => {
chrome.tabs.query({ active: true, currentWindow: true }, tabs => {
if (tabs[0]) {
const tab = tabs[0]
if (tab.id) {
chrome.tabs.reload(tab.id)
}
}
chrome.runtime.reload()
})
}
const watchChanges = async (dir: DirectoryEntry, lastTimestamp?: string) => {
const timestamp = await timestampForFilesInDirectory(dir)
console.log(timestamp)
if (!lastTimestamp || lastTimestamp === timestamp) {
setTimeout(() => watchChanges(dir, timestamp), 1000) // retry after 1s
} else {
reload()
}
}
const enableHotReload = () => {
chrome.management.getSelf(self => {
if (self.installType === 'development') {
chrome.runtime.getPackageDirectoryEntry(dir => watchChanges(dir))
}
})
}
export default enableHotReload
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment