From 6e413ba31b76889637bb9e2d105a7bcc8c85c576 Mon Sep 17 00:00:00 2001 From: Fran Dios Date: Wed, 1 Jun 2022 17:19:25 +0900 Subject: [PATCH 01/10] Stop using globalThis for logger and minor refactor --- packages/hydrogen/src/utilities/log/log.ts | 47 +++++++++------------- 1 file changed, 20 insertions(+), 27 deletions(-) diff --git a/packages/hydrogen/src/utilities/log/log.ts b/packages/hydrogen/src/utilities/log/log.ts index b87370b7e0..eef1a9d109 100644 --- a/packages/hydrogen/src/utilities/log/log.ts +++ b/packages/hydrogen/src/utilities/log/log.ts @@ -9,10 +9,6 @@ import {parseUrl} from './utils'; * current request in progress. */ -declare namespace globalThis { - let __logger: Logger; -} - export interface Logger { trace: (...args: Array) => void; debug: (...args: Array) => void; @@ -31,55 +27,52 @@ export type LoggerOptions = { export type RenderType = 'str' | 'rsc' | 'ssr' | 'api'; -const defaultLogger = { - trace(context: {[key: string]: any}, ...args: Array) { +type LoggerContext = Record; +export const defaultLogger = { + trace(context: LoggerContext, ...args: Array) { // Re-enable following line to show trace debugging information // console.log(context.id, ...args); }, - debug(context: {[key: string]: any}, ...args: Array) { + debug(context: LoggerContext, ...args: Array) { console.log(...args); }, - warn(context: {[key: string]: any}, ...args: Array) { + warn(context: LoggerContext, ...args: Array) { console.warn(yellow('WARN: '), ...args); }, - error(context: {[key: string]: any}, ...args: Array) { + error(context: LoggerContext, ...args: Array) { console.error(red('ERROR: '), ...args); }, - fatal(context: {[key: string]: any}, ...args: Array) { + fatal(context: LoggerContext, ...args: Array) { console.error(red('FATAL: '), ...args); }, - options: () => ({}), + options: () => ({} as LoggerOptions), }; -globalThis.__logger = defaultLogger as Logger; +let currentLogger = defaultLogger as Logger; -function buildLogger(this: any): Logger { +export function getLoggerWithContext(context: any): Logger { return { - trace: (...args) => globalThis.__logger.trace(this, ...args), - debug: (...args) => globalThis.__logger.debug(this, ...args), - warn: (...args) => globalThis.__logger.warn(this, ...args), - error: (...args) => globalThis.__logger.error(this, ...args), - fatal: (...args) => globalThis.__logger.fatal(this, ...args), - options: () => globalThis.__logger.options(), + trace: (...args) => currentLogger.trace(context, ...args), + debug: (...args) => currentLogger.debug(context, ...args), + warn: (...args) => currentLogger.warn(context, ...args), + error: (...args) => currentLogger.error(context, ...args), + fatal: (...args) => currentLogger.fatal(context, ...args), + options: () => currentLogger.options(), }; } -export const log: Logger = buildLogger.call({}); - -export function getLoggerWithContext(context: any = {}): Logger { - return buildLogger.call(context); -} +export const log: Logger = getLoggerWithContext({}); export function setLogger(newLogger: Logger) { - globalThis.__logger = newLogger; + currentLogger = newLogger; } export function setLoggerOptions(options: LoggerOptions) { - globalThis.__logger.options = () => options; + setLogger({...currentLogger, options: () => options}); } export function resetLogger() { - globalThis.__logger = defaultLogger; + currentLogger = defaultLogger; } const SERVER_RESPONSE_MAP: Record = { From 902cc8879b7c82eef08bdee97f987d55f5ce7dbf Mon Sep 17 00:00:00 2001 From: Fran Dios Date: Wed, 1 Jun 2022 18:21:17 +0900 Subject: [PATCH 02/10] Move logger options to Hydrogen config file --- packages/hydrogen/src/entry-server.tsx | 6 +++++- packages/hydrogen/src/index.ts | 2 +- packages/hydrogen/src/types.ts | 3 ++- packages/hydrogen/src/utilities/log/index.ts | 1 - packages/hydrogen/src/utilities/log/log.ts | 19 +++++++++++++------ 5 files changed, 21 insertions(+), 10 deletions(-) diff --git a/packages/hydrogen/src/entry-server.tsx b/packages/hydrogen/src/entry-server.tsx index adfdf69301..ad573b36c8 100644 --- a/packages/hydrogen/src/entry-server.tsx +++ b/packages/hydrogen/src/entry-server.tsx @@ -42,7 +42,7 @@ import { } from './streaming.server'; import {RSC_PATHNAME, EVENT_PATHNAME, EVENT_PATHNAME_REGEX} from './constants'; import {stripScriptsFromTemplate} from './utilities/template'; -import {RenderType} from './utilities/log/log'; +import {setLogger, RenderType} from './utilities/log/log'; import {Analytics} from './foundation/Analytics/Analytics.server'; import {ServerAnalyticsRoute} from './foundation/Analytics/ServerAnalyticsRoute.server'; import {getSyncSessionApi} from './foundation/session/session'; @@ -113,6 +113,10 @@ export const renderHydrogen = (App: any) => { request.ctx.hydrogenConfig = hydrogenConfig; request.ctx.buyerIpHeader = buyerIpHeader; + if (hydrogenConfig.logger) { + setLogger(hydrogenConfig.logger); + } + const response = new ServerComponentResponse(); const log = getLoggerWithContext(request); const sessionApi = hydrogenConfig.session diff --git a/packages/hydrogen/src/index.ts b/packages/hydrogen/src/index.ts index 7587edf92e..9a26f038ba 100644 --- a/packages/hydrogen/src/index.ts +++ b/packages/hydrogen/src/index.ts @@ -17,7 +17,7 @@ export * from './foundation/useServerProps'; export {FileRoutes} from './foundation/FileRoutes/FileRoutes.server'; export {Route} from './foundation/Route/Route.server'; export {Router} from './foundation/Router/Router.server'; -export {log, setLogger, setLoggerOptions, Logger} from './utilities/log'; +export {log, type Logger} from './utilities/log'; export {LocalizationProvider} from './components/LocalizationProvider/LocalizationProvider.server'; export {ShopifyProvider} from './foundation/ShopifyProvider/ShopifyProvider.server'; export { diff --git a/packages/hydrogen/src/types.ts b/packages/hydrogen/src/types.ts index 427d23587a..c081625789 100644 --- a/packages/hydrogen/src/types.ts +++ b/packages/hydrogen/src/types.ts @@ -1,5 +1,5 @@ import type {ServerResponse} from 'http'; -import type {Logger} from './utilities/log/log'; +import type {Logger, LoggerConfig} from './utilities/log/log'; import type {ServerComponentRequest} from './framework/Hydration/ServerComponentRequest.server'; import type {ServerComponentResponse} from './framework/Hydration/ServerComponentResponse.server'; import type { @@ -84,6 +84,7 @@ export type InlineHydrogenConfig = { routes?: InlineHydrogenRoutes; shopify?: ShopifyConfig | ShopifyConfigFetcher; serverAnalyticsConnectors?: Array; + logger?: LoggerConfig; session?: (log: Logger) => SessionStorageAdapter; enableStreaming?: (request: ServerComponentRequest) => boolean; }; diff --git a/packages/hydrogen/src/utilities/log/index.ts b/packages/hydrogen/src/utilities/log/index.ts index 85d52a95d6..d1eedc7b4c 100644 --- a/packages/hydrogen/src/utilities/log/index.ts +++ b/packages/hydrogen/src/utilities/log/index.ts @@ -1,7 +1,6 @@ export { log, setLogger, - setLoggerOptions, getLoggerWithContext, Logger, logServerResponse, diff --git a/packages/hydrogen/src/utilities/log/log.ts b/packages/hydrogen/src/utilities/log/log.ts index eef1a9d109..de7b4fb5c8 100644 --- a/packages/hydrogen/src/utilities/log/log.ts +++ b/packages/hydrogen/src/utilities/log/log.ts @@ -25,10 +25,12 @@ export type LoggerOptions = { showUnusedQueryProperties?: boolean; }; +export type LoggerConfig = Partial> & LoggerOptions; + export type RenderType = 'str' | 'rsc' | 'ssr' | 'api'; type LoggerContext = Record; -export const defaultLogger = { +const defaultLogger = { trace(context: LoggerContext, ...args: Array) { // Re-enable following line to show trace debugging information // console.log(context.id, ...args); @@ -63,14 +65,19 @@ export function getLoggerWithContext(context: any): Logger { export const log: Logger = getLoggerWithContext({}); -export function setLogger(newLogger: Logger) { - currentLogger = newLogger; -} +export function setLogger(config: LoggerConfig) { + const options = {} as LoggerOptions; + currentLogger = {...defaultLogger, ...config, options: () => options}; -export function setLoggerOptions(options: LoggerOptions) { - setLogger({...currentLogger, options: () => options}); + for (const key of Object.keys(config) as (keyof LoggerOptions)[]) { + if (!(key in defaultLogger)) { + delete currentLogger[key as keyof Logger]; + options[key] = config[key]; + } + } } +// For tests export function resetLogger() { currentLogger = defaultLogger; } From 497b6084ec6bf1df6f4e0c9ae6814d8c86222f10 Mon Sep 17 00:00:00 2001 From: Fran Dios Date: Wed, 1 Jun 2022 18:23:08 +0900 Subject: [PATCH 03/10] Update unit tests --- .../__tests__/log-cache-api-status.test.ts | 13 ++-------- .../log/__tests__/log-cache-header.test.ts | 6 +---- .../log/__tests__/log-query-timeline.test.ts | 7 ++---- .../src/utilities/log/__tests__/log.test.ts | 24 ++++++++----------- 4 files changed, 15 insertions(+), 35 deletions(-) diff --git a/packages/hydrogen/src/utilities/log/__tests__/log-cache-api-status.test.ts b/packages/hydrogen/src/utilities/log/__tests__/log-cache-api-status.test.ts index 6b6a1ee2ae..2961d30be3 100644 --- a/packages/hydrogen/src/utilities/log/__tests__/log-cache-api-status.test.ts +++ b/packages/hydrogen/src/utilities/log/__tests__/log-cache-api-status.test.ts @@ -1,10 +1,4 @@ -import { - Logger, - setLogger, - logCacheApiStatus, - resetLogger, - setLoggerOptions, -} from '../index'; +import {Logger, setLogger, logCacheApiStatus, resetLogger} from '../index'; let mockLogger: jest.Mocked; @@ -19,10 +13,7 @@ describe('cache header log', () => { options: jest.fn(() => ({})), }; - setLogger(mockLogger); - setLoggerOptions({ - showCacheApiStatus: true, - }); + setLogger({...mockLogger, showCacheApiStatus: true}); }); afterEach(() => { diff --git a/packages/hydrogen/src/utilities/log/__tests__/log-cache-header.test.ts b/packages/hydrogen/src/utilities/log/__tests__/log-cache-header.test.ts index d22a9fe5dd..04bd9f6cbe 100644 --- a/packages/hydrogen/src/utilities/log/__tests__/log-cache-header.test.ts +++ b/packages/hydrogen/src/utilities/log/__tests__/log-cache-header.test.ts @@ -4,7 +4,6 @@ import { logCacheControlHeaders, collectQueryCacheControlHeaders, resetLogger, - setLoggerOptions, } from '../index'; import {ServerComponentRequest} from '../../../framework/Hydration/ServerComponentRequest.server'; import {ServerComponentResponse} from '../../../framework/Hydration/ServerComponentResponse.server'; @@ -26,10 +25,7 @@ describe('cache header log', () => { options: jest.fn(() => ({})), }; - setLogger(mockLogger); - setLoggerOptions({ - showCacheControlHeader: true, - }); + setLogger({...mockLogger, showCacheControlHeader: true}); }); afterEach(() => { diff --git a/packages/hydrogen/src/utilities/log/__tests__/log-query-timeline.test.ts b/packages/hydrogen/src/utilities/log/__tests__/log-query-timeline.test.ts index c138f26e8c..6097134f26 100644 --- a/packages/hydrogen/src/utilities/log/__tests__/log-query-timeline.test.ts +++ b/packages/hydrogen/src/utilities/log/__tests__/log-query-timeline.test.ts @@ -1,5 +1,5 @@ import {ServerComponentRequest} from '../../../framework/Hydration/ServerComponentRequest.server'; -import {Logger, setLogger, resetLogger, setLoggerOptions} from '../index'; +import {Logger, setLogger, resetLogger} from '../log'; import {collectQueryTimings, logQueryTimings} from '../log-query-timeline'; let mockLogger: jest.Mocked; @@ -36,10 +36,7 @@ describe('cache header log', () => { options: jest.fn(() => ({})), }; - setLogger(mockLogger); - setLoggerOptions({ - showQueryTiming: true, - }); + setLogger({...mockLogger, showQueryTiming: true}); }); afterEach(() => { diff --git a/packages/hydrogen/src/utilities/log/__tests__/log.test.ts b/packages/hydrogen/src/utilities/log/__tests__/log.test.ts index d11c64a958..918defdcc5 100644 --- a/packages/hydrogen/src/utilities/log/__tests__/log.test.ts +++ b/packages/hydrogen/src/utilities/log/__tests__/log.test.ts @@ -7,7 +7,6 @@ import { resetLogger, } from '../log'; import {ServerComponentRequest} from '../../../framework/Hydration/ServerComponentRequest.server'; -import {setLoggerOptions} from '..'; let mockLogger: jest.Mocked; @@ -47,11 +46,10 @@ describe('log', () => { warn: jest.fn(), error: jest.fn(), fatal: jest.fn(), - options: jest.fn(() => ({ - showCacheControlHeader: true, - })), + options: jest.fn(() => ({})), }; - setLogger(mockLogger2); + + setLogger({...mockLogger2, showCacheControlHeader: true}); log.debug('test'); expect(mockLogger2.debug).toHaveBeenCalled(); @@ -62,17 +60,15 @@ describe('log', () => { expect(mockLogger2.debug.mock.calls[0][1]).toEqual('test'); }); - it('should set showCacheControlHeader option when setLoggerOptions is called', () => { - setLoggerOptions({ - showCacheControlHeader: true, - }); + it('should set showCacheControlHeader option correctly', () => { + setLogger({showCacheControlHeader: true}); expect(log.options()).toEqual({ showCacheControlHeader: true, }); }); - it('should set showCacheApiStatus option when setLoggerOptions is called', () => { - setLoggerOptions({ + it('should set showCacheApiStatus option correctly', () => { + setLogger({ showCacheApiStatus: true, }); expect(log.options()).toEqual({ @@ -80,14 +76,14 @@ describe('log', () => { }); }); - it('should return the correct options when setLoggerOptions is set multiple times', () => { - setLoggerOptions({ + it('should set multiple options correctly', () => { + setLogger({ showCacheControlHeader: true, }); expect(log.options()).toEqual({ showCacheControlHeader: true, }); - setLoggerOptions({ + setLogger({ showCacheApiStatus: true, showCacheControlHeader: true, }); From 471abb5675d9fbf032de9e4bf29178917bdf507f Mon Sep 17 00:00:00 2001 From: Fran Dios Date: Wed, 1 Jun 2022 18:27:08 +0900 Subject: [PATCH 04/10] Remove setLogger call from e2e tests --- .../async-config/hydrogen.config.js | 4 ++++ .../async-config/src/App.server.jsx | 23 +------------------ .../server-components/hydrogen.config.js | 4 ++++ .../server-components/src/App.server.jsx | 23 +------------------ 4 files changed, 10 insertions(+), 44 deletions(-) diff --git a/packages/playground/async-config/hydrogen.config.js b/packages/playground/async-config/hydrogen.config.js index 5c0b1ea803..8a27083968 100644 --- a/packages/playground/async-config/hydrogen.config.js +++ b/packages/playground/async-config/hydrogen.config.js @@ -16,4 +16,8 @@ export default defineConfig({ storefrontApiVersion: '2022-07', }; }, + logger: { + trace() {}, + debug() {}, + }, }); diff --git a/packages/playground/async-config/src/App.server.jsx b/packages/playground/async-config/src/App.server.jsx index 0a45c54cd5..b1cd8b62c5 100644 --- a/packages/playground/async-config/src/App.server.jsx +++ b/packages/playground/async-config/src/App.server.jsx @@ -1,28 +1,7 @@ import renderHydrogen from '@shopify/hydrogen/entry-server'; -import { - Router, - FileRoutes, - ShopifyProvider, - setLogger, - useUrl, -} from '@shopify/hydrogen'; +import {Router, FileRoutes, ShopifyProvider, useUrl} from '@shopify/hydrogen'; import {Suspense} from 'react'; -setLogger({ - trace() {}, - debug() {}, - warn(context, ...args) { - console.warn(...args); - }, - error(context, ...args) { - console.error(...args); - }, - fatal(context, ...args) { - console.error(...args); - }, - options: () => ({}), -}); - let localeRedirects; const handleRequest = renderHydrogen(({response}) => { diff --git a/packages/playground/server-components/hydrogen.config.js b/packages/playground/server-components/hydrogen.config.js index 532110a3b8..fb8e045c47 100644 --- a/packages/playground/server-components/hydrogen.config.js +++ b/packages/playground/server-components/hydrogen.config.js @@ -14,4 +14,8 @@ export default defineConfig({ enableStreaming: (req) => { return req.headers.get('user-agent') !== 'custom bot'; }, + logger: { + trace() {}, + debug() {}, + }, }); diff --git a/packages/playground/server-components/src/App.server.jsx b/packages/playground/server-components/src/App.server.jsx index 0daa8e181b..5627804a2f 100644 --- a/packages/playground/server-components/src/App.server.jsx +++ b/packages/playground/server-components/src/App.server.jsx @@ -1,32 +1,11 @@ import renderHydrogen from '@shopify/hydrogen/entry-server'; -import { - Route, - Router, - FileRoutes, - ShopifyProvider, - setLogger, -} from '@shopify/hydrogen'; +import {Route, Router, FileRoutes, ShopifyProvider} from '@shopify/hydrogen'; import {Suspense} from 'react'; import Custom1 from './customRoutes/custom1.server'; import Custom2 from './customRoutes/custom2.server'; import LazyRoute from './customRoutes/lazyRoute.server'; import ServerParams from './customRoutes/params.server'; -setLogger({ - trace() {}, - debug() {}, - warn(context, ...args) { - console.warn(...args); - }, - error(context, ...args) { - console.error(...args); - }, - fatal(context, ...args) { - console.error(...args); - }, - options: () => ({}), -}); - export default renderHydrogen(() => { return ( From 8000035c79ea1fa5178c884af781b53082029b55 Mon Sep 17 00:00:00 2001 From: Fran Dios Date: Wed, 1 Jun 2022 18:35:47 +0900 Subject: [PATCH 05/10] Always call setLogger for HMR --- packages/hydrogen/src/entry-server.tsx | 6 ++---- .../log/__tests__/log-cache-api-status.test.ts | 4 ++-- .../utilities/log/__tests__/log-cache-header.test.ts | 3 +-- .../log/__tests__/log-query-timeline.test.ts | 4 ++-- .../hydrogen/src/utilities/log/__tests__/log.test.ts | 3 +-- packages/hydrogen/src/utilities/log/index.ts | 1 - packages/hydrogen/src/utilities/log/log.ts | 12 ++++++------ 7 files changed, 14 insertions(+), 19 deletions(-) diff --git a/packages/hydrogen/src/entry-server.tsx b/packages/hydrogen/src/entry-server.tsx index ad573b36c8..c2c04af58b 100644 --- a/packages/hydrogen/src/entry-server.tsx +++ b/packages/hydrogen/src/entry-server.tsx @@ -113,12 +113,10 @@ export const renderHydrogen = (App: any) => { request.ctx.hydrogenConfig = hydrogenConfig; request.ctx.buyerIpHeader = buyerIpHeader; - if (hydrogenConfig.logger) { - setLogger(hydrogenConfig.logger); - } + setLogger(hydrogenConfig.logger); + const log = getLoggerWithContext(request); const response = new ServerComponentResponse(); - const log = getLoggerWithContext(request); const sessionApi = hydrogenConfig.session ? hydrogenConfig.session(log) : undefined; diff --git a/packages/hydrogen/src/utilities/log/__tests__/log-cache-api-status.test.ts b/packages/hydrogen/src/utilities/log/__tests__/log-cache-api-status.test.ts index 2961d30be3..6da35b1dbf 100644 --- a/packages/hydrogen/src/utilities/log/__tests__/log-cache-api-status.test.ts +++ b/packages/hydrogen/src/utilities/log/__tests__/log-cache-api-status.test.ts @@ -1,4 +1,4 @@ -import {Logger, setLogger, logCacheApiStatus, resetLogger} from '../index'; +import {Logger, setLogger, logCacheApiStatus} from '../index'; let mockLogger: jest.Mocked; @@ -17,7 +17,7 @@ describe('cache header log', () => { }); afterEach(() => { - resetLogger(); + setLogger(undefined); }); it('should log cache api status', () => { diff --git a/packages/hydrogen/src/utilities/log/__tests__/log-cache-header.test.ts b/packages/hydrogen/src/utilities/log/__tests__/log-cache-header.test.ts index 04bd9f6cbe..1590b5bec5 100644 --- a/packages/hydrogen/src/utilities/log/__tests__/log-cache-header.test.ts +++ b/packages/hydrogen/src/utilities/log/__tests__/log-cache-header.test.ts @@ -3,7 +3,6 @@ import { setLogger, logCacheControlHeaders, collectQueryCacheControlHeaders, - resetLogger, } from '../index'; import {ServerComponentRequest} from '../../../framework/Hydration/ServerComponentRequest.server'; import {ServerComponentResponse} from '../../../framework/Hydration/ServerComponentResponse.server'; @@ -29,7 +28,7 @@ describe('cache header log', () => { }); afterEach(() => { - resetLogger(); + setLogger(undefined); }); it('should log cache control header for main request', () => { diff --git a/packages/hydrogen/src/utilities/log/__tests__/log-query-timeline.test.ts b/packages/hydrogen/src/utilities/log/__tests__/log-query-timeline.test.ts index 6097134f26..77b46e5970 100644 --- a/packages/hydrogen/src/utilities/log/__tests__/log-query-timeline.test.ts +++ b/packages/hydrogen/src/utilities/log/__tests__/log-query-timeline.test.ts @@ -1,5 +1,5 @@ import {ServerComponentRequest} from '../../../framework/Hydration/ServerComponentRequest.server'; -import {Logger, setLogger, resetLogger} from '../log'; +import {Logger, setLogger} from '../log'; import {collectQueryTimings, logQueryTimings} from '../log-query-timeline'; let mockLogger: jest.Mocked; @@ -40,7 +40,7 @@ describe('cache header log', () => { }); afterEach(() => { - resetLogger(); + setLogger(undefined); }); it('should log query timing', () => { diff --git a/packages/hydrogen/src/utilities/log/__tests__/log.test.ts b/packages/hydrogen/src/utilities/log/__tests__/log.test.ts index 918defdcc5..03302a51ee 100644 --- a/packages/hydrogen/src/utilities/log/__tests__/log.test.ts +++ b/packages/hydrogen/src/utilities/log/__tests__/log.test.ts @@ -4,7 +4,6 @@ import { Logger, logServerResponse, getLoggerWithContext, - resetLogger, } from '../log'; import {ServerComponentRequest} from '../../../framework/Hydration/ServerComponentRequest.server'; @@ -28,7 +27,7 @@ describe('log', () => { }); afterEach(() => { - resetLogger(); + setLogger(undefined); }); it('should return the wrapped mockLogger instance when log is called', () => { diff --git a/packages/hydrogen/src/utilities/log/index.ts b/packages/hydrogen/src/utilities/log/index.ts index d1eedc7b4c..c5821679b3 100644 --- a/packages/hydrogen/src/utilities/log/index.ts +++ b/packages/hydrogen/src/utilities/log/index.ts @@ -4,7 +4,6 @@ export { getLoggerWithContext, Logger, logServerResponse, - resetLogger, } from './log'; export { collectQueryCacheControlHeaders, diff --git a/packages/hydrogen/src/utilities/log/log.ts b/packages/hydrogen/src/utilities/log/log.ts index de7b4fb5c8..b8fc8844be 100644 --- a/packages/hydrogen/src/utilities/log/log.ts +++ b/packages/hydrogen/src/utilities/log/log.ts @@ -65,7 +65,12 @@ export function getLoggerWithContext(context: any): Logger { export const log: Logger = getLoggerWithContext({}); -export function setLogger(config: LoggerConfig) { +export function setLogger(config?: LoggerConfig) { + if (!config) { + currentLogger = defaultLogger; + return; + } + const options = {} as LoggerOptions; currentLogger = {...defaultLogger, ...config, options: () => options}; @@ -77,11 +82,6 @@ export function setLogger(config: LoggerConfig) { } } -// For tests -export function resetLogger() { - currentLogger = defaultLogger; -} - const SERVER_RESPONSE_MAP: Record = { str: 'streaming SSR', rsc: 'Server Components', From 3c6ea40bca2eb7eca1bbabea5933cec6193c4e78 Mon Sep 17 00:00:00 2001 From: Fran Dios Date: Wed, 1 Jun 2022 18:41:54 +0900 Subject: [PATCH 06/10] Remove unnecessary type --- packages/hydrogen/src/utilities/log/log.ts | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/packages/hydrogen/src/utilities/log/log.ts b/packages/hydrogen/src/utilities/log/log.ts index b8fc8844be..dc72ec1b85 100644 --- a/packages/hydrogen/src/utilities/log/log.ts +++ b/packages/hydrogen/src/utilities/log/log.ts @@ -29,22 +29,21 @@ export type LoggerConfig = Partial> & LoggerOptions; export type RenderType = 'str' | 'rsc' | 'ssr' | 'api'; -type LoggerContext = Record; -const defaultLogger = { - trace(context: LoggerContext, ...args: Array) { +const defaultLogger: Logger = { + trace(context, ...args) { // Re-enable following line to show trace debugging information // console.log(context.id, ...args); }, - debug(context: LoggerContext, ...args: Array) { + debug(context, ...args) { console.log(...args); }, - warn(context: LoggerContext, ...args: Array) { + warn(context, ...args) { console.warn(yellow('WARN: '), ...args); }, - error(context: LoggerContext, ...args: Array) { + error(context, ...args) { console.error(red('ERROR: '), ...args); }, - fatal(context: LoggerContext, ...args: Array) { + fatal(context, ...args) { console.error(red('FATAL: '), ...args); }, options: () => ({} as LoggerOptions), From 4ec95b9dc6a8b66db3b52e1c19f5b4d2c841e801 Mon Sep 17 00:00:00 2001 From: Fran Dios Date: Wed, 1 Jun 2022 19:16:17 +0900 Subject: [PATCH 07/10] Add docs --- docs/framework/cache.md | 40 +------------------- docs/framework/hydrogen-config.md | 32 ++++++++++++++++ docs/framework/preloaded-queries.md | 16 +------- docs/utilities/log.md | 57 ++--------------------------- 4 files changed, 40 insertions(+), 105 deletions(-) diff --git a/docs/framework/cache.md b/docs/framework/cache.md index 14aabd0082..60257982ec 100644 --- a/docs/framework/cache.md +++ b/docs/framework/cache.md @@ -152,25 +152,7 @@ export default defineConfig({ {% endcodeblock %} -To enable logging for the cache API status, call `setLoggerOptions` and set `showCacheApiStatus` to `true`: - -{% codeblock file, filename: '/src/App.server.jsx' %} - -```js -import renderHydrogen from '@shopify/hydrogen/entry-server'; -import {setLoggerOptions} from '@shopify/hydrogen'; - -setLoggerOptions({showCacheApiStatus: true}); - -function App() { - /* ... */ -} -// ... -``` - -{% endcodeblock %} - -The status of the cache updates on each query: +To enable logging for the cache API status, set `logger.showCacheApiStatus` to `true` in [Hydrogen config](https://shopify.dev/custom-storefronts/hydrogen/framework/hydrogen-config#logger). The status of the cache updates on each query: ```sh [Cache] MISS query shopInfo @@ -179,25 +161,7 @@ The status of the cache updates on each query: [Cache] MISS query Localization ``` -To enable logging for cache control headers, call `setLoggerOptions` and set `showCacheControlHeader` to `true`: - -{% codeblock file, filename: '/src/App.server.jsx' %} - -```js -import renderHydrogen from '@shopify/hydrogen/entry-server'; -import {setLoggerOptions} from '@shopify/hydrogen'; - -setLoggerOptions({showCacheControlHeader: true}); - -function App() { - /* ... */ -} -// ... -``` - -{% endcodeblock %} - -A cache control header report displays for each page request. The report includes the associated queries +To enable logging for cache control headers, set `logger.showCacheControlHeader` to `true` in [Hydrogen config](https://shopify.dev/custom-storefronts/hydrogen/framework/react-server-components). A cache control header report displays for each page request. The report includes the associated queries that built the request and the cache control headers: ```sh diff --git a/docs/framework/hydrogen-config.md b/docs/framework/hydrogen-config.md index ef9ded5a50..11e8a89f8c 100644 --- a/docs/framework/hydrogen-config.md +++ b/docs/framework/hydrogen-config.md @@ -44,6 +44,7 @@ The following groupings of configuration properties can exist in Hydrogen: - [`session`](#session) - [`serverAnalyticsConnectors`](#serveranalyticsconnectors) - [`enableStreaming`](#enablestreaming) +- [`logger`](#logger) ### `routes` @@ -209,6 +210,37 @@ export default defineConfig({ > Tip: > There are [performance benefits](https://shopify.dev/custom-storefronts/hydrogen/best-practices/performance) to streaming. You shouldn't completely disable streaming for all of your storefront's routes. +## Logger + +The [`log` utility](https://shopify.dev/api/hydrogen/utilities/log)'s default behavior is mapping to the global `console` object. However, this behavior can be customized in the configuration object. + +Pass [any method](https://shopify.dev/api/hydrogen/utilities/log#methods) of the `log` utility in the `logger` object to override it. The first argument of each log method will contain a `request` object if the log was called in the same context as a request. Aside from that, the following boolean options are also available: + +{% codeblock file, filename: 'hydrogen.config.ts' %} + +```tsx +export default defineConfig({ + logger: { + /* Overrides the default `log.trace` behavior */ + trace: (request, ...args) => console.log(request.url, ...args), + /* Overrides the default `log.error` behavior */ + error: (request, error) => myErrorTrackingService.send(error, {request}), + /* ... */ + + /* Logs the cache status of each stored entry: `PUT`, `HIT`, `MISS` or `STALE`. */ + showCacheApiStatus: true, + /* Logs the cache control headers of the main document and its sub queries. */ + showCacheControlHeader: true, + /* Logs the timeline of when queries are being requested, resolved, and rendered. */ + showQueryTiming: true, + /* Logs warnings in your app if you're over-fetching data from the Storefront API. */ + showUnusedQueryProperties: true, + } +}); +``` + +{% endcodeblock %} + ## Changing the configuration file location If you don't want the Hydrogen configuration file located at the root of your project, then you can provide the new path to the file in the Hydrogen Vite plugin (`vite.config.js`): diff --git a/docs/framework/preloaded-queries.md b/docs/framework/preloaded-queries.md index 17270e319d..94f76fec92 100644 --- a/docs/framework/preloaded-queries.md +++ b/docs/framework/preloaded-queries.md @@ -101,21 +101,9 @@ const data = fetchSync('https://my.api.com/data.json', { ## Test a preloaded query -To test a preloaded query, enable the `showQueryTiming` property in `App.server.js`. The [`showQueryTiming`](https://shopify.dev/api/hydrogen/utilities/log#logger-options) property logs the timeline of when queries are being requested, resolved, and rendered. +To test a preloaded query, enable the `logger.showQueryTiming` property in [Hydrogen config](https://shopify.dev/custom-storefronts/hydrogen/framework/hydrogen-config#logger). -{% codeblock file, filename: "App.server.js" %} - -```js -import {setLoggerOptions} from '@shopify/hydrogen'; -... -setLoggerOptions({ - showQueryTiming: true -}) -``` - -{% endcodeblock %} - -If a query is preloaded, but isn't being used, then a warning displays in the server log: +The [`showQueryTiming`](https://shopify.dev/api/hydrogen/utilities/log#logger-options) property logs the timeline of when queries are being requested, resolved, and rendered. If a query is preloaded, but isn't being used, then a warning displays in the server log: ![Shows a screenshot of preloaded query warning](/assets/custom-storefronts/hydrogen/preload-query-warning.png) diff --git a/docs/utilities/log.md b/docs/utilities/log.md index 487d408d48..a522c52d35 100644 --- a/docs/utilities/log.md +++ b/docs/utilities/log.md @@ -22,13 +22,9 @@ export default function Product({country = {isoCode: 'US'}, log}) { } ``` -## Arguments +## Methods -None - -## Return type - -Return an object with methods for logging information at different priorities: +The `log` utility exposes the following methods for logging information at different priorities: | Log method | Description | | ------------- | --------------------------------------------------------------------------------- | @@ -38,52 +34,7 @@ Return an object with methods for logging information at different priorities: | `log.error()` | The logging used for errors or invalid application state. | | `log.fatal()` | The logging used just prior to the process exiting. | -## Logger options - -Logger has the following Boolean options: +## Swap logger implementation and options -| Option | Description | -| --------------------------- | ------------------------------------------------------------------------------- | -| `showCacheApiStatus` | Logs the cache status of each stored entry: `PUT`, `HIT`, `MISS` or `STALE`. | -| `showCacheControlHeader` | Logs the cache control headers of the main document and its sub queries. | -| `showQueryTiming` | Logs the timeline of when queries are being requested, resolved, and rendered. | -| `showUnusedQueryProperties` | Logs warnings in your app if you're over-fetching data from the Storefront API. | +Hydrogen includes a default logger implementation that can be swapped for a logger of your choice. It is also possible to show debug information for cache and queries by providing extra options. See [Hydrogen config](https://shopify.dev/custom-storefronts/hydrogen/framework/hydrogen-config#logger) for more information. -### Example - -```js -import {setLoggerOptions} from '@shopify/hydrogen'; - -setLoggerOptions({ - showCacheApiStatus: true, - showCacheControlHeader: true, - showQueryTiming: true, - showUnusedQueryProperties: true, -}); -``` - -## Swap logger implementation - -Hydrogen includes a default logger implementation that can be swapped for a logger of your choice. You can call `setLogger` with your own implementation. The first argument of each log method will contain a `request` object if the log was called in the same context as a request: - -```js -import {setLogger} from '@shopify/hydrogen'; - -setLogger({ - trace(request, ...args) { - // Call your own logger. - }, - debug(request, ...args) { - // Call your own logger. - }, - warn(request, ...args) { - // Call your own logger. - }, - error(request, ...args) { - // Call your own logger. - }, - fatal(request, ...args) { - // Call your own logger. - }, -}); -``` From 7868869fca0ea8eba279737e740cb865f226ce50 Mon Sep 17 00:00:00 2001 From: Fran Dios Date: Wed, 1 Jun 2022 19:22:12 +0900 Subject: [PATCH 08/10] Changeset --- .changeset/rotten-nails-complain.md | 44 +++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 .changeset/rotten-nails-complain.md diff --git a/.changeset/rotten-nails-complain.md b/.changeset/rotten-nails-complain.md new file mode 100644 index 0000000000..f3eb3d0689 --- /dev/null +++ b/.changeset/rotten-nails-complain.md @@ -0,0 +1,44 @@ +--- +'@shopify/hydrogen': minor +--- + +The `setLogger` and `setLoggerOptions` utilities have been removed. The same information can now be passed under the `logger` property in Hydrogen config: + +```diff +// App.server.jsx + +-import {setLogger, setLoggerOptions} from '@shopify/hydrogen'; + +-setLogger({ +- trace() {}, +- error() {}, +- // ... +-}); + +-setLoggerOptions({ +- showQueryTiming: true, +- showCacheControlHeader: true, +- // ... +-}); + +function App() { + // ... +} + +export default renderHydrogen(App); +``` + +```diff +// hydrogen.config.js + +export default defineConfig({ + // ... ++ logger: { ++ trace() {}, ++ error() {}, ++ showQueryTiming: true, ++ showCacheControlHeader: true, ++ // ... ++ }, +}); +``` From 724b99c963d87cc4bf9e7d136d552a912020fccf Mon Sep 17 00:00:00 2001 From: Fran Dios Date: Wed, 1 Jun 2022 19:33:12 +0900 Subject: [PATCH 09/10] Fix link --- docs/framework/cache.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/framework/cache.md b/docs/framework/cache.md index 60257982ec..ff92f88cd9 100644 --- a/docs/framework/cache.md +++ b/docs/framework/cache.md @@ -161,7 +161,7 @@ To enable logging for the cache API status, set `logger.showCacheApiStatus` to ` [Cache] MISS query Localization ``` -To enable logging for cache control headers, set `logger.showCacheControlHeader` to `true` in [Hydrogen config](https://shopify.dev/custom-storefronts/hydrogen/framework/react-server-components). A cache control header report displays for each page request. The report includes the associated queries +To enable logging for cache control headers, set `logger.showCacheControlHeader` to `true` in [Hydrogen config](https://shopify.dev/custom-storefronts/hydrogen/framework/hydrogen-config#logger). A cache control header report displays for each page request. The report includes the associated queries that built the request and the cache control headers: ```sh From 1e402d725c2d0dff1c4e87baccd038d8c64dca8d Mon Sep 17 00:00:00 2001 From: Fran Dios Date: Thu, 2 Jun 2022 11:39:07 +0900 Subject: [PATCH 10/10] Apply suggestions from code review Co-authored-by: Michelle Vinci --- docs/framework/cache.md | 4 ++-- docs/framework/hydrogen-config.md | 8 ++++---- docs/framework/preloaded-queries.md | 2 +- docs/utilities/log.md | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/framework/cache.md b/docs/framework/cache.md index ff92f88cd9..231d6af3ff 100644 --- a/docs/framework/cache.md +++ b/docs/framework/cache.md @@ -152,7 +152,7 @@ export default defineConfig({ {% endcodeblock %} -To enable logging for the cache API status, set `logger.showCacheApiStatus` to `true` in [Hydrogen config](https://shopify.dev/custom-storefronts/hydrogen/framework/hydrogen-config#logger). The status of the cache updates on each query: +To enable logging for the cache API status, set `logger.showCacheApiStatus` to `true` in your [Hydrogen configuration file](https://shopify.dev/custom-storefronts/hydrogen/framework/hydrogen-config#logger). The status of the cache updates on each query: ```sh [Cache] MISS query shopInfo @@ -161,7 +161,7 @@ To enable logging for the cache API status, set `logger.showCacheApiStatus` to ` [Cache] MISS query Localization ``` -To enable logging for cache control headers, set `logger.showCacheControlHeader` to `true` in [Hydrogen config](https://shopify.dev/custom-storefronts/hydrogen/framework/hydrogen-config#logger). A cache control header report displays for each page request. The report includes the associated queries +To enable logging for cache control headers, set `logger.showCacheControlHeader` to `true` in your [Hydrogen configuration file](https://shopify.dev/custom-storefronts/hydrogen/framework/hydrogen-config#logger). A cache control header report displays for each page request. The report includes the associated queries that built the request and the cache control headers: ```sh diff --git a/docs/framework/hydrogen-config.md b/docs/framework/hydrogen-config.md index 11e8a89f8c..a291037b5e 100644 --- a/docs/framework/hydrogen-config.md +++ b/docs/framework/hydrogen-config.md @@ -212,18 +212,18 @@ export default defineConfig({ ## Logger -The [`log` utility](https://shopify.dev/api/hydrogen/utilities/log)'s default behavior is mapping to the global `console` object. However, this behavior can be customized in the configuration object. +The default behavior of the [`log` utility](https://shopify.dev/api/hydrogen/utilities/log) maps to the global `console` object. However, you can also customize this behavior in the configuration object. -Pass [any method](https://shopify.dev/api/hydrogen/utilities/log#methods) of the `log` utility in the `logger` object to override it. The first argument of each log method will contain a `request` object if the log was called in the same context as a request. Aside from that, the following boolean options are also available: +You can pass [any method](https://shopify.dev/api/hydrogen/utilities/log#methods) of the `log` utility in the `logger` object to override the default behavior. The first argument of each log method contains a `request` object if the log was called in the same context as a request. The following Boolean options are also available: {% codeblock file, filename: 'hydrogen.config.ts' %} ```tsx export default defineConfig({ logger: { - /* Overrides the default `log.trace` behavior */ + /* Overrides the default `log.trace` behavior. */ trace: (request, ...args) => console.log(request.url, ...args), - /* Overrides the default `log.error` behavior */ + /* Overrides the default `log.error` behavior. */ error: (request, error) => myErrorTrackingService.send(error, {request}), /* ... */ diff --git a/docs/framework/preloaded-queries.md b/docs/framework/preloaded-queries.md index 94f76fec92..113eac890d 100644 --- a/docs/framework/preloaded-queries.md +++ b/docs/framework/preloaded-queries.md @@ -101,7 +101,7 @@ const data = fetchSync('https://my.api.com/data.json', { ## Test a preloaded query -To test a preloaded query, enable the `logger.showQueryTiming` property in [Hydrogen config](https://shopify.dev/custom-storefronts/hydrogen/framework/hydrogen-config#logger). +To test a preloaded query, enable the `logger.showQueryTiming` property in your [Hydrogen configuration file](https://shopify.dev/custom-storefronts/hydrogen/framework/hydrogen-config#logger). The [`showQueryTiming`](https://shopify.dev/api/hydrogen/utilities/log#logger-options) property logs the timeline of when queries are being requested, resolved, and rendered. If a query is preloaded, but isn't being used, then a warning displays in the server log: diff --git a/docs/utilities/log.md b/docs/utilities/log.md index a522c52d35..f1604a388e 100644 --- a/docs/utilities/log.md +++ b/docs/utilities/log.md @@ -36,5 +36,5 @@ The `log` utility exposes the following methods for logging information at diffe ## Swap logger implementation and options -Hydrogen includes a default logger implementation that can be swapped for a logger of your choice. It is also possible to show debug information for cache and queries by providing extra options. See [Hydrogen config](https://shopify.dev/custom-storefronts/hydrogen/framework/hydrogen-config#logger) for more information. +Hydrogen includes a default logger implementation that can be swapped for a logger of your choice. You can also show debugging information for cache and queries by providing extra options. For more information, refer to [Hydrogen configuration](https://shopify.dev/custom-storefronts/hydrogen/framework/hydrogen-config#logger).