From 40abcd44f285740bd8dd8c0748253ada41b7a3af Mon Sep 17 00:00:00 2001 From: Pedro Cattori Date: Thu, 8 Jun 2023 19:01:11 +0200 Subject: [PATCH 01/12] feat(dev): clear screen and print title for `remix dev` --- packages/remix-dev/cli/commands.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/remix-dev/cli/commands.ts b/packages/remix-dev/cli/commands.ts index 5a16e9a22cf..3ef3ab8937b 100644 --- a/packages/remix-dev/cli/commands.ts +++ b/packages/remix-dev/cli/commands.ts @@ -224,6 +224,10 @@ export async function dev( tlsCert?: string; } = {} ) { + // clear screen + process.stdout.write("\x1Bc"); + console.log(`\n 💿 remix dev\n`); + if (process.env.NODE_ENV && process.env.NODE_ENV !== "development") { console.warn( `Forcing NODE_ENV to be 'development'. Was: ${JSON.stringify( From 174bd0f2c42ee89b74567cfefa5d85fac05835de Mon Sep 17 00:00:00 2001 From: Pedro Cattori Date: Thu, 8 Jun 2023 19:09:04 +0200 Subject: [PATCH 02/12] chore(dev): terminal ux utilities --- packages/remix-dev/package.json | 1 + packages/remix-dev/tux/format.ts | 25 +++++++++++++ packages/remix-dev/tux/index.ts | 1 + packages/remix-dev/tux/logger.ts | 60 ++++++++++++++++++++++++++++++++ 4 files changed, 87 insertions(+) create mode 100644 packages/remix-dev/tux/format.ts create mode 100644 packages/remix-dev/tux/index.ts create mode 100644 packages/remix-dev/tux/logger.ts diff --git a/packages/remix-dev/package.json b/packages/remix-dev/package.json index 15b2270fffb..108db8c11f9 100644 --- a/packages/remix-dev/package.json +++ b/packages/remix-dev/package.json @@ -53,6 +53,7 @@ "minimatch": "^9.0.0", "node-fetch": "^2.6.9", "ora": "^5.4.1", + "picocolors": "^1.0.0", "picomatch": "^2.3.1", "postcss": "^8.4.19", "postcss-discard-duplicates": "^5.1.0", diff --git a/packages/remix-dev/tux/format.ts b/packages/remix-dev/tux/format.ts new file mode 100644 index 00000000000..89269dc59c4 --- /dev/null +++ b/packages/remix-dev/tux/format.ts @@ -0,0 +1,25 @@ +import pc from "picocolors"; +import type { Formatter } from "picocolors/types"; + +type FormatArgs = { + label: string; + color: Formatter; +}; + +export let format = + ({ label, color }: FormatArgs) => + (message: string, details: string[] = []) => { + let lines = []; + lines.push( + (pc.isColorSupported ? pc.inverse(color(` ${label} `)) : `[${label}]`) + + " " + + message + ); + if (details.length > 0) { + for (let detail of details) { + lines.push(color("┃") + " " + pc.gray(detail)); + } + lines.push(color("┗")); + } + return lines.join("\n"); + }; diff --git a/packages/remix-dev/tux/index.ts b/packages/remix-dev/tux/index.ts new file mode 100644 index 00000000000..6edc896e211 --- /dev/null +++ b/packages/remix-dev/tux/index.ts @@ -0,0 +1 @@ +export { logger, type Logger } from "./logger"; diff --git a/packages/remix-dev/tux/logger.ts b/packages/remix-dev/tux/logger.ts new file mode 100644 index 00000000000..5ef1580bf85 --- /dev/null +++ b/packages/remix-dev/tux/logger.ts @@ -0,0 +1,60 @@ +import pc from "picocolors"; +import type { Formatter } from "picocolors/types"; + +import { format } from "./format"; + +type Log = ( + message: string, + options?: { details?: string[]; key?: string } +) => void; + +export type Logger = { + debug: Log; + info: Log; + warn: Log; + error: Log; +}; + +type LogArgs = { + label: string; + color: Formatter; + dest: NodeJS.WriteStream; +}; + +let log = ({ label, color, dest }: LogArgs): Log => { + let _format = format({ label, color }); + let already = new Set(); + + return (message, { details, key } = {}) => { + let formatted = _format(message, details) + "\n"; + + if (key === undefined) return dest.write(formatted); + if (already.has(key)) return; + already.add(key); + + dest.write(formatted); + }; +}; + +export let logger: Logger = { + debug: log({ + label: "debug", + color: pc.green, + dest: process.stdout, + }), + info: log({ + label: "info", + color: pc.blue, + dest: process.stdout, + }), + warn: log({ + label: "warn", + color: pc.yellow, + dest: process.stderr, + }), + error: log({ + label: "error", + color: pc.red, + dest: process.stderr, + }), +}; From 6058a2b4d17e4e07eb34b2c83b8b2159813b351d Mon Sep 17 00:00:00 2001 From: Pedro Cattori Date: Thu, 8 Jun 2023 23:41:30 +0200 Subject: [PATCH 03/12] chore(dev): remove vestigial warning --- packages/remix-dev/compiler/js/compiler.ts | 77 +--------------------- 1 file changed, 1 insertion(+), 76 deletions(-) diff --git a/packages/remix-dev/compiler/js/compiler.ts b/packages/remix-dev/compiler/js/compiler.ts index d9e49bb499e..f79bc2daa4e 100644 --- a/packages/remix-dev/compiler/js/compiler.ts +++ b/packages/remix-dev/compiler/js/compiler.ts @@ -16,15 +16,10 @@ import { mdxPlugin } from "../plugins/mdx"; import { externalPlugin } from "../plugins/external"; import { cssBundlePlugin } from "../plugins/cssBundlePlugin"; import { cssModulesPlugin } from "../plugins/cssModuleImports"; -import { - cssSideEffectImportsPlugin, - isCssSideEffectImportPath, -} from "../plugins/cssSideEffectImports"; +import { cssSideEffectImportsPlugin } from "../plugins/cssSideEffectImports"; import { vanillaExtractPlugin } from "../plugins/vanillaExtract"; import invariant from "../../invariant"; import { hmrPlugin } from "./plugins/hmr"; -import { createMatchPath } from "../utils/tsconfig"; -import { detectPackageManager } from "../../cli/detectPackageManager"; import type { LazyValue } from "../lazyValue"; import type { Context } from "../context"; @@ -38,21 +33,6 @@ type Compiler = { dispose: () => Promise; }; -function getNpmPackageName(id: string): string { - let split = id.split("/"); - let packageName = split[0]; - if (packageName.startsWith("@")) packageName += `/${split[1]}`; - return packageName; -} - -function isBareModuleId(id: string): boolean { - return !id.startsWith("node:") && !id.startsWith(".") && !path.isAbsolute(id); -} - -function isNodeBuiltIn(packageName: string) { - return nodeBuiltins.includes(packageName); -} - const getExternals = (remixConfig: RemixConfig): string[] => { // For the browser build, exclude node built-ins that don't have a // browser-safe alternative installed in node_modules. Nothing should @@ -105,18 +85,6 @@ const createEsbuildConfig = ( ); } - let matchPath = ctx.config.tsconfigPath - ? createMatchPath(ctx.config.tsconfigPath) - : undefined; - function resolvePath(id: string) { - if (!matchPath) { - return id; - } - return ( - matchPath(id, undefined, undefined, [".ts", ".tsx", ".js", ".jsx"]) || id - ); - } - let plugins: esbuild.Plugin[] = [ browserRouteModulesPlugin(ctx, /\?browser$/), deprecatedRemixPackagePlugin(ctx), @@ -135,49 +103,6 @@ const createEsbuildConfig = ( emptyModulesPlugin(ctx, /\.server(\.[jt]sx?)?$/), nodeModulesPolyfillPlugin(), externalPlugin(/^node:.*/, { sideEffects: false }), - { - // TODO: should be removed when error handling for compiler is improved - name: "warn-on-unresolved-imports", - setup: (build) => { - build.onResolve({ filter: /.*/ }, (args) => { - if (!isBareModuleId(resolvePath(args.path))) { - return undefined; - } - - if (args.path === "remix:hmr") { - return undefined; - } - - let packageName = getNpmPackageName(args.path); - let pkgManager = detectPackageManager() ?? "npm"; - if ( - ctx.options.onWarning && - !isNodeBuiltIn(packageName) && - !/\bnode_modules\b/.test(args.importer) && - !args.path.endsWith(".css") && - !isCssSideEffectImportPath(args.path) && - // Silence spurious warnings when using Yarn PnP. Yarn PnP doesn’t use - // a `node_modules` folder to keep its dependencies, so the above check - // will always fail. - (pkgManager === "npm" || - (pkgManager === "yarn" && process.versions.pnp == null)) - ) { - try { - require.resolve(args.path); - } catch (error: unknown) { - ctx.options.onWarning( - `The path "${args.path}" is imported in ` + - `${path.relative(process.cwd(), args.importer)} but ` + - `"${args.path}" was not found in your node_modules. ` + - `Did you forget to install it?`, - args.path - ); - } - } - return undefined; - }); - }, - } as esbuild.Plugin, ]; if (ctx.options.mode === "development" && ctx.config.future.unstable_dev) { From 6b1534d4e764fa10d9202ad50da25cc35cee5e2b Mon Sep 17 00:00:00 2001 From: Pedro Cattori Date: Mon, 12 Jun 2023 16:38:19 -0400 Subject: [PATCH 04/12] refactor(dev): logger as part of compiler context --- packages/remix-dev/cli/commands.ts | 11 +++++++---- packages/remix-dev/compiler/context.ts | 2 ++ packages/remix-dev/devServer/liveReload.ts | 2 ++ packages/remix-dev/devServer_unstable/index.ts | 2 ++ 4 files changed, 13 insertions(+), 4 deletions(-) diff --git a/packages/remix-dev/cli/commands.ts b/packages/remix-dev/cli/commands.ts index 3ef3ab8937b..21deb9c9c43 100644 --- a/packages/remix-dev/cli/commands.ts +++ b/packages/remix-dev/cli/commands.ts @@ -26,6 +26,7 @@ import { transpile as convertFileToJS } from "./useJavascript"; import { warnOnce } from "../warnOnce"; import type { Options } from "../compiler/options"; import { createFileWatchCache } from "../compiler/fileWatchCache"; +import { logger } from "../tux"; export async function create({ appTemplate, @@ -184,10 +185,12 @@ export async function build( let fileWatchCache = createFileWatchCache(); fse.emptyDirSync(config.assetsBuildDirectory); - await compiler.build({ config, options, fileWatchCache }).catch((thrown) => { - compiler.logThrown(thrown); - process.exit(1); - }); + await compiler + .build({ config, options, fileWatchCache, logger }) + .catch((thrown) => { + compiler.logThrown(thrown); + process.exit(1); + }); console.log(`Built in ${prettyMs(Date.now() - start)}`); } diff --git a/packages/remix-dev/compiler/context.ts b/packages/remix-dev/compiler/context.ts index 4cdc90667bb..b924b254662 100644 --- a/packages/remix-dev/compiler/context.ts +++ b/packages/remix-dev/compiler/context.ts @@ -1,4 +1,5 @@ import type { RemixConfig } from "../config"; +import type { Logger } from "../tux"; import type { FileWatchCache } from "./fileWatchCache"; import type { Options } from "./options"; @@ -6,4 +7,5 @@ export type Context = { config: RemixConfig; options: Options; fileWatchCache: FileWatchCache; + logger: Logger; }; diff --git a/packages/remix-dev/devServer/liveReload.ts b/packages/remix-dev/devServer/liveReload.ts index 1add646d273..3680cec2761 100644 --- a/packages/remix-dev/devServer/liveReload.ts +++ b/packages/remix-dev/devServer/liveReload.ts @@ -8,6 +8,7 @@ import { watch } from "../compiler"; import type { RemixConfig } from "../config"; import { warnOnce } from "../warnOnce"; import { createFileWatchCache } from "../compiler/fileWatchCache"; +import { logger } from "../tux"; const relativePath = (file: string) => path.relative(process.cwd(), file); @@ -50,6 +51,7 @@ export async function liveReload(config: RemixConfig) { onWarning: warnOnce, }, fileWatchCache, + logger, }, { onBuildStart() { diff --git a/packages/remix-dev/devServer_unstable/index.ts b/packages/remix-dev/devServer_unstable/index.ts index df572d07c2b..93d6f94711c 100644 --- a/packages/remix-dev/devServer_unstable/index.ts +++ b/packages/remix-dev/devServer_unstable/index.ts @@ -21,6 +21,7 @@ import * as HDR from "./hdr"; import type { Result } from "../result"; import { err, ok } from "../result"; import invariant from "../invariant"; +import { logger } from "../tux"; type Origin = { scheme: string; @@ -183,6 +184,7 @@ export let serve = async ( devOrigin: origin, }, fileWatchCache, + logger, }, { onBuildStart: async (ctx) => { From 546b33d29ecf117a7a03b0469c38cc64df8616df Mon Sep 17 00:00:00 2001 From: Pedro Cattori Date: Mon, 12 Jun 2023 16:51:46 -0400 Subject: [PATCH 05/12] refactor(dev): replace `onWarning` with logger --- integration/compiler-test.ts | 10 +++- integration/esm-only-warning-test.ts | 28 +++------- packages/remix-dev/cli/commands.ts | 2 - packages/remix-dev/compiler/options.ts | 1 - .../plugins/deprecatedRemixPackage.ts | 16 +++--- .../compiler/server/plugins/bareImports.ts | 56 +++++++++---------- packages/remix-dev/devServer/liveReload.ts | 2 - .../remix-dev/devServer_unstable/index.ts | 2 - 8 files changed, 52 insertions(+), 65 deletions(-) diff --git a/integration/compiler-test.ts b/integration/compiler-test.ts index 648a5e8ca42..fceb67ce1b6 100644 --- a/integration/compiler-test.ts +++ b/integration/compiler-test.ts @@ -428,10 +428,16 @@ test.describe("compiler", () => { let importer = path.join("app", "routes", "_index.jsx"); expect(buildOutput).toContain( - `The path "some-not-installed-module" is imported in ${importer} but "some-not-installed-module" was not found in your node_modules. Did you forget to install it?` + `could not resolve "some-not-installed-module"` ); expect(buildOutput).toContain( - `The path "some-not-installed-module/sub" is imported in ${importer} but "some-not-installed-module/sub" was not found in your node_modules. Did you forget to install it?` + `You imported "some-not-installed-module" in ${importer},` + ); + expect(buildOutput).toContain( + `could not resolve "some-not-installed-module/sub"` + ); + expect(buildOutput).toContain( + `You imported "some-not-installed-module/sub" in ${importer},` ); }); }); diff --git a/integration/esm-only-warning-test.ts b/integration/esm-only-warning-test.ts index d287bedd265..c920af4f281 100644 --- a/integration/esm-only-warning-test.ts +++ b/integration/esm-only-warning-test.ts @@ -179,25 +179,11 @@ test.beforeAll(async () => { }); test("logs warnings for ESM only packages", async () => { - expect(buildOutput).toContain( - "esm-only-no-exports is possibly an ESM only package" - ); - expect(buildOutput).toContain( - "esm-only-exports is possibly an ESM only package" - ); - expect(buildOutput).not.toContain( - "esm-only-exports-b is possibly an ESM only package" - ); - expect(buildOutput).not.toContain( - "esm-only-exports-c is possibly an ESM only package" - ); - expect(buildOutput).not.toContain( - "cjs-dynamic-import is possibly an ESM only package" - ); - expect(buildOutput).toContain( - "esm-only-sub-exports is possibly an ESM only package" - ); - expect(buildOutput).not.toContain( - "esm-cjs-exports is possibly an ESM only package" - ); + expect(buildOutput).toContain("esm-only package: esm-only-no-exports"); + expect(buildOutput).toContain("esm-only package: esm-only-exports"); + expect(buildOutput).not.toContain("esm-only package: esm-only-exports-b"); + expect(buildOutput).not.toContain("esm-only package: esm-only-exports-c"); + expect(buildOutput).not.toContain("esm-only package: cjs-dynamic-import"); + expect(buildOutput).toContain("esm-only package: esm-only-sub-exports"); + expect(buildOutput).not.toContain("esm-only package: esm-cjs-exports"); }); diff --git a/packages/remix-dev/cli/commands.ts b/packages/remix-dev/cli/commands.ts index 21deb9c9c43..fd7188b4dfb 100644 --- a/packages/remix-dev/cli/commands.ts +++ b/packages/remix-dev/cli/commands.ts @@ -23,7 +23,6 @@ import runCodemod from "../codemod"; import { CodemodError } from "../codemod/utils/error"; import { TaskError } from "../codemod/utils/task"; import { transpile as convertFileToJS } from "./useJavascript"; -import { warnOnce } from "../warnOnce"; import type { Options } from "../compiler/options"; import { createFileWatchCache } from "../compiler/fileWatchCache"; import { logger } from "../tux"; @@ -175,7 +174,6 @@ export async function build( let options: Options = { mode, sourcemap, - onWarning: warnOnce, }; if (mode === "development" && config.future.unstable_dev) { let origin = await resolveDevOrigin(config); diff --git a/packages/remix-dev/compiler/options.ts b/packages/remix-dev/compiler/options.ts index d128116d7de..072f16ce1e6 100644 --- a/packages/remix-dev/compiler/options.ts +++ b/packages/remix-dev/compiler/options.ts @@ -3,7 +3,6 @@ type Mode = "development" | "production" | "test"; export type Options = { mode: Mode; sourcemap: boolean; - onWarning?: (message: string, key: string) => void; // TODO: required in v2 devOrigin?: { diff --git a/packages/remix-dev/compiler/plugins/deprecatedRemixPackage.ts b/packages/remix-dev/compiler/plugins/deprecatedRemixPackage.ts index 43ef5aa4014..1f12b9a9170 100644 --- a/packages/remix-dev/compiler/plugins/deprecatedRemixPackage.ts +++ b/packages/remix-dev/compiler/plugins/deprecatedRemixPackage.ts @@ -14,13 +14,15 @@ export function deprecatedRemixPackagePlugin(ctx: Context): Plugin { // Warn on deprecated imports from the remix package if (filePath === "remix") { let relativePath = path.relative(process.cwd(), importer); - let warningMessage = - `WARNING: All \`remix\` exports are considered deprecated as of v1.3.3. ` + - `Please change your import in "${relativePath}" to come from the respective ` + - `underlying \`@remix-run/*\` package. ` + - `Run \`npx @remix-run/dev@latest codemod replace-remix-magic-imports\` ` + - `to automatically migrate your code.`; - ctx.options.onWarning?.(warningMessage, importer); + ctx.logger.warn(`deprecated \`remix\` import in ${relativePath}`, { + details: [ + "Imports from the `remix` package were deprecated in v1.3.3.", + "Change your code to import from the appropriate `@remix-run/*` package instead.", + "You can run the following codemod to autofix this issue:", + "-> `npx @remix-run/dev@latest codemod replace-remix-magic-imports`", + ], + key: importer, + }); } return undefined; }); diff --git a/packages/remix-dev/compiler/server/plugins/bareImports.ts b/packages/remix-dev/compiler/server/plugins/bareImports.ts index 075361fa6bf..dab923eff0f 100644 --- a/packages/remix-dev/compiler/server/plugins/bareImports.ts +++ b/packages/remix-dev/compiler/server/plugins/bareImports.ts @@ -18,10 +18,10 @@ import type { Context } from "../../context"; * This includes externalizing for node based platforms, and bundling for single file * environments such as cloudflare. */ -export function serverBareModulesPlugin({ config, options }: Context): Plugin { +export function serverBareModulesPlugin(ctx: Context): Plugin { // Resolve paths according to tsconfig paths property - let matchPath = config.tsconfigPath - ? createMatchPath(config.tsconfigPath) + let matchPath = ctx.config.tsconfigPath + ? createMatchPath(ctx.config.tsconfigPath) : undefined; function resolvePath(id: string) { if (!matchPath) { @@ -76,7 +76,6 @@ export function serverBareModulesPlugin({ config, options }: Context): Plugin { // Warn if we can't find an import for a package. if ( - options.onWarning && !isNodeBuiltIn(packageName) && !/\bnode_modules\b/.test(importer) && // Silence spurious warnings when using Yarn PnP. Yarn PnP doesn’t use @@ -88,21 +87,25 @@ export function serverBareModulesPlugin({ config, options }: Context): Plugin { try { require.resolve(path, { paths: [importer] }); } catch (error: unknown) { - options.onWarning( - `The path "${path}" is imported in ` + - `${relative(process.cwd(), importer)} but ` + - `"${path}" was not found in your node_modules. ` + - `Did you forget to install it?`, - path - ); + ctx.logger.warn(`could not resolve "${path}"`, { + details: [ + `You imported "${path}" in ${relative( + process.cwd(), + importer + )},`, + "but that package is not in your `node_modules`.", + "Did you forget to install it?", + ], + key: path, + }); } } - if (config.serverDependenciesToBundle === "all") { + if (ctx.config.serverDependenciesToBundle === "all") { return undefined; } - for (let pattern of config.serverDependenciesToBundle) { + for (let pattern of ctx.config.serverDependenciesToBundle) { // bundle it if the path matches the pattern if ( typeof pattern === "string" ? path === pattern : pattern.test(path) @@ -112,17 +115,11 @@ export function serverBareModulesPlugin({ config, options }: Context): Plugin { } if ( - options.onWarning && !isNodeBuiltIn(packageName) && kind !== "dynamic-import" && - config.serverPlatform === "node" + ctx.config.serverPlatform === "node" ) { - warnOnceIfEsmOnlyPackage( - packageName, - path, - importer, - options.onWarning - ); + warnOnceIfEsmOnlyPackage(ctx, packageName, path, importer); } // Externalize everything else if we've gotten here. @@ -151,10 +148,10 @@ function isBareModuleId(id: string): boolean { } function warnOnceIfEsmOnlyPackage( + ctx: Context, packageName: string, fullImportPath: string, - importer: string, - onWarning: (msg: string, key: string) => void + importer: string ) { try { let packageDir = resolveModuleBasePath( @@ -187,11 +184,14 @@ function warnOnceIfEsmOnlyPackage( } if (isEsmOnly) { - onWarning( - `${packageName} is possibly an ESM only package and should be bundled with ` + - `"serverDependenciesToBundle" in remix.config.js.`, - packageName + ":esm-only" - ); + ctx.logger.warn(`esm-only package: ${packageName}`, { + details: [ + `${packageName} is possibly an ESM-only package.`, + "To bundle it with your server, include it in `serverDependenciesToBundle`", + "-> https://remix.run/docs/en/main/file-conventions/remix-config#serverdependenciestobundle", + ], + key: packageName + ":esm-only", + }); } } } catch (error: unknown) { diff --git a/packages/remix-dev/devServer/liveReload.ts b/packages/remix-dev/devServer/liveReload.ts index 3680cec2761..e74ca3242bd 100644 --- a/packages/remix-dev/devServer/liveReload.ts +++ b/packages/remix-dev/devServer/liveReload.ts @@ -6,7 +6,6 @@ import WebSocket from "ws"; import { watch } from "../compiler"; import type { RemixConfig } from "../config"; -import { warnOnce } from "../warnOnce"; import { createFileWatchCache } from "../compiler/fileWatchCache"; import { logger } from "../tux"; @@ -48,7 +47,6 @@ export async function liveReload(config: RemixConfig) { options: { mode: "development", sourcemap: true, - onWarning: warnOnce, }, fileWatchCache, logger, diff --git a/packages/remix-dev/devServer_unstable/index.ts b/packages/remix-dev/devServer_unstable/index.ts index 93d6f94711c..26b363158a6 100644 --- a/packages/remix-dev/devServer_unstable/index.ts +++ b/packages/remix-dev/devServer_unstable/index.ts @@ -15,7 +15,6 @@ import { type RemixConfig } from "../config"; import { loadEnv } from "./env"; import * as Socket from "./socket"; import * as HMR from "./hmr"; -import { warnOnce } from "../warnOnce"; import { detectPackageManager } from "../cli/detectPackageManager"; import * as HDR from "./hdr"; import type { Result } from "../result"; @@ -180,7 +179,6 @@ export let serve = async ( options: { mode: "development", sourcemap: true, - onWarning: warnOnce, devOrigin: origin, }, fileWatchCache, From b2be899b3f01efa3b78dbfbe19dc28fb12025eec Mon Sep 17 00:00:00 2001 From: Pedro Cattori Date: Mon, 12 Jun 2023 22:27:12 -0400 Subject: [PATCH 06/12] refactor(dev): replace raw console usage with logger --- packages/remix-dev/compiler/server/plugins/bareImports.ts | 2 +- packages/remix-dev/compiler/watch.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/remix-dev/compiler/server/plugins/bareImports.ts b/packages/remix-dev/compiler/server/plugins/bareImports.ts index dab923eff0f..3d15801f390 100644 --- a/packages/remix-dev/compiler/server/plugins/bareImports.ts +++ b/packages/remix-dev/compiler/server/plugins/bareImports.ts @@ -162,7 +162,7 @@ function warnOnceIfEsmOnlyPackage( let packageJsonFile = path.join(packageDir, "package.json"); if (!fs.existsSync(packageJsonFile)) { - console.log(packageJsonFile, `does not exist`); + ctx.logger.warn(`could not find package.json for ${packageName}`); return; } let pkg = JSON.parse(fs.readFileSync(packageJsonFile, "utf-8")); diff --git a/packages/remix-dev/compiler/watch.ts b/packages/remix-dev/compiler/watch.ts index 1920810b7a2..482627feb7e 100644 --- a/packages/remix-dev/compiler/watch.ts +++ b/packages/remix-dev/compiler/watch.ts @@ -106,7 +106,7 @@ export async function watch( pollInterval: 100, }, }) - .on("error", (error) => console.error(error)) + .on("error", (error) => ctx.logger.error(String(error))) .on("change", async (file) => { onFileChanged?.(file); await rebuild(); From 1e7eb187440269e5bb1656c9f114e618cb5aa67a Mon Sep 17 00:00:00 2001 From: Pedro Cattori Date: Mon, 12 Jun 2023 22:32:50 -0400 Subject: [PATCH 07/12] refactor(dev): replace raw console usage in dev command with logger --- packages/remix-dev/cli/commands.ts | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/packages/remix-dev/cli/commands.ts b/packages/remix-dev/cli/commands.ts index fd7188b4dfb..b473a4ceac0 100644 --- a/packages/remix-dev/cli/commands.ts +++ b/packages/remix-dev/cli/commands.ts @@ -230,11 +230,7 @@ export async function dev( console.log(`\n 💿 remix dev\n`); if (process.env.NODE_ENV && process.env.NODE_ENV !== "development") { - console.warn( - `Forcing NODE_ENV to be 'development'. Was: ${JSON.stringify( - process.env.NODE_ENV - )}` - ); + logger.warn(`overriding NODE_ENV=${process.env.NODE_ENV} to development`); } process.env.NODE_ENV = "development"; if (flags.debug) inspector.open(); From 9b6e4533a6220182a74295b881ad1f41d361cd5d Mon Sep 17 00:00:00 2001 From: Pedro Cattori Date: Mon, 12 Jun 2023 22:47:07 -0400 Subject: [PATCH 08/12] refactor(dev): replace raw console usage with logger in unstable_dev --- packages/remix-dev/devServer_unstable/env.ts | 1 - .../remix-dev/devServer_unstable/index.ts | 66 +++++++++++-------- .../remix-dev/devServer_unstable/socket.ts | 3 +- 3 files changed, 39 insertions(+), 31 deletions(-) diff --git a/packages/remix-dev/devServer_unstable/env.ts b/packages/remix-dev/devServer_unstable/env.ts index 9f9df9c4ff0..b1e385d8449 100644 --- a/packages/remix-dev/devServer_unstable/env.ts +++ b/packages/remix-dev/devServer_unstable/env.ts @@ -6,7 +6,6 @@ export async function loadEnv(rootDirectory: string): Promise { let envPath = path.join(rootDirectory, ".env"); if (!fse.existsSync(envPath)) return; - console.log(`Loading environment variables from .env`); let result = require("dotenv").config({ path: envPath }); if (result.error) throw result.error; } diff --git a/packages/remix-dev/devServer_unstable/index.ts b/packages/remix-dev/devServer_unstable/index.ts index 26b363158a6..9ca668c4dbd 100644 --- a/packages/remix-dev/devServer_unstable/index.ts +++ b/packages/remix-dev/devServer_unstable/index.ts @@ -6,6 +6,7 @@ import fs from "fs-extra"; import prettyMs from "pretty-ms"; import execa from "execa"; import express from "express"; +import pc from "picocolors"; import * as Channel from "../channel"; import { type Manifest } from "../manifest"; @@ -69,7 +70,7 @@ export let serve = async ( .post("/ping", (req, res) => { let { buildHash } = req.body; if (typeof buildHash !== "string") { - console.warn(`Unrecognized payload: ${req.body}`); + logger.warn(`unrecognized payload: ${req.body}`); res.sendStatus(400); } if (buildHash === state.manifest?.version) { @@ -104,7 +105,6 @@ export let serve = async ( process.cwd(), initialConfig.serverBuildPath )}`; - console.log(`> ${cmd}`); let newAppServer = execa .command(cmd, { stdio: "pipe", @@ -125,18 +125,16 @@ export let serve = async ( invariant("path" in e && typeof e.path === "string", "path missing"); if (command === undefined) { - console.error( - [ - "", - `┏ [error] command not found: ${e.path}`, - `┃ \`remix dev\` did not receive \`--command\` nor \`-c\`, defaulting to \`${cmd}\`.`, - "┃ You probably meant to use `-c` for your app server command.", - "┗ For example: `remix dev -c 'node ./server.js'`", - "", - ].join("\n") - ); + logger.error(`command not found: ${e.path}`, { + details: [ + `\`remix dev\` did not receive \`--command\` nor \`-c\`, defaulting to \`${cmd}\`.`, + "You probably meant to use `-c` for your app server command.", + "For example: `remix dev -c 'node ./server.js'`", + ], + }); process.exit(1); } + logger.error("app failed to start" + pc.gray(` (${command})`)); throw e; }); @@ -190,7 +188,11 @@ export let serve = async ( state.appReady?.err(); clean(ctx.config); - websocket.log(state.prevManifest ? "Rebuilding..." : "Building..."); + if (!state.prevManifest) { + let msg = "building..."; + websocket.log(msg); + logger.info(msg); + } state.loaderChanges = HDR.detectLoaderChanges(ctx).then(ok, err); }, @@ -200,15 +202,16 @@ export let serve = async ( }, onBuildFinish: async (ctx, durationMs, succeeded) => { if (!succeeded) return; - websocket.log( - (state.prevManifest ? "Rebuilt" : "Built") + - ` in ${prettyMs(durationMs)}` - ); + + let msg = + (state.prevManifest ? "rebuilt" : "built") + + pc.gray(` (${prettyMs(durationMs)})`); + websocket.log(msg); + logger.info(msg); // accumulate new state, but only update state after updates are processed let newState: typeof state = { prevManifest: state.manifest }; try { - console.log(`Waiting for app server (${state.manifest?.version})`); let start = Date.now(); if (state.appServer === undefined || options.restart) { await kill(state.appServer); @@ -216,7 +219,11 @@ export let serve = async ( } let appReady = await state.appReady!.result; if (!appReady.ok) return; - console.log(`App server took ${prettyMs(Date.now() - start)}`); + if (state.prevManifest) { + logger.info( + `app server ready` + pc.gray(` (${prettyMs(Date.now() - start)})`) + ); + } // HMR + HDR let loaderChanges = await state.loaderChanges!; @@ -234,36 +241,39 @@ export let serve = async ( websocket.hmr(state.manifest, updates); let hdr = updates.some((u) => u.revalidate); - console.log("> HMR" + (hdr ? " + HDR" : "")); + logger.info("hmr" + (hdr ? " + hdr" : "")); return; } // Live Reload if (state.prevManifest !== undefined) { websocket.reload(); - console.log("> Live reload"); + logger.info("live reload"); } } finally { // commit accumulated state Object.assign(state, newState); + // process.stdout.write("\n"); } }, - onFileCreated: (file) => - websocket.log(`File created: ${relativePath(file)}`), + onFileCreated: (file) => { + logger.info(`rebuilding...` + pc.gray(` (+ ${relativePath(file)})`)); + websocket.log(`file created: ${relativePath(file)}`); + }, onFileChanged: (file) => { - websocket.log(`File changed: ${relativePath(file)}`); + logger.info(`rebuilding...` + pc.gray(` (~ ${relativePath(file)})`)); + websocket.log(`file changed: ${relativePath(file)}`); fileWatchCache.invalidateFile(file); }, onFileDeleted: (file) => { - websocket.log(`File deleted: ${relativePath(file)}`); + logger.info(`rebuilding` + pc.gray(` (- ${relativePath(file)})`)); + websocket.log(`file deleted: ${relativePath(file)}`); fileWatchCache.invalidateFile(file); }, } ); - server.listen(origin.port, () => { - console.log("Remix dev server ready"); - }); + server.listen(origin.port); return new Promise(() => {}).finally(async () => { await kill(state.appServer); diff --git a/packages/remix-dev/devServer_unstable/socket.ts b/packages/remix-dev/devServer_unstable/socket.ts index a66ca95a0db..27c07f3df1f 100644 --- a/packages/remix-dev/devServer_unstable/socket.ts +++ b/packages/remix-dev/devServer_unstable/socket.ts @@ -27,8 +27,7 @@ export let serve = (server: HTTPServer) => { }; let log = (messageText: string) => { - let _message = `💿 ${messageText}`; - console.log(_message); + let _message = `[remix] ${messageText}`; broadcast({ type: "LOG", message: _message }); }; From b270e5cd1c3ce6a7abac6f7c4458ec0f6a45c8fd Mon Sep 17 00:00:00 2001 From: Pedro Cattori Date: Tue, 13 Jun 2023 11:07:07 -0400 Subject: [PATCH 09/12] refactor(dev): use logger for build command --- packages/remix-dev/cli/commands.ts | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/packages/remix-dev/cli/commands.ts b/packages/remix-dev/cli/commands.ts index b473a4ceac0..98c47e5e8a0 100644 --- a/packages/remix-dev/cli/commands.ts +++ b/packages/remix-dev/cli/commands.ts @@ -8,6 +8,7 @@ import prettyMs from "pretty-ms"; import * as esbuild from "esbuild"; import NPMCliPackageJson from "@npmcli/package-json"; import { coerce } from "semver"; +import pc from "picocolors"; import * as colors from "../colors"; import * as compiler from "../compiler"; @@ -152,21 +153,18 @@ export async function build( ): Promise { let mode = parseMode(modeArg) ?? "production"; - console.log(`Building Remix app in ${mode} mode...`); + logger.info(`building...` + pc.gray(` (NODE_ENV=${mode})`)); if (modeArg === "production" && sourcemap) { - console.warn( - "\n⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️" - ); - console.warn( - "You have enabled source maps in production. This will make your " + - "server-side code visible to the public and is highly discouraged! If " + - "you insist, please ensure you are using environment variables for " + - "secrets and not hard-coding them into your source!" - ); - console.warn( - "⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️\n" - ); + logger.warn("🚨 source maps enabled in production", { + details: [ + "You are using `--sourcemap` to enable source maps in production,", + "making your server-side code publicly visible in the browser.", + "This is highly discouraged!", + "If you insist, ensure that you are using environment variables for secrets", + "and are not hard-coding them in your source.", + ], + }); } let start = Date.now(); @@ -190,7 +188,7 @@ export async function build( process.exit(1); }); - console.log(`Built in ${prettyMs(Date.now() - start)}`); + logger.info("built" + pc.gray(` (${prettyMs(Date.now() - start)})`)); } // TODO: replace watch in v2 From 71633998e5439b7df84a60bc2eb61cc49c772220 Mon Sep 17 00:00:00 2001 From: Pedro Cattori Date: Tue, 13 Jun 2023 12:26:50 -0400 Subject: [PATCH 10/12] refactor(dev): warnings for config options and future flags use logger --- packages/remix-dev/config.ts | 213 +++++++++++++++++++++++------------ 1 file changed, 139 insertions(+), 74 deletions(-) diff --git a/packages/remix-dev/config.ts b/packages/remix-dev/config.ts index 68e91d48641..a814a2a235d 100644 --- a/packages/remix-dev/config.ts +++ b/packages/remix-dev/config.ts @@ -13,7 +13,7 @@ import { ServerMode, isValidServerMode } from "./config/serverModes"; import { serverBuildVirtualModule } from "./compiler/server/virtualModules"; import { flatRoutes } from "./config/flat-routes"; import { detectPackageManager } from "./cli/detectPackageManager"; -import { warnOnce } from "./warnOnce"; +import { logger } from "./tux"; export interface RemixMdxConfig { rehypePlugins?: any[]; @@ -426,23 +426,23 @@ export async function readConfig( } if (appConfig.serverBuildTarget) { - warnOnce(serverBuildTargetWarning, "v2_serverBuildTarget"); + serverBuildTargetWarning(); } if (!appConfig.future?.v2_errorBoundary) { - warnOnce(errorBoundaryWarning, "v2_errorBoundary"); + errorBoundaryWarning(); } if (!appConfig.future?.v2_normalizeFormMethod) { - warnOnce(formMethodWarning, "v2_normalizeFormMethod"); + formMethodWarning(); } if (!appConfig.future?.v2_meta) { - warnOnce(metaWarning, "v2_meta"); + metaWarning(); } if (!appConfig.future?.v2_headers) { - warnOnce(headersWarning, "v2_headers"); + headersWarning(); } let isCloudflareRuntime = ["cloudflare-pages", "cloudflare-workers"].includes( @@ -462,7 +462,7 @@ export async function readConfig( let serverMinify = appConfig.serverMinify; if (!appConfig.serverModuleFormat) { - warnOnce(serverModuleFormatWarning, "serverModuleFormatWarning"); + serverModuleFormatWarning(); } let serverModuleFormat = appConfig.serverModuleFormat || "cjs"; @@ -488,32 +488,67 @@ export async function readConfig( if (appConfig.future) { if ("unstable_cssModules" in appConfig.future) { - warnOnce( - 'The "future.unstable_cssModules" config option has been removed as this feature is now enabled automatically.' + logger.warn( + 'The "future.unstable_cssModules" config option has been removed', + { + details: [ + "CSS Modules are now enabled automatically.", + "You should remove the `unstable_cssModules` option from your Remix config.", + ], + key: "unstable_cssModules", + } ); } if ("unstable_cssSideEffectImports" in appConfig.future) { - warnOnce( - 'The "future.unstable_cssSideEffectImports" config option has been removed as this feature is now enabled automatically.' + logger.warn( + 'The "future.unstable_cssSideEffectImports" config option has been removed', + { + details: [ + "CSS side-effect imports are now enabled automatically.", + "You should remove the `unstable_cssSideEffectImports` option from your Remix config", + ], + key: "unstable_cssSideEffectImports", + } ); } if ("unstable_vanillaExtract" in appConfig.future) { - warnOnce( - 'The "future.unstable_vanillaExtract" config option has been removed as this feature is now enabled automatically.' + logger.warn( + 'The "future.unstable_vanillaExtract" config option has been removed.', + { + details: [ + "Vanilla Extract is now enabled automatically.", + "You should remove the `unstable_vanillaExtract` option from your Remix config", + ], + key: "unstable_vanillaExtract", + } ); } if (appConfig.future.unstable_postcss !== undefined) { - warnOnce( - 'The "future.unstable_postcss" config option has been deprecated as this feature is now considered stable. Use the "postcss" config option instead.' + logger.warn( + 'The "future.unstable_postcss" config option has been deprecated.', + { + details: [ + "PostCSS support is now stable.", + "Use the `postcss` config option instead.", + ], + key: "unstable_postcss", + } ); } if (appConfig.future.unstable_tailwind !== undefined) { - warnOnce( - 'The "future.unstable_tailwind" config option has been deprecated as this feature is now considered stable. Use the "tailwind" config option instead.' + logger.warn( + 'The "future.unstable_tailwind" config option has been deprecated.', + { + details: [ + "Tailwind support is now stable.", + "Use the `tailwind` config option instead.", + ], + key: "unstable_tailwind", + } ); } } @@ -652,7 +687,7 @@ export async function readConfig( : path.resolve(defaultsDirectory, entryServerFile); if (appConfig.browserBuildDirectory) { - warnOnce(browserBuildDirectoryWarning, "browserBuildDirectory"); + browserBuildDirectoryWarning(); } let assetsBuildDirectory = @@ -690,7 +725,7 @@ export async function readConfig( if (appConfig.future?.v2_routeConvention) { routesConvention = flatRoutes; } else { - warnOnce(flatRoutesWarning, "v2_routeConvention"); + flatRoutesWarning(); routesConvention = defineConventionalRoutes; } @@ -835,7 +870,7 @@ const resolveServerBuildPath = ( // retain deprecated behavior for now if (appConfig.serverBuildDirectory) { - warnOnce(serverBuildDirectoryWarning, "serverBuildDirectory"); + serverBuildDirectoryWarning(); serverBuildPath = path.join(appConfig.serverBuildDirectory, "index.js"); } @@ -884,57 +919,87 @@ let disjunctionListFormat = new Intl.ListFormat("en", { type: "disjunction", }); -export let browserBuildDirectoryWarning = - "⚠️ REMIX FUTURE CHANGE: The `browserBuildDirectory` config option will be removed in v2. " + - "Use `assetsBuildDirectory` instead. " + - "For instructions on making this change see " + - "https://remix.run/docs/en/v1.15.0/pages/v2#browserbuilddirectory"; - -export let serverBuildDirectoryWarning = - "⚠️ REMIX FUTURE CHANGE: The `serverBuildDirectory` config option will be removed in v2. " + - "Use `serverBuildPath` instead. " + - "For instructions on making this change see " + - "https://remix.run/docs/en/v1.15.0/pages/v2#serverbuilddirectory"; - -export let serverBuildTargetWarning = - "⚠️ REMIX FUTURE CHANGE: The `serverBuildTarget` config option will be removed in v2. " + - "Use a combination of server module config values to achieve the same build output. " + - "For instructions on making this change see " + - "https://remix.run/docs/en/v1.15.0/pages/v2#serverbuildtarget"; - -export const serverModuleFormatWarning = - "⚠️ REMIX FUTURE CHANGE: The `serverModuleFormat` config default option will be changing in v2 " + - "from `cjs` to `esm`. You can prepare for this change by explicitly specifying `serverModuleFormat: 'cjs'`. " + - "For instructions on making this change see " + - "https://remix.run/docs/en/v1.16.0/pages/v2#servermoduleformat"; - -export let flatRoutesWarning = - "⚠️ REMIX FUTURE CHANGE: The route file convention is changing in v2. " + - "You can prepare for this change at your convenience with the `v2_routeConvention` future flag. " + - "For instructions on making this change see " + - "https://remix.run/docs/en/v1.15.0/pages/v2#file-system-route-convention"; - -export const errorBoundaryWarning = - "⚠️ REMIX FUTURE CHANGE: The behaviors of `CatchBoundary` and `ErrorBoundary` are changing in v2. " + - "You can prepare for this change at your convenience with the `v2_errorBoundary` future flag. " + - "For instructions on making this change see " + - "https://remix.run/docs/en/v1.15.0/pages/v2#catchboundary-and-errorboundary"; - -export const formMethodWarning = - "⚠️ REMIX FUTURE CHANGE: APIs that provide `formMethod` will be changing in v2. " + - "All values will be uppercase (GET, POST, etc.) instead of lowercase (get, post, etc.) " + - "You can prepare for this change at your convenience with the `v2_normalizeFormMethod` future flag. " + - "For instructions on making this change see " + - "https://remix.run/docs/en/v1.15.0/pages/v2#formMethod"; - -export const metaWarning = - "⚠️ REMIX FUTURE CHANGE: The route `meta` export signature is changing in v2. " + - "You can prepare for this change at your convenience with the `v2_meta` future flag. " + - "For instructions on making this change see " + - "https://remix.run/docs/en/v1.15.0/pages/v2#meta"; - -export const headersWarning = - "⚠️ REMIX FUTURE CHANGE: The route `headers` export behavior is changing in v2. " + - "You can prepare for this change at your convenience with the `v2_headers` future flag. " + - "For instructions on making this change see " + - "https://remix.run/docs/en/v1.17.0/pages/v2#route-headers"; +let browserBuildDirectoryWarning = () => + logger.warn( + "The `browserBuildDirectory` config option will be removed in v2", + { + details: [ + "You can use the `assetsBuildDirectory` config option instead.", + "-> https://remix.run/docs/en/v1.15.0/pages/v2#browserbuilddirectory", + ], + key: "browserBuildDirectoryWarning", + } + ); + +let serverBuildDirectoryWarning = () => + logger.warn( + "The `serverBuildDirectory` config option will be removed in v2", + { + details: [ + "You can use the `serverBuildPath` config option instead.", + "-> https://remix.run/docs/en/v1.15.0/pages/v2#serverbuilddirectory", + ], + key: "serverBuildDirectoryWarning", + } + ); + +let serverBuildTargetWarning = () => + logger.warn("The `serverBuildTarget` config option will be removed in v2", { + details: [ + "You can specify multiple server module config options instead to achieve the same result.", + "-> https://remix.run/docs/en/v1.15.0/pages/v2#serverbuildtarget", + ], + key: "serverBuildTargetWarning", + }); + +let serverModuleFormatWarning = () => + logger.warn("The default server module format is changing in v2", { + details: [ + "The default format will change from `cjs` to `esm`.", + "You can keep using `cjs` by explicitly specifying `serverModuleFormat: 'cjs'`.", + "You can opt-in early to this change by explicitly specifying `serverModuleFormat: 'esm'`", + "-> https://remix.run/docs/en/v1.16.0/pages/v2#servermoduleformat", + ], + key: "serverModuleFormatWarning", + }); + +let futureFlagWarning = + (args: { message: string; flag: string; link: string }) => () => { + logger.warn(args.message, { + key: args.flag, + details: [ + `You can use the \`${args.flag}\` future flag to opt-in early.`, + `-> ${args.link}`, + ], + }); + }; + +let flatRoutesWarning = futureFlagWarning({ + message: "The route file convention is changing in v2", + flag: "v2_routeConvention", + link: "https://remix.run/docs/en/v1.15.0/pages/v2#file-system-route-convention", +}); + +let errorBoundaryWarning = futureFlagWarning({ + message: "The `CatchBoundary` and `ErrorBoundary` API is changing in v2", + flag: "v2_errorBoundary", + link: "https://remix.run/docs/en/v1.15.0/pages/v2#catchboundary-and-errorboundary", +}); + +let formMethodWarning = futureFlagWarning({ + message: "The `formMethod` API is changing in v2", + flag: "v2_normalizeFormMethod", + link: "https://remix.run/docs/en/v1.15.0/pages/v2#formMethod", +}); + +let metaWarning = futureFlagWarning({ + message: "The route `meta` API is changing in v2", + flag: "v2_meta", + link: "https://remix.run/docs/en/v1.15.0/pages/v2#meta", +}); + +let headersWarning = futureFlagWarning({ + message: "The route `headers` API is changing in v2", + flag: "v2_headers", + link: "https://remix.run/docs/en/v1.17.0/pages/v2#route-headers", +}); From 1f7a5f48ecf4db04e48f1e2d9395b106c7df03f3 Mon Sep 17 00:00:00 2001 From: Pedro Cattori Date: Tue, 13 Jun 2023 13:11:41 -0400 Subject: [PATCH 11/12] test(flat-routes): do not depend on config internals --- integration/flat-routes-test.ts | 7 +++--- packages/remix-dev/__tests__/create-test.ts | 24 ++----------------- .../remix-dev/__tests__/readConfig-test.ts | 8 +------ 3 files changed, 7 insertions(+), 32 deletions(-) diff --git a/integration/flat-routes-test.ts b/integration/flat-routes-test.ts index f7c6ba13e52..8af9c20038e 100644 --- a/integration/flat-routes-test.ts +++ b/integration/flat-routes-test.ts @@ -5,7 +5,6 @@ import { PlaywrightFixture } from "./helpers/playwright-fixture"; import type { Fixture, AppFixture } from "./helpers/create-fixture"; import { createFixtureProject } from "./helpers/create-fixture"; import { createAppFixture, createFixture, js } from "./helpers/create-fixture"; -import { flatRoutesWarning } from "../packages/remix-dev/config"; let fixture: Fixture; let appFixture: AppFixture; @@ -159,7 +158,7 @@ test.describe("flat routes", () => { }); } - test("allows ignoredRouteFiles to be configured", async ({ page }) => { + test("allows ignoredRouteFiles to be configured", async () => { let routeIds = Object.keys(fixture.build.routes); expect(routeIds).not.toContain(IGNORED_ROUTE); @@ -210,7 +209,9 @@ test.describe("warns when v1 routesConvention is used", () => { test("v2_routeConvention is not enabled", () => { console.log(buildOutput); - expect(buildOutput).toContain(flatRoutesWarning); + expect(buildOutput).toContain( + "The route file convention is changing in v2" + ); }); }); diff --git a/packages/remix-dev/__tests__/create-test.ts b/packages/remix-dev/__tests__/create-test.ts index 15d6d7fcc59..1fdb00c6f24 100644 --- a/packages/remix-dev/__tests__/create-test.ts +++ b/packages/remix-dev/__tests__/create-test.ts @@ -8,14 +8,6 @@ import stripAnsi from "strip-ansi"; import { run } from "../cli/run"; import { server } from "./msw"; -import { - errorBoundaryWarning, - flatRoutesWarning, - formMethodWarning, - headersWarning, - metaWarning, - serverModuleFormatWarning, -} from "../config"; beforeAll(() => server.listen({ onUnhandledRequest: "error" })); afterAll(() => server.close()); @@ -354,20 +346,8 @@ describe("the create command", () => { "--no-install", "--no-typescript", ]); - expect(output.trim()).toBe( - errorBoundaryWarning + - "\n" + - formMethodWarning + - "\n" + - metaWarning + - "\n" + - headersWarning + - "\n" + - serverModuleFormatWarning + - "\n" + - flatRoutesWarning + - "\n\n" + - getOptOutOfInstallMessage() + + expect(output.trim()).toContain( + getOptOutOfInstallMessage() + "\n\n" + getSuccessMessage(path.join("", "template-to-js")) ); diff --git a/packages/remix-dev/__tests__/readConfig-test.ts b/packages/remix-dev/__tests__/readConfig-test.ts index 3267b8717ef..18d08dbf424 100644 --- a/packages/remix-dev/__tests__/readConfig-test.ts +++ b/packages/remix-dev/__tests__/readConfig-test.ts @@ -1,23 +1,17 @@ import path from "path"; import type { RemixConfig } from "../config"; -import { serverBuildTargetWarning, readConfig } from "../config"; +import { readConfig } from "../config"; const remixRoot = path.resolve(__dirname, "./fixtures/stack"); describe("readConfig", () => { let config: RemixConfig; - let warnStub; beforeEach(async () => { - let consoleWarn = console.warn; - warnStub = jest.fn(); - console.warn = warnStub; config = await readConfig(remixRoot); - console.warn = consoleWarn; }); it("generates a config", async () => { - expect(warnStub).toHaveBeenCalledWith(serverBuildTargetWarning); expect(config).toMatchInlineSnapshot( { rootDirectory: expect.any(String), From b35bd752bdb775e5d5fc2f9f53478e1c6470b87c Mon Sep 17 00:00:00 2001 From: Pedro Cattori Date: Tue, 13 Jun 2023 14:13:42 -0400 Subject: [PATCH 12/12] chore: changeset for improved logging --- .changeset/orange-beds-explode.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/orange-beds-explode.md diff --git a/.changeset/orange-beds-explode.md b/.changeset/orange-beds-explode.md new file mode 100644 index 00000000000..5fa009adcd8 --- /dev/null +++ b/.changeset/orange-beds-explode.md @@ -0,0 +1,5 @@ +--- +"@remix-run/dev": minor +--- + +improved logging for `remix build` and `remix dev`