diff --git a/packages/gatsby/package.json b/packages/gatsby/package.json index 27bbcb3071bce..923197e185d15 100644 --- a/packages/gatsby/package.json +++ b/packages/gatsby/package.json @@ -143,6 +143,7 @@ "st": "^2.0.0", "stack-trace": "^0.0.10", "string-similarity": "^1.2.2", + "strip-ansi": "^5.2.0", "style-loader": "^0.23.1", "terminal-link": "^2.1.1", "terser-webpack-plugin": "^2.3.8", diff --git a/packages/gatsby/src/services/initialize.ts b/packages/gatsby/src/services/initialize.ts index e6666fc84c5ee..de31ff0645e43 100644 --- a/packages/gatsby/src/services/initialize.ts +++ b/packages/gatsby/src/services/initialize.ts @@ -65,20 +65,14 @@ if ( sampleSiteForExperiment(`DEV_SSR`, 5) ) { showExperimentNoticeAfterTimeout( - `devSSR`, - ` -Your dev experience is about to get better, faster, and stronger! - -We'll soon be shipping support for SSR in development. - -This will help the dev environment more closely mimic builds so you'll catch build errors earlier and fix them faster. - -Try out develop SSR *today* by running your site with it enabled: - -GATSBY_EXPERIMENTAL_DEV_SSR=true gatsby develop - -Please let us know how it goes good, bad, or otherwise at gatsby.dev/dev-ssr-feedback - `, + `Server Side Rendering (SSR) in Development`, + `gatsby.dev/dev-ssr-feedback`, + `which helps surface issues with build errors more quickly. Here's how to try it: + +module.exports = { + flags : { DEV_SSR: true }, + plugins: [...] +}`, 1 // Show this immediately to the subset of sites selected. ) } diff --git a/packages/gatsby/src/services/run-page-queries.ts b/packages/gatsby/src/services/run-page-queries.ts index 2c76f54440755..b31f3ddabc6e6 100644 --- a/packages/gatsby/src/services/run-page-queries.ts +++ b/packages/gatsby/src/services/run-page-queries.ts @@ -50,18 +50,15 @@ export async function runPageQueries({ !isCI() ) { cancelNotice = showExperimentNoticeAfterTimeout( - `queryOnDemand`, - reporter.stripIndent(` - Your local development experience is about to get better, faster, and stronger! + `Query On Demand`, + `https://gatsby.dev/query-on-demand-feedback`, + `which avoids running page queries in development until you visit a page — so a lot less upfront work. Here's how to try it: - Your friendly Gatsby maintainers detected your site takes longer than ideal to run page queries. We're working right now to improve this. - - If you're interested in trialing out one of these future improvements *today* which should make your local development experience faster, go ahead and run your site with QUERY_ON_DEMAND enabled. - - You can enable it by adding "flags: { QUERY_ON_DEMAND: true }" to your gatsby-config.js - - Please do let us know how it goes (good, bad, or otherwise) and learn more about it at https://gatsby.dev/query-on-demand-feedback - `), +modules.exports = { + flags: { QUERY_ON_DEMAND: true }, + plugins: [...] +} +`, ONE_MINUTE ) } diff --git a/packages/gatsby/src/services/start-webpack-server.ts b/packages/gatsby/src/services/start-webpack-server.ts index c95ff0eedde4a..5337da46cd84f 100644 --- a/packages/gatsby/src/services/start-webpack-server.ts +++ b/packages/gatsby/src/services/start-webpack-server.ts @@ -12,6 +12,7 @@ import { } from "../utils/webpack-error-utils" import { printDeprecationWarnings } from "../utils/print-deprecation-warnings" +import { showExperimentNotices } from "../utils/show-experiment-notice" import { printInstructions } from "../utils/print-instructions" import { prepareUrls } from "../utils/prepare-urls" import { startServer, IWebpackWatchingPauseResume } from "../utils/start-server" @@ -97,6 +98,9 @@ export async function startWebpackServer({ const isSuccessful = !messages.errors.length if (isSuccessful && isFirstCompile) { + // Show notices to users about potential experiments/feature flags they could + // try. + showExperimentNotices() printInstructions( program.sitePackageJson.name || `(Unnamed package)`, urls diff --git a/packages/gatsby/src/utils/__tests__/__snapshots__/show-experiment-notice.js.snap b/packages/gatsby/src/utils/__tests__/__snapshots__/show-experiment-notice.js.snap new file mode 100644 index 0000000000000..5cfb41a723ae4 --- /dev/null +++ b/packages/gatsby/src/utils/__tests__/__snapshots__/show-experiment-notice.js.snap @@ -0,0 +1,11 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`show-experiment-notice generates a message 1`] = ` +" +Hi from the Gatsby maintainers! Based on what we see in your site, these coming +features may help you. All of these can be enabled within gatsby-config.js via +flags (samples below) + +The Flag (http://example.com), hi +" +`; diff --git a/packages/gatsby/src/utils/__tests__/show-experiment-notice.js b/packages/gatsby/src/utils/__tests__/show-experiment-notice.js new file mode 100644 index 0000000000000..d9fd22c69a76c --- /dev/null +++ b/packages/gatsby/src/utils/__tests__/show-experiment-notice.js @@ -0,0 +1,20 @@ +import { createNoticeMessage } from "../show-experiment-notice" +import stripAnsi from "strip-ansi" + +jest.mock(`terminal-link`, () => (text, url) => `${text} (${url})`) + +describe(`show-experiment-notice`, () => { + it(`generates a message`, () => { + expect( + stripAnsi( + createNoticeMessage([ + { + noticeText: `hi`, + umbrellaLink: `http://example.com`, + experimentIdentifier: `The Flag`, + }, + ]) + ) + ).toMatchSnapshot() + }) +}) diff --git a/packages/gatsby/src/utils/show-experiment-notice.ts b/packages/gatsby/src/utils/show-experiment-notice.ts index d836e116297c7..32715afa0a92e 100644 --- a/packages/gatsby/src/utils/show-experiment-notice.ts +++ b/packages/gatsby/src/utils/show-experiment-notice.ts @@ -1,5 +1,8 @@ import { getConfigStore } from "gatsby-core-utils" import reporter from "gatsby-cli/lib/reporter" +import chalk from "chalk" +import telemetry from "gatsby-telemetry" +import terminalLink from "terminal-link" type CancelExperimentNoticeCallback = () => void @@ -9,15 +12,26 @@ export type CancelExperimentNoticeCallbackOrUndefined = const ONE_DAY = 24 * 60 * 60 * 1000 +interface INoticeObject { + noticeText: string + umbrellaLink: string + experimentIdentifier: string +} + +const noticesToShow: Array = [] +const configStoreKey = (experimentIdentifier): string => + `lastExperimentNotice.${experimentIdentifier}` + export function showExperimentNoticeAfterTimeout( experimentIdentifier: string, + umbrellaLink: string, noticeText: string, showNoticeAfterMs: number, minimumIntervalBetweenNoticesMs: number = ONE_DAY ): CancelExperimentNoticeCallbackOrUndefined { - const configStoreKey = `lastExperimentNotice.${experimentIdentifier}` - - const lastTimeWeShowedNotice = getConfigStore().get(configStoreKey) + const lastTimeWeShowedNotice = getConfigStore().get( + configStoreKey(experimentIdentifier) + ) if (lastTimeWeShowedNotice) { if (Date.now() - lastTimeWeShowedNotice < minimumIntervalBetweenNoticesMs) { @@ -26,12 +40,43 @@ export function showExperimentNoticeAfterTimeout( } const noticeTimeout = setTimeout(() => { - reporter.info(`\n\n${noticeText}\n\n`) - - getConfigStore().set(configStoreKey, Date.now()) + noticesToShow.push({ noticeText, umbrellaLink, experimentIdentifier }) }, showNoticeAfterMs) return function clearNoticeTimeout(): void { clearTimeout(noticeTimeout) } } + +export const createNoticeMessage = (notices): string => { + let message = `\nHi from the Gatsby maintainers! Based on what we see in your site, these coming +features may help you. All of these can be enabled within gatsby-config.js via +flags (samples below)` + + notices.forEach( + notice => + (message += ` + +${chalk.bgBlue.bold( + terminalLink(notice.experimentIdentifier, notice.umbrellaLink) +)}, ${notice.noticeText}\n`) + ) + + return message +} + +export const showExperimentNotices = (): void => { + if (noticesToShow.length > 0) { + telemetry.trackCli(`InviteToTryExperiment`) + // Store that we're showing the invite. + noticesToShow.forEach(notice => + getConfigStore().set( + configStoreKey(notice.experimentIdentifier), + Date.now() + ) + ) + + const message = createNoticeMessage(noticesToShow) + reporter.info(message) + } +} diff --git a/packages/gatsby/src/utils/start-server.ts b/packages/gatsby/src/utils/start-server.ts index 5c4458d049f9f..96bd377645e3d 100644 --- a/packages/gatsby/src/utils/start-server.ts +++ b/packages/gatsby/src/utils/start-server.ts @@ -92,20 +92,16 @@ export async function startServer( !isCI() ) { cancelDevJSNotice = showExperimentNoticeAfterTimeout( - `PRESERVE_WEBPACK_CACHE`, - report.stripIndent(` -Your friendly Gatsby maintainers detected your site has more JavaScript than most sites! We're working to make your site's JS compile as quickly as possible by avoiding clearing your webpack cache as often. - -If you're interested in trialing this coming change *today* — which should make your local development experience faster — go ahead and enable the PRESERVE_WEBPACK_CACHE flag and run your develop server again. - -To do so, add to your gatsby-config.js: - -flags: { - PRESERVE_WEBPACK_CACHE: true, -} - -Visit the umbrella issue to learn more: https://github.com/gatsbyjs/gatsby/discussions/28331 - `), + `Preserve webpack's Cache`, + `https://github.com/gatsbyjs/gatsby/discussions/28331`, + `which changes Gatsby's cache clearing behavior to not clear webpack's +cache unless you run "gatsby clean" or delete the .cache folder manually. +Here's how to try it: + +module.exports = { + flags: { PRESERVE_WEBPACK_CACHE: true }, + plugins: [...] +}`, THIRTY_SECONDS ) }