Skip to content

Commit

Permalink
feat(sw): use lockfile hash
Browse files Browse the repository at this point in the history
  • Loading branch information
yyx990803 committed May 12, 2020
1 parent 3408b97 commit 3bb1324
Show file tree
Hide file tree
Showing 8 changed files with 45 additions and 19 deletions.
2 changes: 1 addition & 1 deletion src/node/build/buildPluginHtml.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export const createBuildHtmlPlugin = async (
inlineLimit: number,
resolver: InternalResolver
) => {
if (!indexPath || !(await fs.pathExists(indexPath))) {
if (!indexPath || !fs.existsSync(indexPath)) {
return {
renderIndex: (...args: any[]) => '',
htmlPlugin: null
Expand Down
2 changes: 1 addition & 1 deletion src/node/build/buildPluginResolve.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export const createBuildResolvePlugin = (
}
if (id.startsWith('/')) {
const resolved = resolver.requestToFile(id)
if (await fs.pathExists(resolved)) {
if (fs.existsSync(resolved)) {
debug(id, `-->`, resolved)
return resolved
}
Expand Down
2 changes: 1 addition & 1 deletion src/node/build/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ export async function build(options: BuildConfig = {}): Promise<BuildResult> {
// copy over /public if it exists
if (emitAssets) {
const publicDir = path.resolve(root, 'public')
if (await fs.pathExists(publicDir)) {
if (fs.existsSync(publicDir)) {
await fs.copy(publicDir, path.resolve(outDir, 'public'))
}
}
Expand Down
16 changes: 10 additions & 6 deletions src/node/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Options:
--help, -h [boolean] show help
--version, -v [boolean] show version
--config, -c [string] use specified config file
--serviceWorker, -sw [boolean | 'deps-only'] configure service worker caching behavior
--serviceWorker, -sw [boolean | 'deps-only'] configure service worker caching (default: true)
--port [number] port to use for serve
--open [boolean] open browser on server start
--base [string] public base path for build (default: /)
Expand All @@ -41,12 +41,16 @@ Options:

console.log(chalk.cyan(`vite v${require('../package.json').version}`))
;(async () => {
const options = await resolveOptions()
if (options.help || options.h) {
if (argv.help || argv.h) {
logHelp()
} else if (options.version || options.v) {
// noop
} else if (!options.command || options.command === 'serve') {
return
} else if (argv.version || argv.v) {
// noop, already logged
return
}

const options = await resolveOptions()
if (!options.command || options.command === 'serve') {
runServe(options)
} else if (options.command === 'build') {
runBuild(options)
Expand Down
4 changes: 2 additions & 2 deletions src/node/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -181,11 +181,11 @@ export async function resolveConfig(
resolvedPath = path.resolve(process.cwd(), configPath)
} else {
const jsConfigPath = path.resolve(process.cwd(), 'vite.config.js')
if (await fs.pathExists(jsConfigPath)) {
if (fs.existsSync(jsConfigPath)) {
resolvedPath = jsConfigPath
} else {
const tsConfigPath = path.resolve(process.cwd(), 'vite.config.ts')
if (await fs.pathExists(tsConfigPath)) {
if (fs.existsSync(tsConfigPath)) {
isTS = true
resolvedPath = tsConfigPath
}
Expand Down
2 changes: 1 addition & 1 deletion src/node/server/serverPluginModuleResolve.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ export async function resolveWebModule(
// id could be a common chunk
if (!id.endsWith('.js')) id += '.js'
webModulePath = path.join(root, 'web_modules', id)
if (await fs.pathExists(webModulePath)) {
if (fs.existsSync(webModulePath)) {
webModulesMap.set(id, webModulePath)
return webModulePath
}
Expand Down
32 changes: 27 additions & 5 deletions src/node/server/serverPluginServiceWorker.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import fs from 'fs'
import path from 'path'
import { createHash } from 'crypto'
import { ServerPlugin } from '.'

// TODO inject lockfile hash
// TODO use file content / lastModified hash instead of timestamp?

export const serviceWorkerPlugin: ServerPlugin = ({
root,
app,
watcher,
resolver,
config
}) => {
// TODO use file content / lastModified hash instead of timestamp?

const enabledString =
typeof config.serviceWorker === 'boolean'
? String(config.serviceWorker)
Expand All @@ -25,10 +25,14 @@ export const serviceWorkerPlugin: ServerPlugin = ({
/const __PROJECT_ROOT__ =.*/,
`const __PROJECT_ROOT__ = ${JSON.stringify(root)}`
)
.replace(
/const __LOCKFILE_HASH__ =.*/,
`const __LOCKFILE_HASH__ = ${JSON.stringify(getLockfileHash(root))}`
)
// inject server start time so the sw cache is invalidated
.replace(
/const __SERVER_TIMESTAMP__ =.*/,
`const __SERVER_TIMESTAMP__ = ${config.serviceWorker ? Date.now() : '0'}`
/const __SERVER_ID__ =.*/,
`const __SERVER_ID__ = ${config.serviceWorker ? Date.now() : '0'}`
)

// enable console logs in debug mode
Expand Down Expand Up @@ -61,3 +65,21 @@ export const serviceWorkerPlugin: ServerPlugin = ({
return next()
})
}

const lockfileFormats = [
'package-lock.json',
'yarn.lock',
'pnpm-lock.yaml',
'package.json'
]

function getLockfileHash(root: string): string {
for (const format of lockfileFormats) {
const fullPath = path.join(root, format)
if (fs.existsSync(fullPath)) {
const content = fs.readFileSync(fullPath, 'utf-8')
return createHash('sha1').update(content).digest('base64')
}
}
return ``
}
4 changes: 2 additions & 2 deletions src/sw/serviceWorker.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
// These are injected by the server on the fly so that we invalidate the cache.
const __ENABLED__ = true as boolean | 'deps-only'
const __PROJECT_ROOT__ = '/'
const __SERVER_TIMESTAMP__ = 1
const __SERVER_ID__ = 1
const __LOCKFILE_HASH__ = 'a'

// We use two separate caches:
// 1. The user files cache is based on the server start timestamp: i.e. it
// persists only for the session of a server process. It is reset every time
// the user restarts the server.
const USER_CACHE_NAME = `vite-cache-${__PROJECT_ROOT__}-${__SERVER_TIMESTAMP__}`
const USER_CACHE_NAME = `vite-cache-${__PROJECT_ROOT__}-${__SERVER_ID__}`
// 2. The deps cache is based on the project's lockfile. They are less likely
// to change, so they are only invalidated when the lockfile has changed.
const DEPS_CACHE_NAME = `vite-cache-${__PROJECT_ROOT__}-${__LOCKFILE_HASH__}`
Expand Down

0 comments on commit 3bb1324

Please sign in to comment.