vite
Advanced tools
Comparing version 0.14.2 to 0.14.3
@@ -0,1 +1,21 @@ | ||
## [0.14.3](https://github.com/vuejs/vite/compare/v0.14.2...v0.14.3) (2020-05-12) | ||
### Bug Fixes | ||
* first request on server start should never 304 ([c8a1ffd](https://github.com/vuejs/vite/commit/c8a1ffd71db0916cd6386130e3eb170fa09c31d2)) | ||
* fix web modules resolve ([ce41994](https://github.com/vuejs/vite/commit/ce41994ee4e395bb304191b5d9a26f0f32d3b47a)) | ||
* make transformed imports work in Safari ([b2377bf](https://github.com/vuejs/vite/commit/b2377bf3b6b14ed972327930644fe6937fa814dd)) | ||
* only register sw if available ([2efe9b3](https://github.com/vuejs/vite/commit/2efe9b3215f04e751d19cd50169bddf4250d114d)) | ||
* should resolve web_modules during rewrite too ([b5871eb](https://github.com/vuejs/vite/commit/b5871eba505e5a109b8b8ae07d6f8a70c6d970eb)) | ||
### Features | ||
* **cva:** use @pika/react + alias ([f9b267f](https://github.com/vuejs/vite/commit/f9b267fbe3f6e8cc11a3e6855f7775aeb863b0f8)) | ||
* **sw:** use lockfile hash ([3bb1324](https://github.com/vuejs/vite/commit/3bb13240d9d6c3ef84020cd69b2e60835f206f8f)) | ||
* service worker caching ([ee6a03d](https://github.com/vuejs/vite/commit/ee6a03d3497433150c13fc9370b17daaa43e1e1d)) | ||
## [0.14.2](https://github.com/vuejs/vite/compare/v0.14.1...v0.14.2) (2020-05-11) | ||
@@ -2,0 +22,0 @@ |
@@ -13,3 +13,3 @@ "use strict"; | ||
exports.createBuildHtmlPlugin = async (root, indexPath, publicBasePath, assetsDir, inlineLimit, resolver) => { | ||
if (!indexPath || !(await fs_extra_1.default.pathExists(indexPath))) { | ||
if (!indexPath || !fs_extra_1.default.existsSync(indexPath)) { | ||
return { | ||
@@ -16,0 +16,0 @@ renderIndex: (...args) => '', |
@@ -27,3 +27,3 @@ "use strict"; | ||
const resolved = resolver.requestToFile(id); | ||
if (await fs_extra_1.default.pathExists(resolved)) { | ||
if (fs_extra_1.default.existsSync(resolved)) { | ||
debug(id, `-->`, resolved); | ||
@@ -30,0 +30,0 @@ return resolved; |
@@ -163,3 +163,3 @@ "use strict"; | ||
const publicDir = path_1.default.resolve(root, 'public'); | ||
if (await fs_extra_1.default.pathExists(publicDir)) { | ||
if (fs_extra_1.default.existsSync(publicDir)) { | ||
await fs_extra_1.default.copy(publicDir, path_1.default.resolve(outDir, 'public')); | ||
@@ -166,0 +166,0 @@ } |
@@ -28,2 +28,3 @@ "use strict"; | ||
--config, -c [string] use specified config file | ||
--serviceWorker, -sw [boolean] configure service worker caching (default: false) | ||
--port [number] port to use for serve | ||
@@ -36,3 +37,3 @@ --open [boolean] open browser on server start | ||
--sourcemap [boolean] output source maps for build (default: false) | ||
--minify [boolean | 'terser' | 'esbuild'] disable minification, or specify | ||
--minify [boolean | 'terser' | 'esbuild'] enable/disable minification, or specify | ||
minifier to use. (default: 'terser') | ||
@@ -47,10 +48,12 @@ --ssr [boolean] build for server-side rendering | ||
(async () => { | ||
const options = await resolveOptions(); | ||
if (options.help || options.h) { | ||
if (argv.help || argv.h) { | ||
logHelp(); | ||
return; | ||
} | ||
else if (options.version || options.v) { | ||
// noop | ||
else if (argv.version || argv.v) { | ||
// noop, already logged | ||
return; | ||
} | ||
else if (!options.command || options.command === 'serve') { | ||
const options = await resolveOptions(); | ||
if (!options.command || options.command === 'serve') { | ||
runServe(options); | ||
@@ -70,2 +73,6 @@ } | ||
async function resolveOptions() { | ||
// shorthand for serviceWorker option | ||
if (argv['sw']) { | ||
argv.serviceWorker = argv['sw']; | ||
} | ||
// map jsx args | ||
@@ -80,3 +87,3 @@ if (argv['jsx-factory']) { | ||
} | ||
// cast xxx=false into actual `false` | ||
// cast xxx=true | false into actual booleans | ||
Object.keys(argv).forEach((key) => { | ||
@@ -86,2 +93,5 @@ if (argv[key] === 'false') { | ||
} | ||
if (argv[key] === 'true') { | ||
argv[key] = true; | ||
} | ||
}); | ||
@@ -88,0 +98,0 @@ // command |
@@ -0,1 +1,24 @@ | ||
// register service worker | ||
if ('serviceWorker' in navigator) { | ||
const hasExistingSw = !!navigator.serviceWorker.controller; | ||
if (__SW_ENABLED__ || hasExistingSw) { | ||
// if not enabled but has existing sw, registering the sw will force the | ||
// cache to be busted. | ||
navigator.serviceWorker.register('/sw.js').catch((e) => { | ||
console.log('[vite] failed to register service worker:', e); | ||
}); | ||
// Notify the user to reload the page if a new service worker has taken | ||
// control. | ||
if (hasExistingSw) { | ||
navigator.serviceWorker.addEventListener('controllerchange', () => { | ||
if (window.confirm('[vite] Service worker cache updated. Reload?')) { | ||
window.location.reload(); | ||
} | ||
// in case the user dismisses it, or the prompt failed to pop because | ||
// the tab was inactive | ||
console.warn(`[vite] Service worker cache updated. A reload is required.`); | ||
}); | ||
} | ||
} | ||
} | ||
console.log('[vite] connecting...'); | ||
@@ -13,4 +36,10 @@ const socketProtocol = location.protocol === 'https:' ? 'wss' : 'ws'; | ||
// Listen for messages | ||
socket.addEventListener('message', ({ data }) => { | ||
const { type, path, id, index, timestamp, customData } = JSON.parse(data); | ||
socket.addEventListener('message', async ({ data }) => { | ||
const { type, path, changeSrcPath, id, index, timestamp, customData } = JSON.parse(data); | ||
if (changeSrcPath) { | ||
await bustSwCache(changeSrcPath); | ||
} | ||
if (path !== changeSrcPath) { | ||
await bustSwCache(path); | ||
} | ||
switch (type) { | ||
@@ -29,3 +58,5 @@ case 'connected': | ||
case 'vue-rerender': | ||
import(`${path}?type=template&t=${timestamp}`).then((m) => { | ||
const templatePath = `${path}?type=template`; | ||
await bustSwCache(templatePath); | ||
import(`${templatePath}&t=${timestamp}`).then((m) => { | ||
__VUE_HMR_RUNTIME__.rerender(path, m.render); | ||
@@ -36,7 +67,9 @@ console.log(`[vite] ${path} template updated.`); | ||
case 'vue-style-update': | ||
updateStyle(id, `${path}?type=style&index=${index}&t=${timestamp}`); | ||
const stylePath = `${path}?type=style&index=${index}`; | ||
await bustSwCache(stylePath); | ||
updateStyle(id, stylePath); | ||
console.log(`[vite] ${path} style${index > 0 ? `#${index}` : ``} updated.`); | ||
break; | ||
case 'style-update': | ||
updateStyle(id, `${path}?raw&t=${timestamp}`); | ||
updateStyle(id, `${path}?t=${timestamp}`); | ||
console.log(`[vite] ${path} updated.`); | ||
@@ -125,1 +158,17 @@ break; | ||
}; | ||
function bustSwCache(path) { | ||
const sw = navigator.serviceWorker && navigator.serviceWorker.controller; | ||
if (sw) { | ||
return new Promise((r) => { | ||
const channel = new MessageChannel(); | ||
channel.port1.onmessage = (e) => { | ||
if (e.data.busted) | ||
r(); | ||
}; | ||
sw.postMessage({ | ||
type: 'bust-cache', | ||
path: `${location.protocol}//${location.host}${path}` | ||
}, [channel.port2]); | ||
}); | ||
} | ||
} |
@@ -49,2 +49,10 @@ import { ServerPlugin } from './server'; | ||
export interface ServerConfig extends SharedConfig { | ||
/** | ||
* Whether to use a Service Worker to cache served code. This can greatly | ||
* improve full page reload performance, but requires a Service Worker | ||
* update + reload on each server restart. | ||
* | ||
* @default false | ||
*/ | ||
serviceWorker?: boolean; | ||
plugins?: ServerPlugin[]; | ||
@@ -128,3 +136,3 @@ } | ||
} | ||
export interface UserConfig extends BuildConfig { | ||
export interface UserConfig extends BuildConfig, Pick<ServerConfig, 'serviceWorker'> { | ||
plugins?: Plugin[]; | ||
@@ -131,0 +139,0 @@ configureServer?: ServerPlugin; |
@@ -20,3 +20,3 @@ "use strict"; | ||
const jsConfigPath = path_1.default.resolve(process.cwd(), 'vite.config.js'); | ||
if (await fs_extra_1.default.pathExists(jsConfigPath)) { | ||
if (fs_extra_1.default.existsSync(jsConfigPath)) { | ||
resolvedPath = jsConfigPath; | ||
@@ -26,3 +26,3 @@ } | ||
const tsConfigPath = path_1.default.resolve(process.cwd(), 'vite.config.ts'); | ||
if (await fs_extra_1.default.pathExists(tsConfigPath)) { | ||
if (fs_extra_1.default.existsSync(tsConfigPath)) { | ||
isTS = true; | ||
@@ -29,0 +29,0 @@ resolvedPath = tsConfigPath; |
@@ -20,2 +20,3 @@ "use strict"; | ||
const transform_1 = require("../transform"); | ||
const serverPluginServiceWorker_1 = require("./serverPluginServiceWorker"); | ||
var serverPluginModuleRewrite_2 = require("./serverPluginModuleRewrite"); | ||
@@ -41,2 +42,3 @@ exports.rewriteImports = serverPluginModuleRewrite_2.rewriteImports; | ||
...plugins, | ||
serverPluginServiceWorker_1.serviceWorkerPlugin, | ||
serverPluginHmr_1.hmrPlugin, | ||
@@ -43,0 +45,0 @@ serverPluginModuleRewrite_1.moduleRewritePlugin, |
@@ -18,11 +18,9 @@ "use strict"; | ||
ctx.body) { | ||
if (utils_1.isImportRequest(ctx) && | ||
// skip raw requests | ||
ctx.query.raw == null) { | ||
if (utils_1.isImportRequest(ctx)) { | ||
await processCss(ctx); | ||
// we rewrite it to JS that injects a <style> tag pointing to the same url | ||
// but with a `?raw` query which returns the actual css | ||
// we rewrite css with `?import` to a js module that inserts a style | ||
// tag linking to the actual raw url | ||
ctx.type = 'js'; | ||
const id = JSON.stringify(hash_sum_1.default(ctx.path)); | ||
const rawPath = JSON.stringify(ctx.path + '?raw'); | ||
const rawPath = JSON.stringify(ctx.path); | ||
let code = `import { updateStyle } from "${serverPluginHmr_1.hmrClientId}"\n` + | ||
@@ -29,0 +27,0 @@ `updateStyle(${id}, ${rawPath})\n`; |
@@ -21,5 +21,6 @@ import { ServerPlugin } from '.'; | ||
interface HMRPayload { | ||
type: 'vue-rerender' | 'vue-reload' | 'vue-style-update' | 'js-update' | 'style-update' | 'style-remove' | 'full-reload' | 'custom'; | ||
type: 'vue-rerender' | 'vue-reload' | 'vue-style-update' | 'js-update' | 'style-update' | 'style-remove' | 'full-reload' | 'sw-bust-cache' | 'custom'; | ||
timestamp: number; | ||
path?: string; | ||
changeSrcPath?: string; | ||
id?: string; | ||
@@ -31,3 +32,3 @@ index?: number; | ||
export declare function ensureMapEntry(map: HMRStateMap, key: string): Set<string>; | ||
export declare function rewriteFileWithHMR(source: string, importer: string, resolver: InternalResolver, s: MagicString): void; | ||
export declare function rewriteFileWithHMR(root: string, source: string, importer: string, resolver: InternalResolver, s: MagicString): void; | ||
export {}; |
@@ -27,2 +27,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const fs_1 = __importDefault(require("fs")); | ||
const ws_1 = __importDefault(require("ws")); | ||
@@ -34,3 +35,2 @@ const path_1 = __importDefault(require("path")); | ||
const serverPluginModuleRewrite_1 = require("./serverPluginModuleRewrite"); | ||
const utils_1 = require("../utils"); | ||
const parser_1 = require("@babel/parser"); | ||
@@ -51,9 +51,12 @@ const lru_cache_1 = __importDefault(require("lru-cache")); | ||
exports.hmrPlugin = ({ root, app, server, watcher, resolver, config }) => { | ||
const hmrClient = fs_1.default.readFileSync(exports.hmrClientFilePath, 'utf-8'); | ||
app.use(async (ctx, next) => { | ||
if (ctx.path !== exports.hmrClientPublicPath) { | ||
if (ctx.path === exports.hmrClientPublicPath) { | ||
ctx.type = 'js'; | ||
ctx.status = 200; | ||
ctx.body = hmrClient; | ||
} | ||
else { | ||
return next(); | ||
} | ||
exports.debugHmr('serving hmr client'); | ||
ctx.type = 'js'; | ||
await utils_1.cachedRead(ctx, exports.hmrClientFilePath); | ||
}); | ||
@@ -119,2 +122,3 @@ // start a websocket server to send hmr notifications to the client | ||
let needReload = false; | ||
let needCssModuleReload = false; | ||
let needRerender = false; | ||
@@ -131,12 +135,13 @@ if (!isEqual(descriptor.script, prevDescriptor.script)) { | ||
const nextStyles = descriptor.styles || []; | ||
if ((!needReload && | ||
prevStyles.some((s) => s.scoped) !== | ||
nextStyles.some((s) => s.scoped)) || | ||
// TODO for now we force the component to reload on <style module> change | ||
// but this should be optimizable to replace the __cssMoudles object | ||
// on script and only trigger a rerender. | ||
prevStyles.some((s) => s.module != null) || | ||
nextStyles.some((s) => s.module != null)) { | ||
if (!needReload && | ||
prevStyles.some((s) => s.scoped) !== nextStyles.some((s) => s.scoped)) { | ||
needReload = true; | ||
} | ||
// css modules update causes a reload because the $style object is changed | ||
// and it may be used in JS. It also needs to trigger a vue-style-update | ||
// event so the client busts the sw cache. | ||
if (prevStyles.some((s) => s.module != null) || | ||
nextStyles.some((s) => s.module != null)) { | ||
needCssModuleReload = true; | ||
} | ||
// only need to update styles if not reloading, since reload forces | ||
@@ -168,3 +173,3 @@ // style updates as well. | ||
}); | ||
if (needReload) { | ||
if (needReload || needCssModuleReload) { | ||
send({ | ||
@@ -214,2 +219,3 @@ type: 'vue-reload', | ||
type: 'full-reload', | ||
path: publicPath, | ||
timestamp | ||
@@ -226,2 +232,3 @@ }); | ||
path: vueImporter, | ||
changeSrcPath: publicPath, | ||
timestamp | ||
@@ -236,2 +243,3 @@ }); | ||
path: jsImporter, | ||
changeSrcPath: publicPath, | ||
timestamp | ||
@@ -305,3 +313,3 @@ }); | ||
exports.ensureMapEntry = ensureMapEntry; | ||
function rewriteFileWithHMR(source, importer, resolver, s) { | ||
function rewriteFileWithHMR(root, source, importer, resolver, s) { | ||
const ast = parser_1.parse(source, { | ||
@@ -320,3 +328,3 @@ sourceType: 'module', | ||
const deps = ensureMapEntry(exports.hmrAcceptanceMap, importer); | ||
const depPublicPath = serverPluginModuleRewrite_1.resolveImport(importer, e.value, resolver); | ||
const depPublicPath = serverPluginModuleRewrite_1.resolveImport(root, importer, e.value, resolver); | ||
deps.add(depPublicPath); | ||
@@ -323,0 +331,0 @@ exports.debugHmr(` ${importer} accepts ${depPublicPath}`); |
@@ -6,2 +6,3 @@ import { ServerPlugin } from '.'; | ||
export declare const moduleResolvePlugin: ServerPlugin; | ||
export declare function resolveWebModule(root: string, id: string): Promise<string | undefined>; | ||
export declare function resolveWebModule(root: string, id: string): string | undefined; | ||
export declare function resolveNodeModuleEntry(root: string, id: string): string | undefined; |
@@ -11,8 +11,5 @@ "use strict"; | ||
const utils_1 = require("../utils"); | ||
const slash_1 = __importDefault(require("slash")); | ||
const debug = require('debug')('vite:resolve'); | ||
const idToEntryMap = new Map(); | ||
exports.idToFileMap = new Map(); | ||
exports.fileToRequestMap = new Map(); | ||
const webModulesMap = new Map(); | ||
exports.moduleRE = /^\/@modules\//; | ||
@@ -53,12 +50,5 @@ const getDebugPath = (root, p) => { | ||
} | ||
// package entries need redirect to ensure correct relative import paths | ||
// check if the entry was already resolved | ||
const cachedEntry = idToEntryMap.get(id); | ||
if (cachedEntry) { | ||
debug(`(cached redirect) ${id} -> ${cachedEntry}`); | ||
return ctx.redirect(slash_1.default(path_1.default.join(ctx.path, cachedEntry))); | ||
} | ||
// resolve from web_modules | ||
try { | ||
const webModulePath = await resolveWebModule(root, id); | ||
const webModulePath = resolveWebModule(root, id); | ||
if (webModulePath) { | ||
@@ -73,6 +63,2 @@ return serve(id, webModulePath, 'web_modules'); | ||
} | ||
const entryPoint = await resolveNodeModuleEntry(root, id); | ||
if (entryPoint) { | ||
return ctx.redirect(slash_1.default(path_1.default.join(ctx.path, entryPoint))); | ||
} | ||
// resolve from node_modules | ||
@@ -92,6 +78,7 @@ try { | ||
}; | ||
async function resolveWebModule(root, id) { | ||
let webModulePath = webModulesMap.get(id); | ||
if (webModulePath) { | ||
return webModulePath; | ||
const webModulesMap = new Map(); | ||
function resolveWebModule(root, id) { | ||
const cached = webModulesMap.get(id); | ||
if (cached) { | ||
return cached; | ||
} | ||
@@ -101,4 +88,4 @@ // id could be a common chunk | ||
id += '.js'; | ||
webModulePath = path_1.default.join(root, 'web_modules', id); | ||
if (await fs_extra_1.default.pathExists(webModulePath)) { | ||
const webModulePath = path_1.default.join(root, 'web_modules', id); | ||
if (fs_extra_1.default.existsSync(webModulePath)) { | ||
webModulesMap.set(id, webModulePath); | ||
@@ -109,3 +96,8 @@ return webModulePath; | ||
exports.resolveWebModule = resolveWebModule; | ||
async function resolveNodeModuleEntry(root, id) { | ||
const idToEntryMap = new Map(); | ||
function resolveNodeModuleEntry(root, id) { | ||
const cached = idToEntryMap.get(id); | ||
if (cached) { | ||
return cached; | ||
} | ||
let pkgPath; | ||
@@ -120,4 +112,4 @@ try { | ||
const pkg = require(pkgPath); | ||
const entryPoint = pkg.module || pkg.main || 'index.js'; | ||
debug(`(redirect) ${id} -> ${entryPoint}`); | ||
const entryPoint = id + '/' + (pkg.module || pkg.main || 'index.js'); | ||
debug(`(node_module entry) ${id} -> ${entryPoint}`); | ||
idToEntryMap.set(id, entryPoint); | ||
@@ -127,1 +119,2 @@ return entryPoint; | ||
} | ||
exports.resolveNodeModuleEntry = resolveNodeModuleEntry; |
import { ServerPlugin } from '.'; | ||
import { InternalResolver } from '../resolver'; | ||
export declare const moduleRewritePlugin: ServerPlugin; | ||
export declare function rewriteImports(source: string, importer: string, resolver: InternalResolver, timestamp?: string): string; | ||
export declare const resolveImport: (importer: string, id: string, resolver: InternalResolver, timestamp?: string | undefined) => string; | ||
export declare function rewriteImports(root: string, source: string, importer: string, resolver: InternalResolver, timestamp?: string): string; | ||
export declare const resolveImport: (root: string, importer: string, id: string, resolver: InternalResolver, timestamp?: string | undefined) => string; |
@@ -14,2 +14,3 @@ "use strict"; | ||
const chalk_1 = __importDefault(require("chalk")); | ||
const serverPluginModuleResolve_1 = require("./serverPluginModuleResolve"); | ||
const debug = require('debug')('vite:rewrite'); | ||
@@ -24,3 +25,3 @@ const rewriteCache = new lru_cache_1.default({ max: 1024 }); | ||
// The graph is used by the HMR plugin to perform analysis on file change. | ||
exports.moduleRewritePlugin = ({ app, watcher, resolver }) => { | ||
exports.moduleRewritePlugin = ({ root, app, watcher, resolver, config }) => { | ||
// bust module rewrite cache on file change | ||
@@ -34,8 +35,9 @@ watcher.on('change', (file) => { | ||
// since some ESM builds expect these to be replaced by the bundler | ||
const devInjectionCode = `\n<script type="module">` + | ||
`import "${serverPluginHmr_1.hmrClientPublicPath}"\n` + | ||
const devInjectionCode = `\n<script>\n` + | ||
`window.__DEV__ = true\n` + | ||
`window.__BASE__ = '/'\n` + | ||
`window.__SW_ENABLED__ = ${!!config.serviceWorker}\n` + | ||
`window.process = { env: { NODE_ENV: 'development' }}\n` + | ||
`</script>\n`; | ||
`</script>` + | ||
`\n<script type="module" src="${serverPluginHmr_1.hmrClientPublicPath}"></script>\n`; | ||
const scriptRE = /(<script\b[^>]*>)([\s\S]*?)<\/script>/gm; | ||
@@ -62,3 +64,3 @@ const srcRE = /\bsrc=(?:"([^"]+)"|'([^']+)'|([^'"\s]+)\b)/; | ||
if (script) { | ||
return `${devFlag}${openTag}${rewriteImports(script, importer, resolver)}</script>`; | ||
return `${devFlag}${openTag}${rewriteImports(root, script, importer, resolver)}</script>`; | ||
} | ||
@@ -97,3 +99,3 @@ else { | ||
await es_module_lexer_1.init; | ||
ctx.body = rewriteImports(content, ctx.path, resolver, ctx.query.t); | ||
ctx.body = rewriteImports(root, content, ctx.path, resolver, ctx.query.t); | ||
rewriteCache.set(content, ctx.body); | ||
@@ -107,3 +109,3 @@ } | ||
}; | ||
function rewriteImports(source, importer, resolver, timestamp) { | ||
function rewriteImports(root, source, importer, resolver, timestamp) { | ||
if (typeof source !== 'string') { | ||
@@ -150,3 +152,3 @@ source = String(source); | ||
// making the module hot. | ||
serverPluginHmr_1.rewriteFileWithHMR(source, importer, resolver, s); | ||
serverPluginHmr_1.rewriteFileWithHMR(root, source, importer, resolver, s); | ||
// we rewrite the hot.accept call | ||
@@ -157,3 +159,3 @@ hasReplaced = true; | ||
else { | ||
resolved = exports.resolveImport(importer, id, resolver, timestamp); | ||
resolved = exports.resolveImport(root, importer, id, resolver, timestamp); | ||
} | ||
@@ -210,6 +212,10 @@ if (resolved !== id) { | ||
const fileExtensionRE = /\.\w+$/; | ||
exports.resolveImport = (importer, id, resolver, timestamp) => { | ||
const jsSrcRE = /\.(?:(?:j|t)sx?|vue)$/; | ||
exports.resolveImport = (root, importer, id, resolver, timestamp) => { | ||
id = resolver.alias(id) || id; | ||
if (bareImportRE.test(id)) { | ||
return `/@modules/${id}`; | ||
// directly resolve bare module names to its entry path so that relative | ||
// imports from it (including source map urls) can work correctly | ||
const isWebModule = !!serverPluginModuleResolve_1.resolveWebModule(root, id); | ||
return `/@modules/${isWebModule ? id : serverPluginModuleResolve_1.resolveNodeModuleEntry(root, id) || id}`; | ||
} | ||
@@ -229,2 +235,6 @@ else { | ||
} | ||
// mark non-src imports | ||
if (!jsSrcRE.test(pathname)) { | ||
query += `${query ? `&` : `?`}import`; | ||
} | ||
// force re-fetch dirty imports by appending timestamp | ||
@@ -231,0 +241,0 @@ if (timestamp) { |
import { ServerPlugin } from '.'; | ||
export declare const seenUrls: Set<unknown>; | ||
export declare const serveStaticPlugin: ServerPlugin; |
@@ -5,3 +5,4 @@ "use strict"; | ||
const debug = require('debug')('vite:history'); | ||
exports.serveStaticPlugin = ({ root, app, resolver }) => { | ||
exports.seenUrls = new Set(); | ||
exports.serveStaticPlugin = ({ root, app, resolver, config }) => { | ||
app.use((ctx, next) => { | ||
@@ -42,3 +43,12 @@ // short circuit requests that have already been explicitly handled | ||
}); | ||
app.use(require('koa-conditional-get')()); | ||
if (!config.serviceWorker) { | ||
app.use(async (ctx, next) => { | ||
await next(); | ||
// the first request to the server should never 304 | ||
if (exports.seenUrls.has(ctx.url) && ctx.fresh) { | ||
ctx.status = 304; | ||
} | ||
exports.seenUrls.add(ctx.url); | ||
}); | ||
} | ||
app.use(require('koa-etag')()); | ||
@@ -45,0 +55,0 @@ app.use((ctx, next) => { |
@@ -16,2 +16,3 @@ "use strict"; | ||
const querystring_1 = __importDefault(require("querystring")); | ||
const serverPluginServeStatic_1 = require("./serverPluginServeStatic"); | ||
const debug = require('debug')('vite:sfc'); | ||
@@ -23,7 +24,14 @@ const getEtag = require('etag'); | ||
}); | ||
const etagCacheCheck = (ctx) => { | ||
ctx.etag = getEtag(ctx.body); | ||
ctx.status = ctx.etag === ctx.get('If-None-Match') ? 304 : 200; | ||
}; | ||
exports.vuePlugin = ({ root, app, resolver, watcher, config }) => { | ||
const etagCacheCheck = (ctx) => { | ||
ctx.etag = getEtag(ctx.body); | ||
// only add 304 tag check if not using service worker to cache user code | ||
if (!config.serviceWorker) { | ||
ctx.status = | ||
serverPluginServeStatic_1.seenUrls.has(ctx.url) && ctx.etag === ctx.get('If-None-Match') | ||
? 304 | ||
: 200; | ||
serverPluginServeStatic_1.seenUrls.add(ctx.url); | ||
} | ||
}; | ||
app.use(async (ctx, next) => { | ||
@@ -30,0 +38,0 @@ if (!ctx.path.endsWith('.vue') && !ctx.vue) { |
@@ -10,2 +10,3 @@ "use strict"; | ||
const stream_1 = require("stream"); | ||
const serverPluginServeStatic_1 = require("../server/serverPluginServeStatic"); | ||
const getETag = require('etag'); | ||
@@ -30,6 +31,8 @@ const moduleReadCache = new lru_cache_1.default({ | ||
ctx.lastModified = new Date(cached.lastModified); | ||
if (ctx.get('If-None-Match') === ctx.etag) { | ||
if (ctx.__serviceWorker !== true && | ||
ctx.get('If-None-Match') === ctx.etag && | ||
serverPluginServeStatic_1.seenUrls.has(ctx.url)) { | ||
ctx.status = 304; | ||
} | ||
// still set the content for *.vue requests | ||
serverPluginServeStatic_1.seenUrls.add(ctx.url); | ||
ctx.body = cached.content; | ||
@@ -36,0 +39,0 @@ } |
@@ -20,6 +20,10 @@ import { Context } from 'koa'; | ||
/** | ||
* Check if a request is an import from js (instead of fetch() or ajax requests) | ||
* A request qualifies as long as it's from one of the supported js source file | ||
* formats (vue,js,ts,jsx,tsx) | ||
* Check if a request is an import from js instead of a native resource request | ||
* i.e. differentiate | ||
* `import('/style.css')` | ||
* from | ||
* `<link rel="stylesheet" href="/style.css">` | ||
* | ||
* The ?import query is injected by serverPluginModuleRewrite. | ||
*/ | ||
export declare const isImportRequest: (ctx: Context) => boolean; |
@@ -45,16 +45,13 @@ "use strict"; | ||
}; | ||
const timeStampRE = /(&|\?)t=\d+/; | ||
const jsSrcFileRE = /\.(vue|jsx?|tsx?)$/; | ||
/** | ||
* Check if a request is an import from js (instead of fetch() or ajax requests) | ||
* A request qualifies as long as it's from one of the supported js source file | ||
* formats (vue,js,ts,jsx,tsx) | ||
* Check if a request is an import from js instead of a native resource request | ||
* i.e. differentiate | ||
* `import('/style.css')` | ||
* from | ||
* `<link rel="stylesheet" href="/style.css">` | ||
* | ||
* The ?import query is injected by serverPluginModuleRewrite. | ||
*/ | ||
exports.isImportRequest = (ctx) => { | ||
if (!ctx.accepts('js')) { | ||
return false; | ||
} | ||
// strip HMR timestamps | ||
const referer = ctx.get('referer').replace(timeStampRE, ''); | ||
return jsSrcFileRE.test(referer); | ||
return ctx.query.import != null; | ||
}; |
{ | ||
"name": "vite", | ||
"version": "0.14.2", | ||
"version": "0.14.3", | ||
"license": "MIT", | ||
@@ -28,9 +28,10 @@ "author": "Evan You", | ||
"scripts": { | ||
"dev": "run-p dev-client dev-node", | ||
"dev": "run-p dev-client dev-node dev-sw", | ||
"dev-client": "tsc -w --p src/client", | ||
"dev-node": "tsc -w --p src/node", | ||
"build": "rm -rf dist && tsc -p src/client && tsc -p src/node", | ||
"dev-sw": "tsc -w --p src/sw", | ||
"build": "rm -rf dist && tsc -p src/client && tsc -p src/node && tsc -p src/sw", | ||
"lint": "prettier --write --parser typescript \"src/**/*.ts\"", | ||
"test": "jest --clearCache && jest --runInBand", | ||
"windows-ci": "yarn build && jest --runInBand --forceExit", | ||
"test": "jest --clearCache && jest --runInBand --forceExit", | ||
"test-sw": "cross-env USE_SW=1 yarn test", | ||
"changelog": "conventional-changelog -p angular -i CHANGELOG.md -s", | ||
@@ -104,2 +105,3 @@ "prepublishOnly": "yarn build && yarn changelog", | ||
"conventional-changelog-cli": "^2.0.31", | ||
"cross-env": "^7.0.2", | ||
"jest": "^25.4.0", | ||
@@ -106,0 +108,0 @@ "lint-staged": "^10.1.6", |
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
194984
75
3683
24
27
3