From 096674f1ab1efcdada90fdcff9eae745b7a31792 Mon Sep 17 00:00:00 2001 From: Daniel Choudhury Date: Wed, 22 Feb 2023 15:59:36 +0700 Subject: [PATCH 01/42] Use async build --- packages/api-server/src/watch.ts | 4 +- packages/cli/src/commands/buildHandler.js | 4 +- packages/internal/src/build/api.ts | 72 ++++++++++++----------- 3 files changed, 42 insertions(+), 38 deletions(-) diff --git a/packages/api-server/src/watch.ts b/packages/api-server/src/watch.ts index e4c4003e0def..729586893ce7 100644 --- a/packages/api-server/src/watch.ts +++ b/packages/api-server/src/watch.ts @@ -62,14 +62,14 @@ const validate = async () => { } } -const rebuildApiServer = () => { +const rebuildApiServer = async () => { try { // Shutdown API server killApiServer() const buildTs = Date.now() process.stdout.write(c.dim(c.italic('Building... '))) - buildApi() + await buildApi() console.log(c.dim(c.italic('Took ' + (Date.now() - buildTs) + ' ms'))) const forkOpts = { diff --git a/packages/cli/src/commands/buildHandler.js b/packages/cli/src/commands/buildHandler.js index 38281403a5b8..251e0d5c416c 100644 --- a/packages/cli/src/commands/buildHandler.js +++ b/packages/cli/src/commands/buildHandler.js @@ -73,8 +73,8 @@ export const handler = async ({ }, side.includes('api') && { title: 'Building API...', - task: () => { - const { errors, warnings } = buildApi() + task: async () => { + const { errors, warnings } = await buildApi() if (errors.length) { console.error(errors) diff --git a/packages/internal/src/build/api.ts b/packages/internal/src/build/api.ts index 80be226f89f2..fe2d7994c14d 100644 --- a/packages/internal/src/build/api.ts +++ b/packages/internal/src/build/api.ts @@ -1,7 +1,8 @@ import fs from 'fs' import path from 'path' -import * as esbuild from 'esbuild' +import { build } from 'esbuild' +import type { PluginBuild } from 'esbuild' import { removeSync } from 'fs-extra' import { findApiFiles } from '../files' @@ -9,18 +10,18 @@ import { getPaths } from '../paths' import { getApiSideBabelPlugins, prebuildApiFile } from './babel/api' -export const buildApi = () => { +export const buildApi = async () => { // TODO: Be smarter about caching and invalidating files, // but right now we just delete everything. cleanApiBuild() const srcFiles = findApiFiles() - const prebuiltFiles = prebuildApiFiles(srcFiles).filter( - (path): path is string => path !== undefined - ) + // const prebuiltFiles = prebuildApiFiles(srcFiles).filter( + // (path): path is string => path !== undefined + // ) - return transpileApi(prebuiltFiles) + return await transpileApi(srcFiles) } export const cleanApiBuild = () => { @@ -29,44 +30,47 @@ export const cleanApiBuild = () => { removeSync(path.join(rwjsPaths.generated.prebuild, 'api')) } -/** - * Remove RedwoodJS "magic" from a user's code leaving JavaScript behind. - */ -export const prebuildApiFiles = (srcFiles: string[]) => { - const rwjsPaths = getPaths() - const plugins = getApiSideBabelPlugins() - - return srcFiles.map((srcPath) => { - const relativePathFromSrc = path.relative(rwjsPaths.base, srcPath) - const dstPath = path - .join(rwjsPaths.generated.prebuild, relativePathFromSrc) - .replace(/\.(ts)$/, '.js') - - const result = prebuildApiFile(srcPath, dstPath, plugins) - if (!result?.code) { - // TODO: Figure out a better way to return these programatically. - console.warn('Error:', srcPath, 'could not prebuilt.') - - return undefined - } - - fs.mkdirSync(path.dirname(dstPath), { recursive: true }) - fs.writeFileSync(dstPath, result.code) - - return dstPath - }) +const runRwBabelTransformsPlugin = { + name: 'rw-babel-transform', + setup(build: PluginBuild) { + build.onLoad({ filter: /.(js|ts|tsx|jsx)$/ }, async (args) => { + const rwjsPaths = getPaths() + + const relativePathFromSrc = path.relative(rwjsPaths.base, args.path) + const dstPath = path + .join(rwjsPaths.generated.prebuild, relativePathFromSrc) + .replace(/\.(ts)$/, '.js') + + // * Remove RedwoodJS "magic" from a user's code leaving JavaScript behind. + const transformedCode = prebuildApiFile( + args.path, + dstPath, + getApiSideBabelPlugins() + ) + + if (transformedCode?.code) { + return { + contents: transformedCode.code, + loader: 'js', + } + } + + throw new Error(`Could not transform file: ${args.path}`) + }) + }, } -export const transpileApi = (files: string[], options = {}) => { +export const transpileApi = async (files: string[], options = {}) => { const rwjsPaths = getPaths() - return esbuild.buildSync({ + return await build({ absWorkingDir: rwjsPaths.api.base, entryPoints: files, platform: 'node', target: 'node16', format: 'cjs', bundle: false, + plugins: [runRwBabelTransformsPlugin], outdir: rwjsPaths.api.dist, // setting this to 'true' will generate an external sourcemap x.js.map // AND set the sourceMappingURL comment From cd49f303d8703ef1ccfce715fa48586a4b7caff3 Mon Sep 17 00:00:00 2001 From: Daniel Choudhury Date: Wed, 22 Feb 2023 16:38:26 +0700 Subject: [PATCH 02/42] Fix tests --- .../internal/src/__tests__/build_api.test.ts | 28 ++++++++++++++++++- packages/internal/src/build/api.ts | 1 - 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/packages/internal/src/__tests__/build_api.test.ts b/packages/internal/src/__tests__/build_api.test.ts index 54bb1e3d048f..eb9915593d5f 100644 --- a/packages/internal/src/__tests__/build_api.test.ts +++ b/packages/internal/src/__tests__/build_api.test.ts @@ -4,7 +4,8 @@ import path from 'path' import * as babel from '@babel/core' import compat from 'core-js-compat' -import { cleanApiBuild, prebuildApiFiles } from '../build/api' +import { cleanApiBuild } from '../build/api' +import { prebuildApiFile } from '../build/babel/api' import { getApiSideBabelConfigPath, getApiSideBabelPlugins, @@ -20,6 +21,31 @@ const FIXTURE_PATH = path.resolve( '../../../../__fixtures__/example-todo-main' ) +export const prebuildApiFiles = (srcFiles: string[]) => { + const rwjsPaths = getPaths() + const plugins = getApiSideBabelPlugins() + + return srcFiles.map((srcPath) => { + const relativePathFromSrc = path.relative(rwjsPaths.base, srcPath) + const dstPath = path + .join(rwjsPaths.generated.prebuild, relativePathFromSrc) + .replace(/\.(ts)$/, '.js') + + const result = prebuildApiFile(srcPath, dstPath, plugins) + if (!result?.code) { + // TODO: Figure out a better way to return these programatically. + console.warn('Error:', srcPath, 'could not prebuilt.') + + return undefined + } + + fs.mkdirSync(path.dirname(dstPath), { recursive: true }) + fs.writeFileSync(dstPath, result.code) + + return dstPath + }) +} + const cleanPaths = (p) => { return ensurePosixPath(path.relative(FIXTURE_PATH, p)) } diff --git a/packages/internal/src/build/api.ts b/packages/internal/src/build/api.ts index fe2d7994c14d..9fc039455440 100644 --- a/packages/internal/src/build/api.ts +++ b/packages/internal/src/build/api.ts @@ -1,4 +1,3 @@ -import fs from 'fs' import path from 'path' import { build } from 'esbuild' From b3ece6781ed744922985f4943bbedffd008a30b4 Mon Sep 17 00:00:00 2001 From: Daniel Choudhury Date: Wed, 22 Feb 2023 17:34:15 +0700 Subject: [PATCH 03/42] Remove graphql-tag plugin because it doesnt work anyway --- packages/internal/package.json | 1 - packages/internal/src/build/babel/api.ts | 7 ------- yarn.lock | 1 - 3 files changed, 9 deletions(-) diff --git a/packages/internal/package.json b/packages/internal/package.json index 7ceb65d354ce..f1d141b466e5 100644 --- a/packages/internal/package.json +++ b/packages/internal/package.json @@ -43,7 +43,6 @@ "@graphql-codegen/typescript-resolvers": "3.0.0", "@iarna/toml": "2.2.5", "@redwoodjs/graphql-server": "4.0.0", - "babel-plugin-graphql-tag": "3.3.0", "babel-plugin-polyfill-corejs3": "0.6.0", "chalk": "4.1.2", "core-js": "3.28.0", diff --git a/packages/internal/src/build/babel/api.ts b/packages/internal/src/build/babel/api.ts index 380925ad8559..c66d57c7ac98 100644 --- a/packages/internal/src/build/babel/api.ts +++ b/packages/internal/src/build/babel/api.ts @@ -144,13 +144,6 @@ export const getApiSideBabelPlugins = ({ forJest } = { forJest: false }) => { }, 'rwjs-babel-auto-import', ], - // FIXME: `graphql-tag` is not working: https://github.com/redwoodjs/redwood/pull/3193 - ['babel-plugin-graphql-tag', undefined, 'rwjs-babel-graphql-tag'], - [ - require('../babelPlugins/babel-plugin-redwood-import-dir').default, - undefined, - 'rwjs-babel-glob-import-dir', - ], ].filter(Boolean) as PluginItem[] return plugins diff --git a/yarn.lock b/yarn.lock index 4263582bd6b0..97a8c6ef2a7f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7102,7 +7102,6 @@ __metadata: "@types/findup-sync": 4.0.2 "@types/fs-extra": 11.0.1 "@types/rimraf": 3.0.2 - babel-plugin-graphql-tag: 3.3.0 babel-plugin-polyfill-corejs3: 0.6.0 babel-plugin-tester: 11.0.4 chalk: 4.1.2 From 7f1c72102fe44582aab3d849bc61b131cfbdbf75 Mon Sep 17 00:00:00 2001 From: Daniel Choudhury Date: Wed, 22 Feb 2023 17:36:30 +0700 Subject: [PATCH 04/42] Explain use of prebuildApiFiles --- packages/internal/src/__tests__/build_api.test.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/internal/src/__tests__/build_api.test.ts b/packages/internal/src/__tests__/build_api.test.ts index eb9915593d5f..f3aa0c5866f8 100644 --- a/packages/internal/src/__tests__/build_api.test.ts +++ b/packages/internal/src/__tests__/build_api.test.ts @@ -21,6 +21,9 @@ const FIXTURE_PATH = path.resolve( '../../../../__fixtures__/example-todo-main' ) +// @NOTE: we no longer prebuild files into the .redwood/prebuild folder +// However, prebuilding in the tests still helpful for us to validate +// that everything is working as expected. export const prebuildApiFiles = (srcFiles: string[]) => { const rwjsPaths = getPaths() const plugins = getApiSideBabelPlugins() @@ -33,10 +36,7 @@ export const prebuildApiFiles = (srcFiles: string[]) => { const result = prebuildApiFile(srcPath, dstPath, plugins) if (!result?.code) { - // TODO: Figure out a better way to return these programatically. - console.warn('Error:', srcPath, 'could not prebuilt.') - - return undefined + throw new Error(`Could not prebuild ${srcPath}`) } fs.mkdirSync(path.dirname(dstPath), { recursive: true }) From bd2c9858ccf835696e875171e6a4a1e40aa8f1bd Mon Sep 17 00:00:00 2001 From: Daniel Choudhury Date: Wed, 22 Feb 2023 17:37:36 +0700 Subject: [PATCH 05/42] Rename prebuild function --- packages/internal/src/__tests__/build_api.test.ts | 4 ++-- packages/internal/src/build/api.ts | 4 ++-- packages/internal/src/build/babel/api.ts | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/internal/src/__tests__/build_api.test.ts b/packages/internal/src/__tests__/build_api.test.ts index f3aa0c5866f8..c76d670b1cb0 100644 --- a/packages/internal/src/__tests__/build_api.test.ts +++ b/packages/internal/src/__tests__/build_api.test.ts @@ -5,7 +5,7 @@ import * as babel from '@babel/core' import compat from 'core-js-compat' import { cleanApiBuild } from '../build/api' -import { prebuildApiFile } from '../build/babel/api' +import { transformWithBabel } from '../build/babel/api' import { getApiSideBabelConfigPath, getApiSideBabelPlugins, @@ -34,7 +34,7 @@ export const prebuildApiFiles = (srcFiles: string[]) => { .join(rwjsPaths.generated.prebuild, relativePathFromSrc) .replace(/\.(ts)$/, '.js') - const result = prebuildApiFile(srcPath, dstPath, plugins) + const result = transformWithBabel(srcPath, dstPath, plugins) if (!result?.code) { throw new Error(`Could not prebuild ${srcPath}`) } diff --git a/packages/internal/src/build/api.ts b/packages/internal/src/build/api.ts index 9fc039455440..0382499ddd97 100644 --- a/packages/internal/src/build/api.ts +++ b/packages/internal/src/build/api.ts @@ -7,7 +7,7 @@ import { removeSync } from 'fs-extra' import { findApiFiles } from '../files' import { getPaths } from '../paths' -import { getApiSideBabelPlugins, prebuildApiFile } from './babel/api' +import { getApiSideBabelPlugins, transformWithBabel } from './babel/api' export const buildApi = async () => { // TODO: Be smarter about caching and invalidating files, @@ -41,7 +41,7 @@ const runRwBabelTransformsPlugin = { .replace(/\.(ts)$/, '.js') // * Remove RedwoodJS "magic" from a user's code leaving JavaScript behind. - const transformedCode = prebuildApiFile( + const transformedCode = transformWithBabel( args.path, dstPath, getApiSideBabelPlugins() diff --git a/packages/internal/src/build/babel/api.ts b/packages/internal/src/build/babel/api.ts index c66d57c7ac98..2eed22876bda 100644 --- a/packages/internal/src/build/babel/api.ts +++ b/packages/internal/src/build/babel/api.ts @@ -187,7 +187,7 @@ export const registerApiSideBabelHook = ({ }) } -export const prebuildApiFile = ( +export const transformWithBabel = ( srcPath: string, // we need to know dstPath as well // so we can generate an inline, relative sourcemap From 9c8fbdeee68a1e162daeb79f1d646483f9c68fa5 Mon Sep 17 00:00:00 2001 From: Daniel Choudhury Date: Wed, 22 Feb 2023 17:49:11 +0700 Subject: [PATCH 06/42] Remove redundant code --- packages/internal/src/build/api.ts | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/packages/internal/src/build/api.ts b/packages/internal/src/build/api.ts index 0382499ddd97..c54d9d9a64af 100644 --- a/packages/internal/src/build/api.ts +++ b/packages/internal/src/build/api.ts @@ -13,14 +13,7 @@ export const buildApi = async () => { // TODO: Be smarter about caching and invalidating files, // but right now we just delete everything. cleanApiBuild() - - const srcFiles = findApiFiles() - - // const prebuiltFiles = prebuildApiFiles(srcFiles).filter( - // (path): path is string => path !== undefined - // ) - - return await transpileApi(srcFiles) + return await transpileApi(findApiFiles()) } export const cleanApiBuild = () => { From 00a4a850e514024d1998ecf66471c3b2e3a8d82d Mon Sep 17 00:00:00 2001 From: Daniel Choudhury Date: Wed, 22 Feb 2023 18:06:49 +0700 Subject: [PATCH 07/42] Revert "Remove graphql-tag plugin because it doesnt work anyway" This reverts commit b3ece6781ed744922985f4943bbedffd008a30b4. --- packages/internal/package.json | 1 + packages/internal/src/build/babel/api.ts | 7 +++++++ yarn.lock | 1 + 3 files changed, 9 insertions(+) diff --git a/packages/internal/package.json b/packages/internal/package.json index f1d141b466e5..7ceb65d354ce 100644 --- a/packages/internal/package.json +++ b/packages/internal/package.json @@ -43,6 +43,7 @@ "@graphql-codegen/typescript-resolvers": "3.0.0", "@iarna/toml": "2.2.5", "@redwoodjs/graphql-server": "4.0.0", + "babel-plugin-graphql-tag": "3.3.0", "babel-plugin-polyfill-corejs3": "0.6.0", "chalk": "4.1.2", "core-js": "3.28.0", diff --git a/packages/internal/src/build/babel/api.ts b/packages/internal/src/build/babel/api.ts index 2eed22876bda..e2175fc944a7 100644 --- a/packages/internal/src/build/babel/api.ts +++ b/packages/internal/src/build/babel/api.ts @@ -144,6 +144,13 @@ export const getApiSideBabelPlugins = ({ forJest } = { forJest: false }) => { }, 'rwjs-babel-auto-import', ], + // FIXME: `graphql-tag` is not working: https://github.com/redwoodjs/redwood/pull/3193 + ['babel-plugin-graphql-tag', undefined, 'rwjs-babel-graphql-tag'], + [ + require('../babelPlugins/babel-plugin-redwood-import-dir').default, + undefined, + 'rwjs-babel-glob-import-dir', + ], ].filter(Boolean) as PluginItem[] return plugins diff --git a/yarn.lock b/yarn.lock index 97a8c6ef2a7f..4263582bd6b0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7102,6 +7102,7 @@ __metadata: "@types/findup-sync": 4.0.2 "@types/fs-extra": 11.0.1 "@types/rimraf": 3.0.2 + babel-plugin-graphql-tag: 3.3.0 babel-plugin-polyfill-corejs3: 0.6.0 babel-plugin-tester: 11.0.4 chalk: 4.1.2 From 893283324b6548f054f286e94ef6e1e8adcd704a Mon Sep 17 00:00:00 2001 From: Daniel Choudhury Date: Thu, 23 Feb 2023 17:28:18 +0700 Subject: [PATCH 08/42] Fix failing nftPack test --- packages/cli/src/commands/deploy/__tests__/nftPack.test.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/cli/src/commands/deploy/__tests__/nftPack.test.js b/packages/cli/src/commands/deploy/__tests__/nftPack.test.js index a3f79a6e8572..6bd8fd15f26b 100644 --- a/packages/cli/src/commands/deploy/__tests__/nftPack.test.js +++ b/packages/cli/src/commands/deploy/__tests__/nftPack.test.js @@ -13,12 +13,12 @@ const FIXTURE_PATH = path.resolve( let functionDistFiles -beforeAll(() => { +beforeAll(async () => { process.env.RWJS_CWD = FIXTURE_PATH // Actually build the fixture, if we need it if (!fs.existsSync(path.join(FIXTURE_PATH, 'api/dist/functions'))) { - buildApi() + await buildApi() } functionDistFiles = findApiDistFunctions() From 480a2578c8845a4eec040624487422ce50ea4422 Mon Sep 17 00:00:00 2001 From: Daniel Choudhury Date: Thu, 23 Feb 2023 17:35:38 +0700 Subject: [PATCH 09/42] Fix sourcemaps/debugging with breakpoints --- packages/internal/src/build/api.ts | 14 +++----------- packages/internal/src/build/babel/api.ts | 6 ------ 2 files changed, 3 insertions(+), 17 deletions(-) diff --git a/packages/internal/src/build/api.ts b/packages/internal/src/build/api.ts index c54d9d9a64af..55dea9e2b427 100644 --- a/packages/internal/src/build/api.ts +++ b/packages/internal/src/build/api.ts @@ -13,7 +13,7 @@ export const buildApi = async () => { // TODO: Be smarter about caching and invalidating files, // but right now we just delete everything. cleanApiBuild() - return await transpileApi(findApiFiles()) + return transpileApi(findApiFiles()) } export const cleanApiBuild = () => { @@ -23,20 +23,12 @@ export const cleanApiBuild = () => { } const runRwBabelTransformsPlugin = { - name: 'rw-babel-transform', + name: 'rw-esbuild-babel-transform', setup(build: PluginBuild) { build.onLoad({ filter: /.(js|ts|tsx|jsx)$/ }, async (args) => { - const rwjsPaths = getPaths() - - const relativePathFromSrc = path.relative(rwjsPaths.base, args.path) - const dstPath = path - .join(rwjsPaths.generated.prebuild, relativePathFromSrc) - .replace(/\.(ts)$/, '.js') - - // * Remove RedwoodJS "magic" from a user's code leaving JavaScript behind. + // Remove RedwoodJS "magic" from a user's code leaving JavaScript behind. const transformedCode = transformWithBabel( args.path, - dstPath, getApiSideBabelPlugins() ) diff --git a/packages/internal/src/build/babel/api.ts b/packages/internal/src/build/babel/api.ts index e2175fc944a7..c2d1d37fe670 100644 --- a/packages/internal/src/build/babel/api.ts +++ b/packages/internal/src/build/babel/api.ts @@ -196,9 +196,6 @@ export const registerApiSideBabelHook = ({ export const transformWithBabel = ( srcPath: string, - // we need to know dstPath as well - // so we can generate an inline, relative sourcemap - dstPath: string, plugins: TransformOptions['plugins'] ) => { const code = fs.readFileSync(srcPath, 'utf-8') @@ -208,9 +205,6 @@ export const transformWithBabel = ( ...defaultOptions, cwd: getPaths().api.base, filename: srcPath, - // we set the sourceFile (for the sourcemap) as a correct, relative path - // this is why this function (prebuildFile) must know about the dstPath - sourceFileName: path.relative(path.dirname(dstPath), srcPath), // we need inline sourcemaps at this level // because this file will eventually be fed to esbuild // when esbuild finds an inline sourcemap, it tries to "combine" it From 3f84ed2e220fe5f6e06ca06d123859e0a82bfb30 Mon Sep 17 00:00:00 2001 From: Daniel Choudhury Date: Thu, 23 Feb 2023 17:58:32 +0700 Subject: [PATCH 10/42] Fix api build test --- packages/internal/src/__tests__/build_api.test.ts | 2 +- packages/internal/src/build/api.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/internal/src/__tests__/build_api.test.ts b/packages/internal/src/__tests__/build_api.test.ts index c76d670b1cb0..62ccc0597ed3 100644 --- a/packages/internal/src/__tests__/build_api.test.ts +++ b/packages/internal/src/__tests__/build_api.test.ts @@ -34,7 +34,7 @@ export const prebuildApiFiles = (srcFiles: string[]) => { .join(rwjsPaths.generated.prebuild, relativePathFromSrc) .replace(/\.(ts)$/, '.js') - const result = transformWithBabel(srcPath, dstPath, plugins) + const result = transformWithBabel(srcPath, plugins) if (!result?.code) { throw new Error(`Could not prebuild ${srcPath}`) } diff --git a/packages/internal/src/build/api.ts b/packages/internal/src/build/api.ts index 55dea9e2b427..e1abbeba8a6f 100644 --- a/packages/internal/src/build/api.ts +++ b/packages/internal/src/build/api.ts @@ -47,7 +47,7 @@ const runRwBabelTransformsPlugin = { export const transpileApi = async (files: string[], options = {}) => { const rwjsPaths = getPaths() - return await build({ + return build({ absWorkingDir: rwjsPaths.api.base, entryPoints: files, platform: 'node', From d86822e42d34c548f7473257f755ffd849ca0de5 Mon Sep 17 00:00:00 2001 From: Daniel Choudhury Date: Fri, 24 Feb 2023 15:06:27 +0700 Subject: [PATCH 11/42] Try disabling telemetry on CLI tests --- packages/cli/jest.config.js | 1 + packages/cli/jest.setup.js | 1 + 2 files changed, 2 insertions(+) create mode 100644 packages/cli/jest.setup.js diff --git a/packages/cli/jest.config.js b/packages/cli/jest.config.js index 96d2e376cabf..d8510c5e51c1 100644 --- a/packages/cli/jest.config.js +++ b/packages/cli/jest.config.js @@ -1,6 +1,7 @@ module.exports = { testMatch: ['**/__tests__/**/*.[jt]s?(x)', '**/*.test.[jt]s?(x)'], testPathIgnorePatterns: ['fixtures', 'dist'], + setupFilesAfterEnv: ['./jest.setup.js'], moduleNameMapper: { '^src/(.*)': '/src/$1', }, diff --git a/packages/cli/jest.setup.js b/packages/cli/jest.setup.js new file mode 100644 index 000000000000..43f90f67c504 --- /dev/null +++ b/packages/cli/jest.setup.js @@ -0,0 +1 @@ +process.env.REDWOOD_DISABLE_TELEMETRY = 1 From f2ebf215e42f5629a06ff72bbaa0f7b461423c92 Mon Sep 17 00:00:00 2001 From: Daniel Choudhury Date: Fri, 24 Feb 2023 16:33:41 +0700 Subject: [PATCH 12/42] Try mocking telemetry --- packages/cli/jest.config.js | 1 + packages/cli/jest.setup.js | 10 +++++++++- packages/cli/src/commands/__tests__/build.test.js | 4 ++-- packages/cli/src/commands/buildHandler.js | 3 +++ packages/telemetry/src/telemetry.ts | 2 +- 5 files changed, 16 insertions(+), 4 deletions(-) diff --git a/packages/cli/jest.config.js b/packages/cli/jest.config.js index d8510c5e51c1..c9a3ea6f02a9 100644 --- a/packages/cli/jest.config.js +++ b/packages/cli/jest.config.js @@ -1,3 +1,4 @@ +/** @type {import('jest').Config} */ module.exports = { testMatch: ['**/__tests__/**/*.[jt]s?(x)', '**/*.test.[jt]s?(x)'], testPathIgnorePatterns: ['fixtures', 'dist'], diff --git a/packages/cli/jest.setup.js b/packages/cli/jest.setup.js index 43f90f67c504..d53d7aaa22d6 100644 --- a/packages/cli/jest.setup.js +++ b/packages/cli/jest.setup.js @@ -1 +1,9 @@ -process.env.REDWOOD_DISABLE_TELEMETRY = 1 +// process.env.REDWOOD_DISABLE_TELEMETRY = '1' +jest.mock('@redwoodjs/telemetry', () => { + return { + errorTelemetry: () => {}, + timedTelemetry: async (_argv, _options, func) => { + return await func() + }, + } +}) diff --git a/packages/cli/src/commands/__tests__/build.test.js b/packages/cli/src/commands/__tests__/build.test.js index cda0c2b82069..64dc5bf41784 100644 --- a/packages/cli/src/commands/__tests__/build.test.js +++ b/packages/cli/src/commands/__tests__/build.test.js @@ -72,7 +72,7 @@ test('Should run prerender for web', async () => { // Run prerendering task, but expect warning, // because `detectPrerenderRoutes` is empty. expect(consoleSpy.mock.calls[0][0]).toBe('Starting prerendering...') - expect(consoleSpy.mock.calls[1][0]).toBe( - 'You have not marked any routes to "prerender" in your Routes (​file:///mocked/project/web/Routes.tsx​).' + expect(consoleSpy.mock.calls[1][0]).toMatch( + /You have not marked any routes to "prerender"/ ) }) diff --git a/packages/cli/src/commands/buildHandler.js b/packages/cli/src/commands/buildHandler.js index 251e0d5c416c..ed716539543d 100644 --- a/packages/cli/src/commands/buildHandler.js +++ b/packages/cli/src/commands/buildHandler.js @@ -134,7 +134,10 @@ export const handler = async ({ 'file://' + rwjsPaths.web.routes )}.` ) + + return } + // Running a separate process here, otherwise it wouldn't pick up the // generated Prisma Client due to require module caching await execa('yarn rw prerender', { diff --git a/packages/telemetry/src/telemetry.ts b/packages/telemetry/src/telemetry.ts index da5d9313aa04..d81e05a33d27 100644 --- a/packages/telemetry/src/telemetry.ts +++ b/packages/telemetry/src/telemetry.ts @@ -47,7 +47,7 @@ export const timedTelemetry = async ( func: (...args: any[]) => any ) => { if (process.env.REDWOOD_DISABLE_TELEMETRY) { - return func.call(this) + return await func.call(this) } const start = new Date() From 113ce60ac67152a68fd6ffdf8e047d71c0ee597c Mon Sep 17 00:00:00 2001 From: Daniel Choudhury Date: Fri, 24 Feb 2023 16:37:27 +0700 Subject: [PATCH 13/42] Add "." to esbuild filter --- packages/internal/src/build/api.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/internal/src/build/api.ts b/packages/internal/src/build/api.ts index e1abbeba8a6f..bfd90bad8298 100644 --- a/packages/internal/src/build/api.ts +++ b/packages/internal/src/build/api.ts @@ -25,7 +25,7 @@ export const cleanApiBuild = () => { const runRwBabelTransformsPlugin = { name: 'rw-esbuild-babel-transform', setup(build: PluginBuild) { - build.onLoad({ filter: /.(js|ts|tsx|jsx)$/ }, async (args) => { + build.onLoad({ filter: /\.(js|ts|tsx|jsx)$/ }, async (args) => { // Remove RedwoodJS "magic" from a user's code leaving JavaScript behind. const transformedCode = transformWithBabel( args.path, From dc03ee15138a54adeeafea00746566ef13fbfe9a Mon Sep 17 00:00:00 2001 From: Daniel Choudhury Date: Fri, 24 Feb 2023 17:18:17 +0700 Subject: [PATCH 14/42] Remove prebuild --- packages/internal/src/build/api.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/internal/src/build/api.ts b/packages/internal/src/build/api.ts index bfd90bad8298..282c94d85497 100644 --- a/packages/internal/src/build/api.ts +++ b/packages/internal/src/build/api.ts @@ -19,7 +19,6 @@ export const buildApi = async () => { export const cleanApiBuild = () => { const rwjsPaths = getPaths() removeSync(rwjsPaths.api.dist) - removeSync(path.join(rwjsPaths.generated.prebuild, 'api')) } const runRwBabelTransformsPlugin = { From 0f8f8b23fe051f0ec5fe0a5dec71234150995d40 Mon Sep 17 00:00:00 2001 From: Daniel Choudhury Date: Fri, 24 Feb 2023 17:37:36 +0700 Subject: [PATCH 15/42] Remove unused import --- packages/internal/src/build/api.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/internal/src/build/api.ts b/packages/internal/src/build/api.ts index 282c94d85497..1148dd43bbf5 100644 --- a/packages/internal/src/build/api.ts +++ b/packages/internal/src/build/api.ts @@ -1,7 +1,5 @@ -import path from 'path' - -import { build } from 'esbuild' import type { PluginBuild } from 'esbuild' +import { build } from 'esbuild' import { removeSync } from 'fs-extra' import { findApiFiles } from '../files' From 4863387c13c1f22745c244036e56ee2c7163b145 Mon Sep 17 00:00:00 2001 From: Daniel Choudhury Date: Fri, 24 Feb 2023 17:42:46 +0700 Subject: [PATCH 16/42] Increase test timeout --- packages/cli/jest.config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/cli/jest.config.js b/packages/cli/jest.config.js index c9a3ea6f02a9..6ad6f602b4e1 100644 --- a/packages/cli/jest.config.js +++ b/packages/cli/jest.config.js @@ -6,5 +6,5 @@ module.exports = { moduleNameMapper: { '^src/(.*)': '/src/$1', }, - testTimeout: 15000, + testTimeout: 60000, } From 5d6557ec906a4c9662f27262941c80b013bf888d Mon Sep 17 00:00:00 2001 From: Tobbe Lundberg Date: Fri, 31 Mar 2023 18:40:57 +0700 Subject: [PATCH 17/42] Mock FS in tests --- .../commands/deploy/__tests__/nftPack.test.js | 47 ++++++++++--------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/packages/cli/src/commands/deploy/__tests__/nftPack.test.js b/packages/cli/src/commands/deploy/__tests__/nftPack.test.js index 6bd8fd15f26b..3430d4ef6630 100644 --- a/packages/cli/src/commands/deploy/__tests__/nftPack.test.js +++ b/packages/cli/src/commands/deploy/__tests__/nftPack.test.js @@ -1,31 +1,32 @@ -import fs from 'fs' -import path from 'path' - -import { buildApi } from '@redwoodjs/internal/dist/build/api' import { findApiDistFunctions } from '@redwoodjs/internal/dist/files' import nftPacker from '../packing/nft' -const FIXTURE_PATH = path.resolve( - __dirname, - '../../../../../../__fixtures__/example-todo-main' -) - -let functionDistFiles - -beforeAll(async () => { - process.env.RWJS_CWD = FIXTURE_PATH - - // Actually build the fixture, if we need it - if (!fs.existsSync(path.join(FIXTURE_PATH, 'api/dist/functions'))) { - await buildApi() +jest.mock('@redwoodjs/internal/dist/files', () => { + return { + findApiDistFunctions: () => { + return [ + '/Users/carmack/dev/redwood/__fixtures__/example-todo-main/api/dist/functions/graphql.js', + '/Users/carmack/dev/redwood/__fixtures__/example-todo-main/api/dist/functions/healthz/healthz.js', + '/Users/carmack/dev/redwood/__fixtures__/example-todo-main/api/dist/functions/invalid/x.js', + '/Users/carmack/dev/redwood/__fixtures__/example-todo-main/api/dist/functions/nested/nested.js', + '/Users/carmack/dev/redwood/__fixtures__/example-todo-main/api/dist/functions/x/index.js', + ] + }, } - - functionDistFiles = findApiDistFunctions() }) -afterAll(() => { - delete process.env.RWJS_CWD +jest.mock('@redwoodjs/internal/dist/paths', () => { + return { + getPaths: () => { + return { + base: '/Users/carmack/dev/redwood/__fixtures__/example-todo-main/', + } + }, + ensurePosixPath: (path) => { + return path + }, + } }) test('Check packager detects all functions', () => { @@ -39,7 +40,7 @@ test('Check packager detects all functions', () => { }) test('Creates entry file for nested functions correctly', () => { - const nestedFunction = functionDistFiles.find((fPath) => + const nestedFunction = findApiDistFunctions().find((fPath) => fPath.includes('nested') ) @@ -55,7 +56,7 @@ test('Creates entry file for nested functions correctly', () => { }) test('Creates entry file for top level functions correctly', () => { - const graphqlFunction = functionDistFiles.find((fPath) => + const graphqlFunction = findApiDistFunctions().find((fPath) => fPath.includes('graphql') ) From 5b8fdd2724b6ecf5f26c6d44d702218f9978194f Mon Sep 17 00:00:00 2001 From: Tobbe Lundberg Date: Fri, 31 Mar 2023 19:03:49 +0700 Subject: [PATCH 18/42] Fix test after merge --- packages/cli/src/commands/deploy/__tests__/nftPack.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/cli/src/commands/deploy/__tests__/nftPack.test.js b/packages/cli/src/commands/deploy/__tests__/nftPack.test.js index 3430d4ef6630..c69a62754a82 100644 --- a/packages/cli/src/commands/deploy/__tests__/nftPack.test.js +++ b/packages/cli/src/commands/deploy/__tests__/nftPack.test.js @@ -16,7 +16,7 @@ jest.mock('@redwoodjs/internal/dist/files', () => { } }) -jest.mock('@redwoodjs/internal/dist/paths', () => { +jest.mock('@redwoodjs/project-config', () => { return { getPaths: () => { return { From fd575ba82cf9cbbaf45eae08db55412de5889332 Mon Sep 17 00:00:00 2001 From: Tobbe Lundberg Date: Fri, 31 Mar 2023 19:17:07 +0700 Subject: [PATCH 19/42] Fix merge conflicts --- packages/cli/jest.config.js | 1 - packages/cli/jsconfig.json | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/cli/jest.config.js b/packages/cli/jest.config.js index f895c3c6092f..6ad6f602b4e1 100644 --- a/packages/cli/jest.config.js +++ b/packages/cli/jest.config.js @@ -7,5 +7,4 @@ module.exports = { '^src/(.*)': '/src/$1', }, testTimeout: 60000, - setupFilesAfterEnv: ['./jest.setup.js'], } diff --git a/packages/cli/jsconfig.json b/packages/cli/jsconfig.json index 0b2607fe6cfc..1b8d45ca0773 100644 --- a/packages/cli/jsconfig.json +++ b/packages/cli/jsconfig.json @@ -12,7 +12,6 @@ { "path": "../project-config" }, { "path": "../structure" }, { "path": "../prerender" }, - { "path": "../api-server" }, - { "path": "../auth-providers-setup" }, + { "path": "../api-server" } ] } From de923aec01b619b3540fce77c44b5ee355f3a6d7 Mon Sep 17 00:00:00 2001 From: Tobbe Lundberg Date: Fri, 31 Mar 2023 19:28:22 +0700 Subject: [PATCH 20/42] Fix merge conflicts --- packages/internal/src/__tests__/build_api.test.ts | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/packages/internal/src/__tests__/build_api.test.ts b/packages/internal/src/__tests__/build_api.test.ts index 214b710919fb..5c90d9965f4a 100644 --- a/packages/internal/src/__tests__/build_api.test.ts +++ b/packages/internal/src/__tests__/build_api.test.ts @@ -6,11 +6,12 @@ import compat from 'core-js-compat' import { ensurePosixPath, getPaths } from '@redwoodjs/project-config' -import { cleanApiBuild, prebuildApiFiles } from '../build/api' +import { cleanApiBuild } from '../build/api' import { getApiSideBabelConfigPath, getApiSideBabelPlugins, getApiSideDefaultBabelConfig, + transformWithBabel, BABEL_PLUGIN_TRANSFORM_RUNTIME_OPTIONS, TARGETS_NODE, } from '../build/babel/api' @@ -115,6 +116,10 @@ test.skip('api prebuild transforms gql with `babel-plugin-graphql-tag`', () => { .filter((p) => p.endsWith('todos.sdl.js')) .pop() + if (!p) { + throw new Error('No built files') + } + const code = fs.readFileSync(p, 'utf-8') expect(code.includes('import gql from "graphql-tag";')).toEqual(false) expect(code.includes('gql`')).toEqual(false) @@ -518,7 +523,7 @@ test('jest mock statements also handle', () => { cwd: getPaths().api.base, // We override the plugins, to match packages/testing/config/jest/api/index.js plugins: getApiSideBabelPlugins({ forJest: true }), - }).code + })?.code // Step 2: check that output has correct import statement path expect(outputForJest).toContain('import dog from "../../lib/dog"') @@ -528,10 +533,13 @@ test('jest mock statements also handle', () => { test('core-js polyfill list', () => { const { list } = compat({ + // @ts-expect-error TODO: Figure out why this is needed targets: { node: TARGETS_NODE }, + // @ts-expect-error TODO: Figure out why this is needed version: BABEL_PLUGIN_TRANSFORM_RUNTIME_OPTIONS.corejs.version, }) + // TODO: Node.js 12? Really? /** * Redwood targets Node.js 12, but that doesn't factor into what gets polyfilled * because Redwood uses the plugin-transform-runtime polyfill strategy. From 3010ad9b8508d054deb53dc66bfb968aee781206 Mon Sep 17 00:00:00 2001 From: Tobbe Lundberg Date: Sat, 1 Apr 2023 01:03:23 +0700 Subject: [PATCH 21/42] fix tests on windows --- packages/cli/src/commands/deploy/__tests__/nftPack.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/cli/src/commands/deploy/__tests__/nftPack.test.js b/packages/cli/src/commands/deploy/__tests__/nftPack.test.js index c69a62754a82..62e859a49c6a 100644 --- a/packages/cli/src/commands/deploy/__tests__/nftPack.test.js +++ b/packages/cli/src/commands/deploy/__tests__/nftPack.test.js @@ -24,7 +24,7 @@ jest.mock('@redwoodjs/project-config', () => { } }, ensurePosixPath: (path) => { - return path + return path.replace(/\\/g, '/') }, } }) From 333cac871900472944ca323ffd5edddca16eb302 Mon Sep 17 00:00:00 2001 From: Daniel Choudhury Date: Mon, 3 Apr 2023 13:30:11 +0700 Subject: [PATCH 22/42] Undo jest config change --- packages/cli/jest.config.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/cli/jest.config.js b/packages/cli/jest.config.js index 6ad6f602b4e1..a1ed78aa66e1 100644 --- a/packages/cli/jest.config.js +++ b/packages/cli/jest.config.js @@ -1,10 +1,9 @@ -/** @type {import('jest').Config} */ module.exports = { testMatch: ['**/__tests__/**/*.[jt]s?(x)', '**/*.test.[jt]s?(x)'], testPathIgnorePatterns: ['fixtures', 'dist'], - setupFilesAfterEnv: ['./jest.setup.js'], moduleNameMapper: { '^src/(.*)': '/src/$1', }, - testTimeout: 60000, + testTimeout: 15000, + setupFilesAfterEnv: ['./jest.setup.js'], } From 9bac85bf33155bfa3a4ea78f31a38f9a7b84cc29 Mon Sep 17 00:00:00 2001 From: Daniel Choudhury Date: Mon, 3 Apr 2023 13:38:43 +0700 Subject: [PATCH 23/42] Undo telemetry change --- packages/telemetry/src/telemetry.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/telemetry/src/telemetry.ts b/packages/telemetry/src/telemetry.ts index e7436962a2f3..5b8f98346480 100644 --- a/packages/telemetry/src/telemetry.ts +++ b/packages/telemetry/src/telemetry.ts @@ -47,7 +47,7 @@ export const timedTelemetry = async ( func: (...args: any[]) => any ) => { if (process.env.REDWOOD_DISABLE_TELEMETRY) { - return await func.call(this) + return func.call(this) } const start = new Date() From 4aa171cdbc18f30d06b1131b2a31b24f381d16cc Mon Sep 17 00:00:00 2001 From: Daniel Choudhury Date: Thu, 28 Dec 2023 15:04:17 +0700 Subject: [PATCH 24/42] Fix tests --- .../src/__tests__/prebuildApiFile.test.ts | 176 +++++++++--------- packages/babel-config/src/api.ts | 24 --- packages/babel-config/src/index.ts | 1 - .../commands/deploy/__tests__/nftPack.test.js | 5 - packages/internal/src/build/api.ts | 4 +- 5 files changed, 90 insertions(+), 120 deletions(-) diff --git a/packages/babel-config/src/__tests__/prebuildApiFile.test.ts b/packages/babel-config/src/__tests__/prebuildApiFile.test.ts index 3bfadf7a4368..cf69fb69de71 100644 --- a/packages/babel-config/src/__tests__/prebuildApiFile.test.ts +++ b/packages/babel-config/src/__tests__/prebuildApiFile.test.ts @@ -2,13 +2,13 @@ import path from 'path' import compat from 'core-js-compat' -import { getPaths, getConfig } from '@redwoodjs/project-config' +import { getConfig } from '@redwoodjs/project-config' import { BABEL_PLUGIN_TRANSFORM_RUNTIME_OPTIONS, - getApiSideBabelPlugins, - prebuildApiFile, TARGETS_NODE, + getApiSideBabelPlugins, + transformWithBabel, } from '../api' const RWJS_CWD = path.join(__dirname, '__fixtures__/redwood-app') @@ -386,7 +386,7 @@ describe('api prebuild ', () => { expect(sources).toMatchInlineSnapshot(` [ - "../../../../../api/src/lib/polyfill.js", + "polyfill.js", ] `) }) @@ -463,84 +463,84 @@ describe('api prebuild ', () => { * Some "ES Next" polyfills have landed in v12+ Node.js versions. */ expect(list).toMatchInlineSnapshot(` - [ - "esnext.array.last-index", - "esnext.array.last-item", - "esnext.composite-key", - "esnext.composite-symbol", - "esnext.map.delete-all", - "esnext.map.every", - "esnext.map.filter", - "esnext.map.find", - "esnext.map.find-key", - "esnext.map.from", - "esnext.map.group-by", - "esnext.map.includes", - "esnext.map.key-by", - "esnext.map.key-of", - "esnext.map.map-keys", - "esnext.map.map-values", - "esnext.map.merge", - "esnext.map.of", - "esnext.map.reduce", - "esnext.map.some", - "esnext.map.update", - "esnext.math.clamp", - "esnext.math.deg-per-rad", - "esnext.math.degrees", - "esnext.math.fscale", - "esnext.math.iaddh", - "esnext.math.imulh", - "esnext.math.isubh", - "esnext.math.rad-per-deg", - "esnext.math.radians", - "esnext.math.scale", - "esnext.math.seeded-prng", - "esnext.math.signbit", - "esnext.math.umulh", - "esnext.number.from-string", - "esnext.observable", - "esnext.promise.try", - "esnext.reflect.define-metadata", - "esnext.reflect.delete-metadata", - "esnext.reflect.get-metadata", - "esnext.reflect.get-metadata-keys", - "esnext.reflect.get-own-metadata", - "esnext.reflect.get-own-metadata-keys", - "esnext.reflect.has-metadata", - "esnext.reflect.has-own-metadata", - "esnext.reflect.metadata", - "esnext.set.add-all", - "esnext.set.delete-all", - "esnext.set.difference", - "esnext.set.every", - "esnext.set.filter", - "esnext.set.find", - "esnext.set.from", - "esnext.set.intersection", - "esnext.set.is-disjoint-from", - "esnext.set.is-subset-of", - "esnext.set.is-superset-of", - "esnext.set.join", - "esnext.set.map", - "esnext.set.of", - "esnext.set.reduce", - "esnext.set.some", - "esnext.set.symmetric-difference", - "esnext.set.union", - "esnext.string.at", - "esnext.string.code-points", - "esnext.symbol.observable", - "esnext.symbol.pattern-match", - "esnext.weak-map.delete-all", - "esnext.weak-map.from", - "esnext.weak-map.of", - "esnext.weak-set.add-all", - "esnext.weak-set.delete-all", - "esnext.weak-set.from", - "esnext.weak-set.of", - ] - `) + [ + "esnext.array.last-index", + "esnext.array.last-item", + "esnext.composite-key", + "esnext.composite-symbol", + "esnext.map.delete-all", + "esnext.map.every", + "esnext.map.filter", + "esnext.map.find", + "esnext.map.find-key", + "esnext.map.from", + "esnext.map.group-by", + "esnext.map.includes", + "esnext.map.key-by", + "esnext.map.key-of", + "esnext.map.map-keys", + "esnext.map.map-values", + "esnext.map.merge", + "esnext.map.of", + "esnext.map.reduce", + "esnext.map.some", + "esnext.map.update", + "esnext.math.clamp", + "esnext.math.deg-per-rad", + "esnext.math.degrees", + "esnext.math.fscale", + "esnext.math.iaddh", + "esnext.math.imulh", + "esnext.math.isubh", + "esnext.math.rad-per-deg", + "esnext.math.radians", + "esnext.math.scale", + "esnext.math.seeded-prng", + "esnext.math.signbit", + "esnext.math.umulh", + "esnext.number.from-string", + "esnext.observable", + "esnext.promise.try", + "esnext.reflect.define-metadata", + "esnext.reflect.delete-metadata", + "esnext.reflect.get-metadata", + "esnext.reflect.get-metadata-keys", + "esnext.reflect.get-own-metadata", + "esnext.reflect.get-own-metadata-keys", + "esnext.reflect.has-metadata", + "esnext.reflect.has-own-metadata", + "esnext.reflect.metadata", + "esnext.set.add-all", + "esnext.set.delete-all", + "esnext.set.difference", + "esnext.set.every", + "esnext.set.filter", + "esnext.set.find", + "esnext.set.from", + "esnext.set.intersection", + "esnext.set.is-disjoint-from", + "esnext.set.is-subset-of", + "esnext.set.is-superset-of", + "esnext.set.join", + "esnext.set.map", + "esnext.set.of", + "esnext.set.reduce", + "esnext.set.some", + "esnext.set.symmetric-difference", + "esnext.set.union", + "esnext.string.at", + "esnext.string.code-points", + "esnext.symbol.observable", + "esnext.symbol.pattern-match", + "esnext.weak-map.delete-all", + "esnext.weak-map.from", + "esnext.weak-map.of", + "esnext.weak-set.add-all", + "esnext.weak-set.delete-all", + "esnext.weak-set.from", + "esnext.weak-set.of", + ] + `) }) }) @@ -549,19 +549,19 @@ describe('api prebuild ', () => { * This will be re-architected, but doing so now would introduce breaking changes. */ export const prebuildApiFileWrapper = (srcFile: string) => { - const redwoodProjectPaths = getPaths() + // const redwoodProjectPaths = getPaths() const plugins = getApiSideBabelPlugins({ openTelemetry: getConfig().experimental.opentelemetry.enabled, }) - const relativePathFromSrc = path.relative(redwoodProjectPaths.base, srcFile) + // const relativePathFromSrc = path.relative(redwoodProjectPaths.base, srcFile) - const dstPath = path - .join(redwoodProjectPaths.generated.prebuild, relativePathFromSrc) - .replace(/\.(ts)$/, '.js') + // const dstPath = path + // .join(redwoodProjectPaths.generated.prebuild, relativePathFromSrc) + // .replace(/\.(ts)$/, '.js') - const result = prebuildApiFile(srcFile, dstPath, plugins) + const result = transformWithBabel(srcFile, plugins) if (!result?.code) { throw new Error(`Couldn't prebuild ${srcFile}`) diff --git a/packages/babel-config/src/api.ts b/packages/babel-config/src/api.ts index 0e61d8f0cc53..79b29a906009 100644 --- a/packages/babel-config/src/api.ts +++ b/packages/babel-config/src/api.ts @@ -208,27 +208,3 @@ export const transformWithBabel = ( }) return result } - -// TODO (STREAMING) I changed the prebuildApiFile function in https://github.com/redwoodjs/redwood/pull/7672/files -// but we had to revert. For this branch temporarily, I'm going to add a new function -// This is used in building routeHooks -export const transformWithBabel = ( - srcPath: string, - plugins: TransformOptions['plugins'] -) => { - const code = fs.readFileSync(srcPath, 'utf-8') - const defaultOptions = getApiSideDefaultBabelConfig() - - const result = transform(code, { - ...defaultOptions, - cwd: getPaths().api.base, - filename: srcPath, - // we need inline sourcemaps at this level - // because this file will eventually be fed to esbuild - // when esbuild finds an inline sourcemap, it tries to "combine" it - // so the final sourcemap (the one that esbuild generates) combines both mappings - sourceMaps: 'inline', - plugins, - }) - return result -} diff --git a/packages/babel-config/src/index.ts b/packages/babel-config/src/index.ts index 0c4d675cb117..7658f3e7a67c 100644 --- a/packages/babel-config/src/index.ts +++ b/packages/babel-config/src/index.ts @@ -9,7 +9,6 @@ export { getApiSideBabelPlugins, getApiSideBabelPresets, getApiSideDefaultBabelConfig, - prebuildApiFile, registerApiSideBabelHook, transformWithBabel, } from './api' diff --git a/packages/cli/src/commands/deploy/__tests__/nftPack.test.js b/packages/cli/src/commands/deploy/__tests__/nftPack.test.js index 3099422cf930..b1d90a728ce8 100644 --- a/packages/cli/src/commands/deploy/__tests__/nftPack.test.js +++ b/packages/cli/src/commands/deploy/__tests__/nftPack.test.js @@ -1,8 +1,3 @@ -import path from 'path' - -import fs from 'fs-extra' - -import { buildApi } from '@redwoodjs/internal/dist/build/api' import { findApiDistFunctions } from '@redwoodjs/internal/dist/files' import * as nftPacker from '../packing/nft' diff --git a/packages/internal/src/build/api.ts b/packages/internal/src/build/api.ts index 27947bb48ec0..b34cb2925708 100644 --- a/packages/internal/src/build/api.ts +++ b/packages/internal/src/build/api.ts @@ -22,11 +22,11 @@ export const cleanApiBuild = () => { removeSync(rwjsPaths.api.dist) } -const rwjsConfig = getConfig() - const runRwBabelTransformsPlugin = { name: 'rw-esbuild-babel-transform', setup(build: PluginBuild) { + const rwjsConfig = getConfig() + build.onLoad({ filter: /\.(js|ts|tsx|jsx)$/ }, async (args) => { // Remove RedwoodJS "magic" from a user's code leaving JavaScript behind. const transformedCode = transformWithBabel( From 4ced18aa99478a79149edb5093bc84c09f364637 Mon Sep 17 00:00:00 2001 From: Daniel Choudhury Date: Thu, 28 Dec 2023 20:01:20 +0700 Subject: [PATCH 25/42] Try using esbuild's watcher instead --- packages/api-server/src/watch.ts | 76 +++--------------------------- packages/internal/src/build/api.ts | 32 ++++++++----- 2 files changed, 27 insertions(+), 81 deletions(-) diff --git a/packages/api-server/src/watch.ts b/packages/api-server/src/watch.ts index 33ced351c4a2..5a192e201b05 100644 --- a/packages/api-server/src/watch.ts +++ b/packages/api-server/src/watch.ts @@ -1,26 +1,20 @@ #!/usr/bin/env node -import { fork } from 'child_process' import type { ChildProcess } from 'child_process' +import { fork } from 'child_process' import fs from 'fs' import path from 'path' import c from 'ansi-colors' import chalk from 'chalk' -import chokidar from 'chokidar' import dotenv from 'dotenv' import { debounce } from 'lodash' import { hideBin } from 'yargs/helpers' import yargs from 'yargs/yargs' -import { buildApi } from '@redwoodjs/internal/dist/build/api' +import { buildApi, watchApi } from '@redwoodjs/internal/dist/build/api' import { loadAndValidateSdls } from '@redwoodjs/internal/dist/validateSchema' -import { - getPaths, - ensurePosixPath, - getConfig, - resolveFile, -} from '@redwoodjs/project-config' +import { getConfig, getPaths, resolveFile } from '@redwoodjs/project-config' const argv = yargs(hideBin(process.argv)) .option('debug-port', { @@ -150,64 +144,6 @@ const delayRestartServer = debounce( : 5 ) -// NOTE: the file comes through as a unix path, even on windows -// So we need to convert the rwjsPaths - -const IGNORED_API_PATHS = [ - 'api/dist', // use this, because using rwjsPaths.api.dist seems to not ignore on first build - rwjsPaths.api.types, - rwjsPaths.api.db, -].map((path) => ensurePosixPath(path)) - -chokidar - .watch(rwjsPaths.api.base, { - persistent: true, - ignoreInitial: true, - ignored: (file: string) => { - const x = - file.includes('node_modules') || - IGNORED_API_PATHS.some((ignoredPath) => file.includes(ignoredPath)) || - [ - '.DS_Store', - '.db', - '.sqlite', - '-journal', - '.test.js', - '.test.ts', - '.scenarios.ts', - '.scenarios.js', - '.d.ts', - '.log', - ].some((ext) => file.endsWith(ext)) - return x - }, - }) - .on('ready', async () => { - rebuildApiServer() - await validate() - }) - .on('all', async (eventName, filePath) => { - // On sufficiently large projects (500+ files, or >= 2000 ms build times) on older machines, esbuild writing to the api directory - // makes chokidar emit an `addDir` event. This starts an infinite loop where the api starts building itself as soon as it's finished. - // This could probably be fixed with some sort of build caching. - if (eventName === 'addDir' && filePath === rwjsPaths.api.base) { - return - } - - // We validate here, so that developers will see the error - // As they're running the dev server - if (filePath.includes('.sdl')) { - const isValid = await validate() - - // Exit early if not valid - if (!isValid) { - return - } - } - - console.log( - c.dim(`[${eventName}] ${filePath.replace(rwjsPaths.api.base, '')}`) - ) - delayRestartServer.cancel() - delayRestartServer() - }) +// Use esbuild's watcher instead of chokidar +// Restarts seem to be handled by nodemon +watchApi() diff --git a/packages/internal/src/build/api.ts b/packages/internal/src/build/api.ts index b34cb2925708..d73b34ae5d0e 100644 --- a/packages/internal/src/build/api.ts +++ b/packages/internal/src/build/api.ts @@ -1,18 +1,16 @@ -import type { PluginBuild } from 'esbuild' -import { build } from 'esbuild' +import type { Format, Platform, PluginBuild } from 'esbuild' +import { build, context } from 'esbuild' import { removeSync } from 'fs-extra' import { getApiSideBabelPlugins, transformWithBabel, } from '@redwoodjs/babel-config' -import { getPaths, getConfig } from '@redwoodjs/project-config' +import { getConfig, getPaths } from '@redwoodjs/project-config' import { findApiFiles } from '../files' export const buildApi = async () => { - // TODO: Be smarter about caching and invalidating files, - // but right now we just delete everything. cleanApiBuild() return transpileApi(findApiFiles()) } @@ -50,15 +48,28 @@ const runRwBabelTransformsPlugin = { }, } -export const transpileApi = async (files: string[], options = {}) => { +export const watchApi = async () => { + const apiFiles = findApiFiles() + + const esbCtx = await context(getEsbuildOptions(apiFiles)) + + return esbCtx.watch() +} + +export const transpileApi = async (files: string[]) => { + return build(getEsbuildOptions(files)) +} + +function getEsbuildOptions(files: string[]) { const rwjsPaths = getPaths() - return build({ + return { absWorkingDir: rwjsPaths.api.base, entryPoints: files, - platform: 'node', + platform: 'node' as Platform, target: 'node20', - format: 'cjs', + format: 'cjs' as Format, + allowOverwrite: true, bundle: false, plugins: [runRwBabelTransformsPlugin], outdir: rwjsPaths.api.dist, @@ -66,6 +77,5 @@ export const transpileApi = async (files: string[], options = {}) => { // AND set the sourceMappingURL comment // (setting it to 'external' will ONLY generate the file, but won't add the comment) sourcemap: true, - ...options, - }) + } } From 47822bf7546610ac54ad00e19387c2bcf0aa10d8 Mon Sep 17 00:00:00 2001 From: Daniel Choudhury Date: Thu, 28 Dec 2023 20:31:23 +0700 Subject: [PATCH 26/42] Hacky poc --- packages/api-server/src/watch.ts | 36 ++++++++++++++---------------- packages/internal/src/build/api.ts | 23 ++++++++++++++----- 2 files changed, 35 insertions(+), 24 deletions(-) diff --git a/packages/api-server/src/watch.ts b/packages/api-server/src/watch.ts index 5a192e201b05..e95b443fb611 100644 --- a/packages/api-server/src/watch.ts +++ b/packages/api-server/src/watch.ts @@ -1,4 +1,5 @@ #!/usr/bin/env node +/* eslint-disable @typescript-eslint/no-unused-vars */ import type { ChildProcess } from 'child_process' import { fork } from 'child_process' @@ -13,7 +14,6 @@ import { hideBin } from 'yargs/helpers' import yargs from 'yargs/yargs' import { buildApi, watchApi } from '@redwoodjs/internal/dist/build/api' -import { loadAndValidateSdls } from '@redwoodjs/internal/dist/validateSchema' import { getConfig, getPaths, resolveFile } from '@redwoodjs/project-config' const argv = yargs(hideBin(process.argv)) @@ -37,9 +37,6 @@ dotenv.config({ path: rwjsPaths.base, }) -// TODO: -// 1. Move this file out of the HTTP server, and place it in the CLI? - let httpServerProcess: ChildProcess const killApiServer = () => { @@ -47,20 +44,21 @@ const killApiServer = () => { httpServerProcess?.kill() } -const validate = async () => { - try { - await loadAndValidateSdls() - return true - } catch (e: any) { - killApiServer() - console.log(c.redBright(`[GQL Server Error] - Schema validation failed`)) - console.error(c.red(e?.message)) - console.log(c.redBright('-'.repeat(40))) - - delayRestartServer.cancel() - return false - } -} +// @TODO need to enable validation +// const validate = async () => { +// try { +// await loadAndValidateSdls() +// return true +// } catch (e: any) { +// killApiServer() +// console.log(c.redBright(`[GQL Server Error] - Schema validation failed`)) +// console.error(c.red(e?.message)) +// console.log(c.redBright('-'.repeat(40))) + +// delayRestartServer.cancel() +// return false +// } +// } const rebuildApiServer = async () => { try { @@ -146,4 +144,4 @@ const delayRestartServer = debounce( // Use esbuild's watcher instead of chokidar // Restarts seem to be handled by nodemon -watchApi() +watchApi(delayRestartServer) diff --git a/packages/internal/src/build/api.ts b/packages/internal/src/build/api.ts index d73b34ae5d0e..e6da3b7719a9 100644 --- a/packages/internal/src/build/api.ts +++ b/packages/internal/src/build/api.ts @@ -48,19 +48,32 @@ const runRwBabelTransformsPlugin = { }, } -export const watchApi = async () => { +const createBuildEndPlugin = (cb: Function) => ({ + name: 'buildEndPLugin', + setup(build: PluginBuild) { + // const rwjsConfig = getConfig() + + build.onEnd(async (result) => { + console.log(`πŸ‘‰ \n ~ file: api.ts:57 ~ result:`, result) + + await cb() + }) + }, +}) + +export const watchApi = async (cb: Function) => { const apiFiles = findApiFiles() - const esbCtx = await context(getEsbuildOptions(apiFiles)) + const esbCtx = await context(getEsbuildOptions(apiFiles, cb)) return esbCtx.watch() } export const transpileApi = async (files: string[]) => { - return build(getEsbuildOptions(files)) + return build(getEsbuildOptions(files, () => {})) } -function getEsbuildOptions(files: string[]) { +function getEsbuildOptions(files: string[], cb: Function) { const rwjsPaths = getPaths() return { @@ -71,7 +84,7 @@ function getEsbuildOptions(files: string[]) { format: 'cjs' as Format, allowOverwrite: true, bundle: false, - plugins: [runRwBabelTransformsPlugin], + plugins: [runRwBabelTransformsPlugin, createBuildEndPlugin(cb)], outdir: rwjsPaths.api.dist, // setting this to 'true' will generate an external sourcemap x.js.map // AND set the sourceMappingURL comment From 213fbf7fc2f7d433439886ef054ff4f7e29c7411 Mon Sep 17 00:00:00 2001 From: Daniel Choudhury Date: Thu, 28 Dec 2023 22:12:41 +0700 Subject: [PATCH 27/42] Remove incorrect comment --- packages/api-server/src/watch.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/api-server/src/watch.ts b/packages/api-server/src/watch.ts index e95b443fb611..87db1978a775 100644 --- a/packages/api-server/src/watch.ts +++ b/packages/api-server/src/watch.ts @@ -143,5 +143,4 @@ const delayRestartServer = debounce( ) // Use esbuild's watcher instead of chokidar -// Restarts seem to be handled by nodemon watchApi(delayRestartServer) From cc1d7dfe536e2c0e3e43cb29235e04ea21e94d8c Mon Sep 17 00:00:00 2001 From: Daniel Choudhury Date: Fri, 29 Dec 2023 15:46:35 +0700 Subject: [PATCH 28/42] Try esbuild rebuild with chokidar --- packages/api-server/src/watch.ts | 120 +++++++++++++++++++++++------ packages/internal/src/build/api.ts | 18 ++++- 2 files changed, 112 insertions(+), 26 deletions(-) diff --git a/packages/api-server/src/watch.ts b/packages/api-server/src/watch.ts index 87db1978a775..6bea7f03e875 100644 --- a/packages/api-server/src/watch.ts +++ b/packages/api-server/src/watch.ts @@ -1,20 +1,27 @@ #!/usr/bin/env node -/* eslint-disable @typescript-eslint/no-unused-vars */ -import type { ChildProcess } from 'child_process' import { fork } from 'child_process' +import type { ChildProcess } from 'child_process' import fs from 'fs' import path from 'path' import c from 'ansi-colors' import chalk from 'chalk' +import chokidar from 'chokidar' import dotenv from 'dotenv' import { debounce } from 'lodash' import { hideBin } from 'yargs/helpers' import yargs from 'yargs/yargs' -import { buildApi, watchApi } from '@redwoodjs/internal/dist/build/api' -import { getConfig, getPaths, resolveFile } from '@redwoodjs/project-config' +import { buildApi, rebuildApi } from '@redwoodjs/internal/dist/build/api' +import { loadAndValidateSdls } from '@redwoodjs/internal/dist/validateSchema' +import { + getPaths, + ensurePosixPath, + getConfig, + resolveFile, + getConfigPath, +} from '@redwoodjs/project-config' const argv = yargs(hideBin(process.argv)) .option('debug-port', { @@ -44,30 +51,34 @@ const killApiServer = () => { httpServerProcess?.kill() } -// @TODO need to enable validation -// const validate = async () => { -// try { -// await loadAndValidateSdls() -// return true -// } catch (e: any) { -// killApiServer() -// console.log(c.redBright(`[GQL Server Error] - Schema validation failed`)) -// console.error(c.red(e?.message)) -// console.log(c.redBright('-'.repeat(40))) - -// delayRestartServer.cancel() -// return false -// } -// } - -const rebuildApiServer = async () => { +const validate = async () => { + try { + await loadAndValidateSdls() + return true + } catch (e: any) { + killApiServer() + console.log(c.redBright(`[GQL Server Error] - Schema validation failed`)) + console.error(c.red(e?.message)) + console.log(c.redBright('-'.repeat(40))) + + delayRestartServer.cancel() + return false + } +} + +const rebuildApiServer = (rebuild = false) => { try { // Shutdown API server killApiServer() const buildTs = Date.now() process.stdout.write(c.dim(c.italic('Building... '))) - await buildApi() + + if (rebuild) { + rebuildApi() + } else { + buildApi() + } console.log(c.dim(c.italic('Took ' + (Date.now() - buildTs) + ' ms'))) const forkOpts = { @@ -136,11 +147,70 @@ const rebuildApiServer = async () => { // Local writes are very fast, but writes in e2e environments are not, // so allow the default to be adjust with a env-var. const delayRestartServer = debounce( - rebuildApiServer, + () => rebuildApiServer(true), process.env.RWJS_DELAY_RESTART ? parseInt(process.env.RWJS_DELAY_RESTART, 10) : 5 ) -// Use esbuild's watcher instead of chokidar -watchApi(delayRestartServer) +// NOTE: the file comes through as a unix path, even on windows +// So we need to convert the rwjsPaths + +const IGNORED_API_PATHS = [ + 'api/dist', // use this, because using rwjsPaths.api.dist seems to not ignore on first build + rwjsPaths.api.types, + rwjsPaths.api.db, +].map((path) => ensurePosixPath(path)) + +chokidar + .watch([rwjsPaths.api.src, getConfigPath()], { + persistent: true, + ignoreInitial: true, + ignored: (file: string) => { + const x = + file.includes('node_modules') || + IGNORED_API_PATHS.some((ignoredPath) => file.includes(ignoredPath)) || + [ + '.DS_Store', + '.db', + '.sqlite', + '-journal', + '.test.js', + '.test.ts', + '.scenarios.ts', + '.scenarios.js', + '.d.ts', + '.log', + ].some((ext) => file.endsWith(ext)) + return x + }, + }) + .on('ready', async () => { + rebuildApiServer() + await validate() + }) + .on('all', async (eventName, filePath) => { + // On sufficiently large projects (500+ files, or >= 2000 ms build times) on older machines, esbuild writing to the api directory + // makes chokidar emit an `addDir` event. This starts an infinite loop where the api starts building itself as soon as it's finished. + // This could probably be fixed with some sort of build caching. + if (eventName === 'addDir' && filePath === rwjsPaths.api.base) { + return + } + + // We validate here, so that developers will see the error + // As they're running the dev server + if (filePath.includes('.sdl')) { + const isValid = await validate() + + // Exit early if not valid + if (!isValid) { + return + } + } + + console.log( + c.dim(`[${eventName}] ${filePath.replace(rwjsPaths.api.base, '')}`) + ) + delayRestartServer.cancel() + delayRestartServer() + }) diff --git a/packages/internal/src/build/api.ts b/packages/internal/src/build/api.ts index e6da3b7719a9..7c130d23fa79 100644 --- a/packages/internal/src/build/api.ts +++ b/packages/internal/src/build/api.ts @@ -1,4 +1,4 @@ -import type { Format, Platform, PluginBuild } from 'esbuild' +import type { Format, Platform, PluginBuild, BuildContext } from 'esbuild' import { build, context } from 'esbuild' import { removeSync } from 'fs-extra' @@ -10,11 +10,27 @@ import { getConfig, getPaths } from '@redwoodjs/project-config' import { findApiFiles } from '../files' +let BUILD_CTX: BuildContext | null = null + export const buildApi = async () => { cleanApiBuild() return transpileApi(findApiFiles()) } +export const rebuildApi = async () => { + const apiFiles = findApiFiles() + + if (!BUILD_CTX) { + BUILD_CTX = await context(getEsbuildOptions(apiFiles, () => {})) + } + + console.log('definitely rebuilding!!') + console.log('definitely rebuilding!!') + console.log('definitely rebuilding!!') + console.log('definitely rebuilding!!') + return BUILD_CTX.rebuild() +} + export const cleanApiBuild = () => { const rwjsPaths = getPaths() removeSync(rwjsPaths.api.dist) From 2c9b6088ccd4ccf73486efc90c032e4a5247aa92 Mon Sep 17 00:00:00 2001 From: Daniel Choudhury Date: Fri, 29 Dec 2023 16:11:56 +0700 Subject: [PATCH 29/42] Try removing second level nodemon --- packages/cli/src/commands/devHandler.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/cli/src/commands/devHandler.js b/packages/cli/src/commands/devHandler.js index e4ed83085460..8a4317f27459 100644 --- a/packages/cli/src/commands/devHandler.js +++ b/packages/cli/src/commands/devHandler.js @@ -178,7 +178,9 @@ export const handler = async ({ const jobs = { api: { name: 'api', - command: `yarn cross-env NODE_ENV=development NODE_OPTIONS="${getDevNodeOptions()}" yarn nodemon --quiet --watch "${redwoodConfigPath}" --exec "yarn rw-api-server-watch --port ${apiAvailablePort} ${getApiDebugFlag()} | rw-log-formatter"`, + command: `yarn cross-env NODE_ENV=development NODE_OPTIONS="${getDevNodeOptions()}" node ${require.resolve( + '@redwoodjs/api-server/dist/watch.js' + )} --port ${apiAvailablePort} ${getApiDebugFlag()}`, prefixColor: 'cyan', runWhen: () => fs.existsSync(rwjsPaths.api.src), }, From 48127638efd62ca8d143020f4e16609745ed3c35 Mon Sep 17 00:00:00 2001 From: Daniel Choudhury Date: Fri, 29 Dec 2023 17:35:12 +0700 Subject: [PATCH 30/42] Restore nodemon for now --- packages/cli/src/commands/devHandler.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/cli/src/commands/devHandler.js b/packages/cli/src/commands/devHandler.js index 8a4317f27459..e4ed83085460 100644 --- a/packages/cli/src/commands/devHandler.js +++ b/packages/cli/src/commands/devHandler.js @@ -178,9 +178,7 @@ export const handler = async ({ const jobs = { api: { name: 'api', - command: `yarn cross-env NODE_ENV=development NODE_OPTIONS="${getDevNodeOptions()}" node ${require.resolve( - '@redwoodjs/api-server/dist/watch.js' - )} --port ${apiAvailablePort} ${getApiDebugFlag()}`, + command: `yarn cross-env NODE_ENV=development NODE_OPTIONS="${getDevNodeOptions()}" yarn nodemon --quiet --watch "${redwoodConfigPath}" --exec "yarn rw-api-server-watch --port ${apiAvailablePort} ${getApiDebugFlag()} | rw-log-formatter"`, prefixColor: 'cyan', runWhen: () => fs.existsSync(rwjsPaths.api.src), }, From 2377778e0210d73ede905dbda00a30b4fa5f05f9 Mon Sep 17 00:00:00 2001 From: Daniel Choudhury Date: Fri, 29 Dec 2023 17:38:10 +0700 Subject: [PATCH 31/42] Differenciate rebuild and build --- packages/api-server/src/watch.ts | 47 ++++++++++++++++++++---------- packages/internal/src/build/api.ts | 32 +++++--------------- 2 files changed, 39 insertions(+), 40 deletions(-) diff --git a/packages/api-server/src/watch.ts b/packages/api-server/src/watch.ts index 6bea7f03e875..12a3ced03159 100644 --- a/packages/api-server/src/watch.ts +++ b/packages/api-server/src/watch.ts @@ -1,7 +1,7 @@ #!/usr/bin/env node -import { fork } from 'child_process' import type { ChildProcess } from 'child_process' +import { fork } from 'child_process' import fs from 'fs' import path from 'path' @@ -16,11 +16,10 @@ import yargs from 'yargs/yargs' import { buildApi, rebuildApi } from '@redwoodjs/internal/dist/build/api' import { loadAndValidateSdls } from '@redwoodjs/internal/dist/validateSchema' import { - getPaths, ensurePosixPath, getConfig, + getPaths, resolveFile, - getConfigPath, } from '@redwoodjs/project-config' const argv = yargs(hideBin(process.argv)) @@ -61,7 +60,8 @@ const validate = async () => { console.error(c.red(e?.message)) console.log(c.redBright('-'.repeat(40))) - delayRestartServer.cancel() + debouncedBuild.cancel() + debouncedRebuild.cancel() return false } } @@ -146,13 +146,20 @@ const rebuildApiServer = (rebuild = false) => { // this usually happens when running RedwoodJS generator commands. // Local writes are very fast, but writes in e2e environments are not, // so allow the default to be adjust with a env-var. -const delayRestartServer = debounce( +const debouncedRebuild = debounce( () => rebuildApiServer(true), process.env.RWJS_DELAY_RESTART ? parseInt(process.env.RWJS_DELAY_RESTART, 10) : 5 ) +const debouncedBuild = debounce( + () => rebuildApiServer(false), + process.env.RWJS_DELAY_RESTART + ? parseInt(process.env.RWJS_DELAY_RESTART, 10) + : 5 +) + // NOTE: the file comes through as a unix path, even on windows // So we need to convert the rwjsPaths @@ -163,7 +170,7 @@ const IGNORED_API_PATHS = [ ].map((path) => ensurePosixPath(path)) chokidar - .watch([rwjsPaths.api.src, getConfigPath()], { + .watch([rwjsPaths.api.src], { persistent: true, ignoreInitial: true, ignored: (file: string) => { @@ -197,20 +204,30 @@ chokidar return } - // We validate here, so that developers will see the error - // As they're running the dev server - if (filePath.includes('.sdl')) { - const isValid = await validate() + if (eventName) { + if (filePath.includes('.sdl')) { + // We validate here, so that developers will see the error + // As they're running the dev server + const isValid = await validate() - // Exit early if not valid - if (!isValid) { - return + // Exit early if not valid + if (!isValid) { + return + } } } console.log( c.dim(`[${eventName}] ${filePath.replace(rwjsPaths.api.base, '')}`) ) - delayRestartServer.cancel() - delayRestartServer() + + if (eventName === 'add' || eventName === 'unlink') { + debouncedBuild.cancel() + debouncedRebuild.cancel() + debouncedBuild() + } else { + // If files have just changed, then rebuild + debouncedRebuild.cancel() + debouncedRebuild() + } }) diff --git a/packages/internal/src/build/api.ts b/packages/internal/src/build/api.ts index 7c130d23fa79..62d1df036c91 100644 --- a/packages/internal/src/build/api.ts +++ b/packages/internal/src/build/api.ts @@ -14,6 +14,9 @@ let BUILD_CTX: BuildContext | null = null export const buildApi = async () => { cleanApiBuild() + // Reset the build context for rebuildling + BUILD_CTX = null + return transpileApi(findApiFiles()) } @@ -21,7 +24,7 @@ export const rebuildApi = async () => { const apiFiles = findApiFiles() if (!BUILD_CTX) { - BUILD_CTX = await context(getEsbuildOptions(apiFiles, () => {})) + BUILD_CTX = await context(getEsbuildOptions(apiFiles)) } console.log('definitely rebuilding!!') @@ -64,32 +67,11 @@ const runRwBabelTransformsPlugin = { }, } -const createBuildEndPlugin = (cb: Function) => ({ - name: 'buildEndPLugin', - setup(build: PluginBuild) { - // const rwjsConfig = getConfig() - - build.onEnd(async (result) => { - console.log(`πŸ‘‰ \n ~ file: api.ts:57 ~ result:`, result) - - await cb() - }) - }, -}) - -export const watchApi = async (cb: Function) => { - const apiFiles = findApiFiles() - - const esbCtx = await context(getEsbuildOptions(apiFiles, cb)) - - return esbCtx.watch() -} - export const transpileApi = async (files: string[]) => { - return build(getEsbuildOptions(files, () => {})) + return build(getEsbuildOptions(files)) } -function getEsbuildOptions(files: string[], cb: Function) { +function getEsbuildOptions(files: string[]) { const rwjsPaths = getPaths() return { @@ -100,7 +82,7 @@ function getEsbuildOptions(files: string[], cb: Function) { format: 'cjs' as Format, allowOverwrite: true, bundle: false, - plugins: [runRwBabelTransformsPlugin, createBuildEndPlugin(cb)], + plugins: [runRwBabelTransformsPlugin], outdir: rwjsPaths.api.dist, // setting this to 'true' will generate an external sourcemap x.js.map // AND set the sourceMappingURL comment From 655b8f636be0b2f6a743b288792ede5b4f3a28a1 Mon Sep 17 00:00:00 2001 From: Daniel Choudhury Date: Fri, 29 Dec 2023 17:42:40 +0700 Subject: [PATCH 32/42] Add additional await statements --- packages/api-server/src/watch.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/api-server/src/watch.ts b/packages/api-server/src/watch.ts index 12a3ced03159..c92e669bef21 100644 --- a/packages/api-server/src/watch.ts +++ b/packages/api-server/src/watch.ts @@ -66,7 +66,7 @@ const validate = async () => { } } -const rebuildApiServer = (rebuild = false) => { +const rebuildApiServer = async (rebuild = false) => { try { // Shutdown API server killApiServer() @@ -75,9 +75,9 @@ const rebuildApiServer = (rebuild = false) => { process.stdout.write(c.dim(c.italic('Building... '))) if (rebuild) { - rebuildApi() + await rebuildApi() } else { - buildApi() + await buildApi() } console.log(c.dim(c.italic('Took ' + (Date.now() - buildTs) + ' ms'))) @@ -193,7 +193,7 @@ chokidar }, }) .on('ready', async () => { - rebuildApiServer() + await rebuildApiServer() await validate() }) .on('all', async (eventName, filePath) => { From 66e1aff4f05b6f8df8923cd5152b7d3473973d70 Mon Sep 17 00:00:00 2001 From: Daniel Choudhury Date: Fri, 5 Jan 2024 15:48:15 +0700 Subject: [PATCH 33/42] TEMP: try removing clean --- packages/internal/src/build/api.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/internal/src/build/api.ts b/packages/internal/src/build/api.ts index 62d1df036c91..b8eb22d060ea 100644 --- a/packages/internal/src/build/api.ts +++ b/packages/internal/src/build/api.ts @@ -13,7 +13,9 @@ import { findApiFiles } from '../files' let BUILD_CTX: BuildContext | null = null export const buildApi = async () => { - cleanApiBuild() + // @MARK: mai tong clean, overwriting already + // cleanApiBuild() + // Reset the build context for rebuildling BUILD_CTX = null @@ -45,7 +47,7 @@ const runRwBabelTransformsPlugin = { const rwjsConfig = getConfig() build.onLoad({ filter: /\.(js|ts|tsx|jsx)$/ }, async (args) => { - // Remove RedwoodJS "magic" from a user's code leaving JavaScript behind. + // @TODO I khitwaa implement LRU cache here const transformedCode = transformWithBabel( args.path, getApiSideBabelPlugins({ From fd72ccc2499151240113b4eb586aacee469876cc Mon Sep 17 00:00:00 2001 From: Daniel Choudhury Date: Fri, 5 Jan 2024 17:13:20 +0700 Subject: [PATCH 34/42] Increase timeout on logger --- tasks/e2e/cypress/e2e/04-logger/logger.cy.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tasks/e2e/cypress/e2e/04-logger/logger.cy.js b/tasks/e2e/cypress/e2e/04-logger/logger.cy.js index 66d9e18aa561..82a40611fd81 100644 --- a/tasks/e2e/cypress/e2e/04-logger/logger.cy.js +++ b/tasks/e2e/cypress/e2e/04-logger/logger.cy.js @@ -18,6 +18,8 @@ import 'cypress-wait-until' describe('The Redwood Logger - Basic Scaffold CRUD Logging', () => { const LOG_PATH = path.join(BASE_DIR, LOG_FILENAME) + const WAIT_TIMEOUT = 10_000 + it('1. Test Logging for CRUD', () => { // Empty log file. cy.writeFile(LOG_PATH, '') @@ -46,7 +48,7 @@ describe('The Redwood Logger - Basic Scaffold CRUD Logging', () => { console.log(str) return str.includes('> in posts()') }), - { interval: 2000, timeout: 2000 } + { interval: 2000, timeout: WAIT_TIMEOUT } ) // CREATE / SAVE @@ -110,7 +112,7 @@ describe('The Redwood Logger - Basic Scaffold CRUD Logging', () => { !str.includes('Slow Query performed in ') ) }), - { interval: 2000, timeout: 2000 } + { interval: 2000, timeout: WAIT_TIMEOUT } ) // With slow query logging. @@ -135,7 +137,7 @@ describe('The Redwood Logger - Basic Scaffold CRUD Logging', () => { console.log(str) return str.includes('Slow Query performed in ') }), - { interval: 2000, timeout: 2000 } + { interval: 2000, timeout: WAIT_TIMEOUT } ) }) }) From 04a02cf856cfb4ef67b9488522cef1768f29c4fc Mon Sep 17 00:00:00 2001 From: Dominic Saadi Date: Sat, 6 Jan 2024 21:49:57 +0000 Subject: [PATCH 35/42] add dev server logs, fail fast, bump delay restart --- .github/workflows/ci.yml | 59 ++++++++++++++++---------------- package.json | 1 + packages/api-server/src/watch.ts | 4 +-- tasks/e2e/cypress.config.js | 15 +++++--- tasks/e2e/cypress/support/e2e.js | 1 + tasks/run-e2e | 3 +- yarn.lock | 12 +++++++ 7 files changed, 59 insertions(+), 36 deletions(-) create mode 100644 tasks/e2e/cypress/support/e2e.js diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 61c51cbebd7a..f095bca9515c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -179,54 +179,55 @@ jobs: env: GITHUB_TOKEN: ${{ github.token }} - - name: πŸ“ Create a temporary directory - id: createpath - run: | - project_path=$(mktemp -d -t redwood.XXXXXX) - echo "::set-output name=project_path::$project_path" - framework_path=$(pwd) - echo "::set-output name=framework_path::$framework_path" + - name: πŸ”¨ Build + run: yarn build + + - name: 🌲 Install Cypress + run: yarn cypress install - name: 🌲 Create a Redwood App - run: | - ./tasks/run-e2e ${{ steps.createpath.outputs.project_path }} \ - --no-start \ - --bundler ${{ matrix.bundler }} + id: crwa env: YARN_ENABLE_IMMUTABLE_INSTALLS: false - - - name: πŸ™ Git init in the Redwood App directory run: | + project_path=$(mktemp -d -t redwood.XXXXXX) + echo "project-path=$project_path" >> $GITHUB_OUTPUT + git config --global user.email "you@example.com" git config --global user.name "Your Name" - git init --initial-branch main && git add . - git commit -a --message=init - working-directory: ${{ steps.createpath.outputs.project_path }} - - name: Start server in background - run: yarn rw dev --no-generate --fwd="--no-open" & - working-directory: ${{ steps.createpath.outputs.project_path }} + ./tasks/run-e2e "$project_path" \ + --bundler ${{ matrix.bundler }} \ + --no-build-framework \ + --no-start - - name: 🌲 Install Cypress - run: yarn run cypress install + - name: Start the dev server in the background + run: | + yarn rw dev --no-generate --fwd="--no-open" 2>&1 | tee dev_server.log & + working-directory: ${{ steps.crwa.outputs.project-path }} - - name: 🌲 Run cypress - uses: cypress-io/github-action@v5 + - name: 🌲 Run Cypress + uses: cypress-io/github-action@v6 env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - CYPRESS_RW_PATH: "${{ steps.createpath.outputs.project_path }}" + CYPRESS_RW_PATH: ${{ steps.crwa.outputs.project-path }} with: - # We've already installed dependencies. - install: false - env: true browser: chrome - record: false + env: true + install: false wait-on: 'http://[::1]:8910' working-directory: ./tasks/e2e spec: | cypress/e2e/01-tutorial/*.cy.js cypress/e2e/04-logger/*.cy.js + - uses: actions/upload-artifact@v4 + if: always() + with: + name: ${{ matrix.bundler }}-logs + path: | + ${{ steps.crwa.outputs.project-path }}/dev_server.log + ${{ steps.crwa.outputs.project-path }}/e2e.log + tutorial-e2e-skip: needs: detect-changes if: needs.detect-changes.outputs.onlydocs == 'true' diff --git a/package.json b/package.json index 5a5ffdd5b298..c09d021daae2 100644 --- a/package.json +++ b/package.json @@ -83,6 +83,7 @@ "boxen": "5.1.2", "core-js": "3.34.0", "cypress": "13.6.1", + "cypress-fail-fast": "7.1.0", "cypress-wait-until": "3.0.1", "dependency-cruiser": "15.5.0", "dotenv": "16.3.1", diff --git a/packages/api-server/src/watch.ts b/packages/api-server/src/watch.ts index 00e04d5f060c..77990e89117d 100644 --- a/packages/api-server/src/watch.ts +++ b/packages/api-server/src/watch.ts @@ -155,14 +155,14 @@ const debouncedRebuild = debounce( () => rebuildApiServer(true), process.env.RWJS_DELAY_RESTART ? parseInt(process.env.RWJS_DELAY_RESTART, 10) - : 5 + : 500 ) const debouncedBuild = debounce( () => rebuildApiServer(false), process.env.RWJS_DELAY_RESTART ? parseInt(process.env.RWJS_DELAY_RESTART, 10) - : 5 + : 500 ) // NOTE: the file comes through as a unix path, even on windows diff --git a/tasks/e2e/cypress.config.js b/tasks/e2e/cypress.config.js index e7a3142f764c..094111eab9a3 100644 --- a/tasks/e2e/cypress.config.js +++ b/tasks/e2e/cypress.config.js @@ -2,17 +2,24 @@ const { defineConfig } = require('cypress') module.exports = defineConfig({ e2e: { - excludeSpecPattern: ['**/codemods/*.js', '**/sharedTests.js'], specPattern: 'cypress/e2e/**/*.{js,jsx,ts,tsx}', - supportFile: false, + excludeSpecPattern: ['**/codemods/*.js', '**/sharedTests.js'], + testIsolation: false, + + setupNodeEvents(on, config) { + require('cypress-fail-fast/plugin')(on, config) + return config + }, }, + // `runMode` is for `cypress run`, `openMode` is for `cypress open`. // Locally, we use open. But in CI, we use run. retries: { - runMode: 5, - openMode: 0, + runMode: 1, + openMode: 1, }, + defaultCommandTimeout: 12_0000, execTimeout: 12_0000, pageLoadTimeout: 12_0000, diff --git a/tasks/e2e/cypress/support/e2e.js b/tasks/e2e/cypress/support/e2e.js new file mode 100644 index 000000000000..40971b0f6df1 --- /dev/null +++ b/tasks/e2e/cypress/support/e2e.js @@ -0,0 +1 @@ +import 'cypress-fail-fast' diff --git a/tasks/run-e2e b/tasks/run-e2e index 6e8cb303aca0..d0b31c409455 100755 --- a/tasks/run-e2e +++ b/tasks/run-e2e @@ -58,7 +58,8 @@ const createRedwoodJSApp = ({ typescript, bundler }) => { '--no-yarn-install', `--typescript ${typescript}`, '--no-telemetry', - '--no-git', + '--git', + '-m "first"', ].filter(Boolean), { cwd: path.join(REDWOODJS_FRAMEWORK_PATH, 'packages/create-redwood-app'), diff --git a/yarn.lock b/yarn.lock index 56ec480e1eb5..975554480c4e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -17369,6 +17369,17 @@ __metadata: languageName: node linkType: hard +"cypress-fail-fast@npm:7.1.0": + version: 7.1.0 + resolution: "cypress-fail-fast@npm:7.1.0" + dependencies: + chalk: "npm:4.1.2" + peerDependencies: + cypress: ">=8.0.0" + checksum: a523c0dac14c8c6a7297282e0dfd275f9bbcf242661932a449a5a2a02521886ceb70d420ed81d042a1d69bc62dc96209310225a9e54a2c44cf9c929dd2b8d7e4 + languageName: node + linkType: hard + "cypress-wait-until@npm:3.0.1": version: 3.0.1 resolution: "cypress-wait-until@npm:3.0.1" @@ -31780,6 +31791,7 @@ __metadata: boxen: "npm:5.1.2" core-js: "npm:3.34.0" cypress: "npm:13.6.1" + cypress-fail-fast: "npm:7.1.0" cypress-wait-until: "npm:3.0.1" dependency-cruiser: "npm:15.5.0" dotenv: "npm:16.3.1" From 4fb918a594c87620caad60f92f784c794824f4df Mon Sep 17 00:00:00 2001 From: Daniel Choudhury Date: Mon, 8 Jan 2024 11:41:37 +0600 Subject: [PATCH 36/42] Try making api transform async --- packages/api-server/src/watch.ts | 25 +++++++++++--- packages/babel-config/package.json | 1 + .../babel-config/src/__tests__/api.test.ts | 2 +- .../src/__tests__/prebuildApiFile.test.ts | 20 +++++------ packages/babel-config/src/api.ts | 19 ++++++----- packages/babel-config/tsconfig.json | 1 + packages/cli/src/commands/buildHandler.js | 3 +- .../internal/src/__tests__/build_api.test.ts | 34 ++++++++++--------- packages/internal/src/build/api.ts | 11 +++--- packages/vite/src/buildFeServer.ts | 4 +-- yarn.lock | 1 + 11 files changed, 70 insertions(+), 51 deletions(-) diff --git a/packages/api-server/src/watch.ts b/packages/api-server/src/watch.ts index 77990e89117d..611994b269f3 100644 --- a/packages/api-server/src/watch.ts +++ b/packages/api-server/src/watch.ts @@ -13,7 +13,11 @@ import { debounce } from 'lodash' import { hideBin } from 'yargs/helpers' import yargs from 'yargs/yargs' -import { buildApi, rebuildApi } from '@redwoodjs/internal/dist/build/api' +import { + buildApi, + cleanApiBuild, + rebuildApi, +} from '@redwoodjs/internal/dist/build/api' import { loadAndValidateSdls } from '@redwoodjs/internal/dist/validateSchema' import { ensurePosixPath, @@ -66,7 +70,10 @@ const validate = async () => { } } -const rebuildApiServer = async (rebuild = false) => { +const rebuildApiServer = async ({ + rebuild = false, + clean = false, +}: { rebuild?: boolean; clean?: boolean } = {}) => { try { // Shutdown API server killApiServer() @@ -74,6 +81,10 @@ const rebuildApiServer = async (rebuild = false) => { const buildTs = Date.now() process.stdout.write(c.dim(c.italic('Building... '))) + if (clean) { + await cleanApiBuild() + } + if (rebuild) { await rebuildApi() } else { @@ -152,14 +163,14 @@ const rebuildApiServer = async (rebuild = false) => { // Local writes are very fast, but writes in e2e environments are not, // so allow the default to be adjust with a env-var. const debouncedRebuild = debounce( - () => rebuildApiServer(true), + () => rebuildApiServer({ rebuild: true }), process.env.RWJS_DELAY_RESTART ? parseInt(process.env.RWJS_DELAY_RESTART, 10) : 500 ) const debouncedBuild = debounce( - () => rebuildApiServer(false), + () => rebuildApiServer({ rebuild: false }), process.env.RWJS_DELAY_RESTART ? parseInt(process.env.RWJS_DELAY_RESTART, 10) : 500 @@ -198,7 +209,11 @@ chokidar }, }) .on('ready', async () => { - await rebuildApiServer() + // First time + await rebuildApiServer({ + clean: true, + rebuild: false, + }) await validate() }) .on('all', async (eventName, filePath) => { diff --git a/packages/babel-config/package.json b/packages/babel-config/package.json index 11bca75dfbe5..1b3275eff0f9 100644 --- a/packages/babel-config/package.json +++ b/packages/babel-config/package.json @@ -47,6 +47,7 @@ "devDependencies": { "@types/babel-plugin-tester": "9.0.9", "@types/babel__core": "7.20.4", + "@types/node": "20.10.4", "babel-plugin-tester": "11.0.4", "esbuild": "0.19.9", "jest": "29.7.0" diff --git a/packages/babel-config/src/__tests__/api.test.ts b/packages/babel-config/src/__tests__/api.test.ts index a3c7af764927..f4a98eb3e5a1 100644 --- a/packages/babel-config/src/__tests__/api.test.ts +++ b/packages/babel-config/src/__tests__/api.test.ts @@ -87,7 +87,7 @@ describe('api', () => { ) const apiSideBabelConfigPath = getApiSideBabelConfigPath() - expect(ensurePosixPath(apiSideBabelConfigPath)).toMatch( + expect(ensurePosixPath(apiSideBabelConfigPath || '')).toMatch( '/redwood-app/api/babel.config.js' ) }) diff --git a/packages/babel-config/src/__tests__/prebuildApiFile.test.ts b/packages/babel-config/src/__tests__/prebuildApiFile.test.ts index cf69fb69de71..e044bb7ceb3e 100644 --- a/packages/babel-config/src/__tests__/prebuildApiFile.test.ts +++ b/packages/babel-config/src/__tests__/prebuildApiFile.test.ts @@ -18,9 +18,9 @@ let code describe('api prebuild ', () => { describe('polyfills unsupported functionality', () => { - beforeAll(() => { + beforeAll(async () => { const apiFile = path.join(RWJS_CWD, 'api/src/lib/polyfill.js') - code = prebuildApiFileWrapper(apiFile) + code = await prebuildApiFileWrapper(apiFile) }) describe('ES features', () => { @@ -393,9 +393,9 @@ describe('api prebuild ', () => { }) describe('uses core-js3 aliasing', () => { - beforeAll(() => { + beforeAll(async () => { const apiFile = path.join(RWJS_CWD, 'api/src/lib/transform.js') - code = prebuildApiFileWrapper(apiFile) + code = await prebuildApiFileWrapper(apiFile) }) it('works', () => { @@ -425,9 +425,9 @@ describe('api prebuild ', () => { }) describe('typescript', () => { - beforeAll(() => { + beforeAll(async () => { const apiFile = path.join(RWJS_CWD, 'api/src/lib/typescript.ts') - code = prebuildApiFileWrapper(apiFile) + code = await prebuildApiFileWrapper(apiFile) }) it('transpiles ts to js', () => { @@ -437,9 +437,9 @@ describe('api prebuild ', () => { }) describe('auto imports', () => { - beforeAll(() => { + beforeAll(async () => { const apiFile = path.join(RWJS_CWD, 'api/src/lib/autoImports.ts') - code = prebuildApiFileWrapper(apiFile) + code = await prebuildApiFileWrapper(apiFile) }) it('auto imports', () => { @@ -548,7 +548,7 @@ describe('api prebuild ', () => { * A copy of prebuildApiFiles from packages/internal/src/build/api.ts * This will be re-architected, but doing so now would introduce breaking changes. */ -export const prebuildApiFileWrapper = (srcFile: string) => { +export const prebuildApiFileWrapper = async (srcFile: string) => { // const redwoodProjectPaths = getPaths() const plugins = getApiSideBabelPlugins({ @@ -561,7 +561,7 @@ export const prebuildApiFileWrapper = (srcFile: string) => { // .join(redwoodProjectPaths.generated.prebuild, relativePathFromSrc) // .replace(/\.(ts)$/, '.js') - const result = transformWithBabel(srcFile, plugins) + const result = await transformWithBabel(srcFile, plugins) if (!result?.code) { throw new Error(`Couldn't prebuild ${srcFile}`) diff --git a/packages/babel-config/src/api.ts b/packages/babel-config/src/api.ts index 79b29a906009..f4937d88421e 100644 --- a/packages/babel-config/src/api.ts +++ b/packages/babel-config/src/api.ts @@ -1,19 +1,20 @@ -import fs from 'fs' +import { existsSync } from 'fs' +import fs from 'fs/promises' import path from 'path' -import { transform } from '@babel/core' import type { PluginItem, TransformOptions } from '@babel/core' +import { transformAsync } from '@babel/core' import { getPaths } from '@redwoodjs/project-config' import type { RegisterHookOptions } from './common' import { - registerBabel, CORE_JS_VERSION, RUNTIME_CORE_JS_VERSION, getCommonPlugins, - parseTypeScriptConfigFiles, getPathsFromTypeScriptConfig, + parseTypeScriptConfigFiles, + registerBabel, } from './common' export const TARGETS_NODE = '20.10' @@ -137,9 +138,10 @@ export const getApiSideBabelPlugins = ( export const getApiSideBabelConfigPath = () => { const p = path.join(getPaths().api.base, 'babel.config.js') - if (fs.existsSync(p)) { + if (existsSync(p)) { return p } else { + // Null and undefined do not have the same effect I believe return undefined } } @@ -188,14 +190,14 @@ export const registerApiSideBabelHook = ({ }) } -export const transformWithBabel = ( +export const transformWithBabel = async ( srcPath: string, plugins: TransformOptions['plugins'] ) => { - const code = fs.readFileSync(srcPath, 'utf-8') + const code = await fs.readFile(srcPath, 'utf-8') const defaultOptions = getApiSideDefaultBabelConfig() - const result = transform(code, { + const result = transformAsync(code, { ...defaultOptions, cwd: getPaths().api.base, filename: srcPath, @@ -206,5 +208,6 @@ export const transformWithBabel = ( sourceMaps: 'inline', plugins, }) + return result } diff --git a/packages/babel-config/tsconfig.json b/packages/babel-config/tsconfig.json index 91b48264c7cf..4f3efc420676 100644 --- a/packages/babel-config/tsconfig.json +++ b/packages/babel-config/tsconfig.json @@ -4,6 +4,7 @@ "baseUrl": ".", "rootDir": "src", "outDir": "dist", + "types": ["node"], }, "include": ["src"], "references": [ diff --git a/packages/cli/src/commands/buildHandler.js b/packages/cli/src/commands/buildHandler.js index 8a47f2b842c1..fa58f3cd453d 100644 --- a/packages/cli/src/commands/buildHandler.js +++ b/packages/cli/src/commands/buildHandler.js @@ -7,7 +7,7 @@ import { rimraf } from 'rimraf' import terminalLink from 'terminal-link' import { recordTelemetryAttributes } from '@redwoodjs/cli-helpers' -import { buildApi } from '@redwoodjs/internal/dist/build/api' +import { buildApi, cleanApiBuild } from '@redwoodjs/internal/dist/build/api' import { loadAndValidateSdls } from '@redwoodjs/internal/dist/validateSchema' import { detectPrerenderRoutes } from '@redwoodjs/prerender/detection' import { timedTelemetry } from '@redwoodjs/telemetry' @@ -82,6 +82,7 @@ export const handler = async ({ side.includes('api') && { title: 'Building API...', task: async () => { + await cleanApiBuild() const { errors, warnings } = await buildApi() if (errors.length) { diff --git a/packages/internal/src/__tests__/build_api.test.ts b/packages/internal/src/__tests__/build_api.test.ts index a9eda1e59038..26a7a7d018cf 100644 --- a/packages/internal/src/__tests__/build_api.test.ts +++ b/packages/internal/src/__tests__/build_api.test.ts @@ -21,26 +21,28 @@ const FIXTURE_PATH = path.resolve( // @NOTE: we no longer prebuild files into the .redwood/prebuild folder // However, prebuilding in the tests still helpful for us to validate // that everything is working as expected. -export const prebuildApiFiles = (srcFiles: string[]) => { +export const prebuildApiFiles = async (srcFiles: string[]) => { const rwjsPaths = getPaths() const plugins = getApiSideBabelPlugins() - return srcFiles.map((srcPath) => { - const relativePathFromSrc = path.relative(rwjsPaths.base, srcPath) - const dstPath = path - .join(rwjsPaths.generated.prebuild, relativePathFromSrc) - .replace(/\.(ts)$/, '.js') + return Promise.all( + srcFiles.map(async (srcPath) => { + const relativePathFromSrc = path.relative(rwjsPaths.base, srcPath) + const dstPath = path + .join(rwjsPaths.generated.prebuild, relativePathFromSrc) + .replace(/\.(ts)$/, '.js') - const result = transformWithBabel(srcPath, plugins) - if (!result?.code) { - throw new Error(`Could not prebuild ${srcPath}`) - } + const result = await transformWithBabel(srcPath, plugins) + if (!result?.code) { + throw new Error(`Could not prebuild ${srcPath}`) + } - fs.mkdirSync(path.dirname(dstPath), { recursive: true }) - fs.writeFileSync(dstPath, result.code) + fs.mkdirSync(path.dirname(dstPath), { recursive: true }) + fs.writeFileSync(dstPath, result.code) - return dstPath - }) + return dstPath + }) + ) } const cleanPaths = (p) => { @@ -51,12 +53,12 @@ const cleanPaths = (p) => { let prebuiltFiles let relativePaths -beforeAll(() => { +beforeAll(async () => { process.env.RWJS_CWD = FIXTURE_PATH cleanApiBuild() const apiFiles = findApiFiles() - prebuiltFiles = prebuildApiFiles(apiFiles) + prebuiltFiles = await prebuildApiFiles(apiFiles) relativePaths = prebuiltFiles .filter((x) => typeof x !== 'undefined') diff --git a/packages/internal/src/build/api.ts b/packages/internal/src/build/api.ts index b8eb22d060ea..9ac1ff80f297 100644 --- a/packages/internal/src/build/api.ts +++ b/packages/internal/src/build/api.ts @@ -1,6 +1,6 @@ import type { Format, Platform, PluginBuild, BuildContext } from 'esbuild' import { build, context } from 'esbuild' -import { removeSync } from 'fs-extra' +import { remove } from 'fs-extra' import { getApiSideBabelPlugins, @@ -13,9 +13,6 @@ import { findApiFiles } from '../files' let BUILD_CTX: BuildContext | null = null export const buildApi = async () => { - // @MARK: mai tong clean, overwriting already - // cleanApiBuild() - // Reset the build context for rebuildling BUILD_CTX = null @@ -36,9 +33,9 @@ export const rebuildApi = async () => { return BUILD_CTX.rebuild() } -export const cleanApiBuild = () => { +export const cleanApiBuild = async () => { const rwjsPaths = getPaths() - removeSync(rwjsPaths.api.dist) + return remove(rwjsPaths.api.dist) } const runRwBabelTransformsPlugin = { @@ -48,7 +45,7 @@ const runRwBabelTransformsPlugin = { build.onLoad({ filter: /\.(js|ts|tsx|jsx)$/ }, async (args) => { // @TODO I khitwaa implement LRU cache here - const transformedCode = transformWithBabel( + const transformedCode = await transformWithBabel( args.path, getApiSideBabelPlugins({ openTelemetry: diff --git a/packages/vite/src/buildFeServer.ts b/packages/vite/src/buildFeServer.ts index f5d01e254268..382e80dd5f48 100644 --- a/packages/vite/src/buildFeServer.ts +++ b/packages/vite/src/buildFeServer.ts @@ -80,9 +80,7 @@ export const buildFeServer = async ({ verbose, webDir }: BuildOptions = {}) => { name: 'rw-esbuild-babel-transform', setup(build: PluginBuild) { build.onLoad({ filter: /\.(js|ts|tsx|jsx)$/ }, async (args) => { - // Remove RedwoodJS "magic" from a user's code leaving JavaScript behind. - // TODO (STREAMING) We need the new transformWithBabel function in https://github.com/redwoodjs/redwood/pull/7672/files - const transformedCode = transformWithBabel(args.path, [ + const transformedCode = await transformWithBabel(args.path, [ ...getRouteHookBabelPlugins(), ]) diff --git a/yarn.lock b/yarn.lock index 975554480c4e..e71ca4fba8e8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8660,6 +8660,7 @@ __metadata: "@redwoodjs/project-config": "npm:6.0.7" "@types/babel-plugin-tester": "npm:9.0.9" "@types/babel__core": "npm:7.20.4" + "@types/node": "npm:20.10.4" babel-plugin-auto-import: "npm:1.1.0" babel-plugin-graphql-tag: "npm:3.3.0" babel-plugin-module-resolver: "npm:5.0.0" From 00c83707ffbdd838728de3b07c979cd66f051761 Mon Sep 17 00:00:00 2001 From: Daniel Choudhury Date: Mon, 8 Jan 2024 11:50:56 +0600 Subject: [PATCH 37/42] Explain LRU comment --- packages/internal/src/build/api.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/internal/src/build/api.ts b/packages/internal/src/build/api.ts index 9ac1ff80f297..6ea431a0a7b7 100644 --- a/packages/internal/src/build/api.ts +++ b/packages/internal/src/build/api.ts @@ -44,7 +44,9 @@ const runRwBabelTransformsPlugin = { const rwjsConfig = getConfig() build.onLoad({ filter: /\.(js|ts|tsx|jsx)$/ }, async (args) => { - // @TODO I khitwaa implement LRU cache here + // @TODO Implement LRU cache? Unsure how much of a performance benefit its going to be + // Generate a CRC of file contents, then save it to LRU cache with a limit + // without LRU cache, the memory usage can be come unbound const transformedCode = await transformWithBabel( args.path, getApiSideBabelPlugins({ From 8ad47538cb49eec84854375db006c1604fdfef6e Mon Sep 17 00:00:00 2001 From: Daniel Choudhury Date: Mon, 8 Jan 2024 15:32:00 +0600 Subject: [PATCH 38/42] Bit more cleanup --- packages/api-server/src/watch.ts | 8 ++++---- packages/internal/src/build/api.ts | 6 ++---- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/packages/api-server/src/watch.ts b/packages/api-server/src/watch.ts index 611994b269f3..29fd4aedf5ed 100644 --- a/packages/api-server/src/watch.ts +++ b/packages/api-server/src/watch.ts @@ -70,7 +70,7 @@ const validate = async () => { } } -const rebuildApiServer = async ({ +const buildAndRestart = async ({ rebuild = false, clean = false, }: { rebuild?: boolean; clean?: boolean } = {}) => { @@ -163,14 +163,14 @@ const rebuildApiServer = async ({ // Local writes are very fast, but writes in e2e environments are not, // so allow the default to be adjust with a env-var. const debouncedRebuild = debounce( - () => rebuildApiServer({ rebuild: true }), + () => buildAndRestart({ rebuild: true }), process.env.RWJS_DELAY_RESTART ? parseInt(process.env.RWJS_DELAY_RESTART, 10) : 500 ) const debouncedBuild = debounce( - () => rebuildApiServer({ rebuild: false }), + () => buildAndRestart({ rebuild: false }), process.env.RWJS_DELAY_RESTART ? parseInt(process.env.RWJS_DELAY_RESTART, 10) : 500 @@ -210,7 +210,7 @@ chokidar }) .on('ready', async () => { // First time - await rebuildApiServer({ + await buildAndRestart({ clean: true, rebuild: false, }) diff --git a/packages/internal/src/build/api.ts b/packages/internal/src/build/api.ts index 6ea431a0a7b7..653f429fb0e0 100644 --- a/packages/internal/src/build/api.ts +++ b/packages/internal/src/build/api.ts @@ -14,6 +14,8 @@ let BUILD_CTX: BuildContext | null = null export const buildApi = async () => { // Reset the build context for rebuildling + // No need to wait for promise to resolve + BUILD_CTX?.dispose() BUILD_CTX = null return transpileApi(findApiFiles()) @@ -26,10 +28,6 @@ export const rebuildApi = async () => { BUILD_CTX = await context(getEsbuildOptions(apiFiles)) } - console.log('definitely rebuilding!!') - console.log('definitely rebuilding!!') - console.log('definitely rebuilding!!') - console.log('definitely rebuilding!!') return BUILD_CTX.rebuild() } From a41233b9570367f929624e52f938596d7088a305 Mon Sep 17 00:00:00 2001 From: Daniel Choudhury Date: Mon, 15 Jan 2024 14:35:06 +0700 Subject: [PATCH 39/42] Increase runMode retries to 3 --- tasks/e2e/cypress.config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks/e2e/cypress.config.js b/tasks/e2e/cypress.config.js index 094111eab9a3..67498e6087be 100644 --- a/tasks/e2e/cypress.config.js +++ b/tasks/e2e/cypress.config.js @@ -16,7 +16,7 @@ module.exports = defineConfig({ // `runMode` is for `cypress run`, `openMode` is for `cypress open`. // Locally, we use open. But in CI, we use run. retries: { - runMode: 1, + runMode: 3, openMode: 1, }, From 57600006836882c848c1294a600a21fb31f27093 Mon Sep 17 00:00:00 2001 From: Daniel Choudhury Date: Mon, 15 Jan 2024 15:49:17 +0700 Subject: [PATCH 40/42] PR comments and type fixes --- .../babel-config/src/__tests__/api.test.ts | 17 +++++++++++---- .../src/__tests__/prebuildApiFile.test.ts | 18 +++++----------- packages/babel-config/src/api.ts | 21 +++++++++++-------- ...in-redwood-directory-named-imports.test.ts | 2 +- packages/babel-config/tsconfig.json | 4 +++- .../internal/src/__tests__/build_api.test.ts | 2 +- packages/internal/src/build/api.ts | 12 +++++------ 7 files changed, 41 insertions(+), 35 deletions(-) diff --git a/packages/babel-config/src/__tests__/api.test.ts b/packages/babel-config/src/__tests__/api.test.ts index f4a98eb3e5a1..6fef1a715cb6 100644 --- a/packages/babel-config/src/__tests__/api.test.ts +++ b/packages/babel-config/src/__tests__/api.test.ts @@ -1,7 +1,8 @@ import { vol } from 'memfs' -import { getPaths, ensurePosixPath } from '@redwoodjs/project-config' +import { ensurePosixPath, getPaths } from '@redwoodjs/project-config' +import type { PluginList } from '../api' import { getApiSideBabelConfigPath, getApiSideBabelPlugins, @@ -185,9 +186,17 @@ describe('api', () => { }, ]) + type ModuleResolverConfig = { + root: string[] + alias: Record + cwd: string + loglevel: string + } + + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const [_, babelPluginModuleResolverConfig] = apiSideBabelPlugins.find( (plugin) => plugin[0] === 'babel-plugin-module-resolver' - ) + )! as [any, ModuleResolverConfig, any] expect(babelPluginModuleResolverConfig).toMatchObject({ alias: { @@ -238,12 +247,12 @@ describe('api', () => { }) }) -function getPluginAliases(plugins) { +function getPluginAliases(plugins: PluginList) { return plugins.reduce((pluginAliases, plugin) => { if (plugin.length !== 3) { return pluginAliases } return [...pluginAliases, plugin[2]] - }, []) + }, [] as any) } diff --git a/packages/babel-config/src/__tests__/prebuildApiFile.test.ts b/packages/babel-config/src/__tests__/prebuildApiFile.test.ts index e044bb7ceb3e..24fd5126f0c3 100644 --- a/packages/babel-config/src/__tests__/prebuildApiFile.test.ts +++ b/packages/babel-config/src/__tests__/prebuildApiFile.test.ts @@ -14,7 +14,7 @@ import { const RWJS_CWD = path.join(__dirname, '__fixtures__/redwood-app') process.env.RWJS_CWD = RWJS_CWD -let code +let code: string describe('api prebuild ', () => { describe('polyfills unsupported functionality', () => { @@ -371,7 +371,7 @@ describe('api prebuild ', () => { }) it('includes source maps', () => { - const sourceMaps = code.split('\n').pop() + const sourceMaps = code.split('\n').pop() as string const sourceMapsMatcher = '//# sourceMappingURL=data:application/json;charset=utf-8;base64,' @@ -451,7 +451,7 @@ describe('api prebuild ', () => { test('core-js polyfill list', () => { const { list } = compat({ targets: { node: TARGETS_NODE }, - version: BABEL_PLUGIN_TRANSFORM_RUNTIME_OPTIONS.corejs.version, + version: BABEL_PLUGIN_TRANSFORM_RUNTIME_OPTIONS.corejs.version.toString(), }) /** @@ -545,22 +545,14 @@ describe('api prebuild ', () => { }) /** - * A copy of prebuildApiFiles from packages/internal/src/build/api.ts - * This will be re-architected, but doing so now would introduce breaking changes. + * We no longer prebuild files as part of the build process + * This is so we can test the babel configuration in isolation */ export const prebuildApiFileWrapper = async (srcFile: string) => { - // const redwoodProjectPaths = getPaths() - const plugins = getApiSideBabelPlugins({ openTelemetry: getConfig().experimental.opentelemetry.enabled, }) - // const relativePathFromSrc = path.relative(redwoodProjectPaths.base, srcFile) - - // const dstPath = path - // .join(redwoodProjectPaths.generated.prebuild, relativePathFromSrc) - // .replace(/\.(ts)$/, '.js') - const result = await transformWithBabel(srcFile, plugins) if (!result?.code) { diff --git a/packages/babel-config/src/api.ts b/packages/babel-config/src/api.ts index f4937d88421e..e673f311a8bf 100644 --- a/packages/babel-config/src/api.ts +++ b/packages/babel-config/src/api.ts @@ -2,7 +2,7 @@ import { existsSync } from 'fs' import fs from 'fs/promises' import path from 'path' -import type { PluginItem, TransformOptions } from '@babel/core' +import type { PluginOptions, PluginTarget, TransformOptions } from '@babel/core' import { transformAsync } from '@babel/core' import { getPaths } from '@redwoodjs/project-config' @@ -66,17 +66,21 @@ export const BABEL_PLUGIN_TRANSFORM_RUNTIME_OPTIONS = { version: RUNTIME_CORE_JS_VERSION, } +// Plugin shape: [ ["Target", "Options", "name"] ], +// a custom "name" is supplied so that user's do not accidentally overwrite +// Redwood's own plugins when they specify their own. +export type PluginList = Array< + [PluginTarget, PluginOptions, string | undefined] +> + export const getApiSideBabelPlugins = ( { openTelemetry } = { openTelemetry: false, } -) => { - // Plugin shape: [ ["Target", "Options", "name"] ], - // a custom "name" is supplied so that user's do not accidentally overwrite - // Redwood's own plugins when they specify their own. +): PluginList => { const tsConfig = parseTypeScriptConfigFiles() - const plugins: TransformOptions['plugins'] = [ + const plugins: PluginList = [ ...getCommonPlugins(), // Needed to support `/** @jsxImportSource custom-jsx-library */` // comments in JSX files @@ -131,7 +135,7 @@ export const getApiSideBabelPlugins = ( undefined, 'rwjs-babel-otel-wrapping', ], - ].filter(Boolean) as PluginItem[] + ].filter(Boolean) as PluginList // ts doesn't play nice with filter(Boolean) return plugins } @@ -141,8 +145,7 @@ export const getApiSideBabelConfigPath = () => { if (existsSync(p)) { return p } else { - // Null and undefined do not have the same effect I believe - return undefined + return } } diff --git a/packages/babel-config/src/plugins/__tests__/babel-plugin-redwood-directory-named-imports.test.ts b/packages/babel-config/src/plugins/__tests__/babel-plugin-redwood-directory-named-imports.test.ts index 6f50c9ee1de7..14ed1918c6df 100644 --- a/packages/babel-config/src/plugins/__tests__/babel-plugin-redwood-directory-named-imports.test.ts +++ b/packages/babel-config/src/plugins/__tests__/babel-plugin-redwood-directory-named-imports.test.ts @@ -65,7 +65,7 @@ describe('directory named imports', () => { }, ], ], - }).code + })?.code expect(babeled).toMatch(output) }) }) diff --git a/packages/babel-config/tsconfig.json b/packages/babel-config/tsconfig.json index 4f3efc420676..3b0700b39db5 100644 --- a/packages/babel-config/tsconfig.json +++ b/packages/babel-config/tsconfig.json @@ -4,9 +4,11 @@ "baseUrl": ".", "rootDir": "src", "outDir": "dist", - "types": ["node"], + "types": ["node", "jest"], }, "include": ["src"], + // Excluding cypress types, because it interferes with expect in tests + "exclude": ["node_modules/cypress/types/*", "**/__tests__/__fixtures__/*"], "references": [ { "path": "../project-config" } ] diff --git a/packages/internal/src/__tests__/build_api.test.ts b/packages/internal/src/__tests__/build_api.test.ts index 26a7a7d018cf..38945bf3d282 100644 --- a/packages/internal/src/__tests__/build_api.test.ts +++ b/packages/internal/src/__tests__/build_api.test.ts @@ -19,7 +19,7 @@ const FIXTURE_PATH = path.resolve( ) // @NOTE: we no longer prebuild files into the .redwood/prebuild folder -// However, prebuilding in the tests still helpful for us to validate +// However, prebuilding in the tests is still helpful for us to validate // that everything is working as expected. export const prebuildApiFiles = async (srcFiles: string[]) => { const rwjsPaths = getPaths() diff --git a/packages/internal/src/build/api.ts b/packages/internal/src/build/api.ts index 653f429fb0e0..e8770d6baf83 100644 --- a/packages/internal/src/build/api.ts +++ b/packages/internal/src/build/api.ts @@ -1,4 +1,4 @@ -import type { Format, Platform, PluginBuild, BuildContext } from 'esbuild' +import type { BuildContext, BuildOptions, PluginBuild } from 'esbuild' import { build, context } from 'esbuild' import { remove } from 'fs-extra' @@ -13,7 +13,7 @@ import { findApiFiles } from '../files' let BUILD_CTX: BuildContext | null = null export const buildApi = async () => { - // Reset the build context for rebuildling + // Reset the build context for rebuilding // No need to wait for promise to resolve BUILD_CTX?.dispose() BUILD_CTX = null @@ -44,7 +44,7 @@ const runRwBabelTransformsPlugin = { build.onLoad({ filter: /\.(js|ts|tsx|jsx)$/ }, async (args) => { // @TODO Implement LRU cache? Unsure how much of a performance benefit its going to be // Generate a CRC of file contents, then save it to LRU cache with a limit - // without LRU cache, the memory usage can be come unbound + // without LRU cache, the memory usage can become unbound const transformedCode = await transformWithBabel( args.path, getApiSideBabelPlugins({ @@ -70,15 +70,15 @@ export const transpileApi = async (files: string[]) => { return build(getEsbuildOptions(files)) } -function getEsbuildOptions(files: string[]) { +function getEsbuildOptions(files: string[]): BuildOptions { const rwjsPaths = getPaths() return { absWorkingDir: rwjsPaths.api.base, entryPoints: files, - platform: 'node' as Platform, + platform: 'node', target: 'node20', - format: 'cjs' as Format, + format: 'cjs', allowOverwrite: true, bundle: false, plugins: [runRwBabelTransformsPlugin], From 14db4546f1b4431b4846da987f1dbf765566ce6e Mon Sep 17 00:00:00 2001 From: Daniel Choudhury Date: Mon, 15 Jan 2024 16:18:34 +0700 Subject: [PATCH 41/42] Mroe type tweaks --- packages/babel-config/src/api.ts | 17 +++++++++-------- packages/babel-config/src/common.ts | 4 ++-- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/packages/babel-config/src/api.ts b/packages/babel-config/src/api.ts index e673f311a8bf..53c05cc56801 100644 --- a/packages/babel-config/src/api.ts +++ b/packages/babel-config/src/api.ts @@ -67,20 +67,21 @@ export const BABEL_PLUGIN_TRANSFORM_RUNTIME_OPTIONS = { } // Plugin shape: [ ["Target", "Options", "name"] ], -// a custom "name" is supplied so that user's do not accidentally overwrite +// a custom "name" can be supplied so that user's do not accidentally overwrite // Redwood's own plugins when they specify their own. -export type PluginList = Array< - [PluginTarget, PluginOptions, string | undefined] -> +export type PluginList = Array +type PluginShape = + | [PluginTarget, PluginOptions, undefined | string] + | [PluginTarget, PluginOptions] export const getApiSideBabelPlugins = ( { openTelemetry } = { openTelemetry: false, } -): PluginList => { +) => { const tsConfig = parseTypeScriptConfigFiles() - const plugins: PluginList = [ + const plugins: Array = [ ...getCommonPlugins(), // Needed to support `/** @jsxImportSource custom-jsx-library */` // comments in JSX files @@ -135,9 +136,9 @@ export const getApiSideBabelPlugins = ( undefined, 'rwjs-babel-otel-wrapping', ], - ].filter(Boolean) as PluginList // ts doesn't play nice with filter(Boolean) + ] - return plugins + return plugins.filter(Boolean) as PluginList // ts doesn't play nice with filter(Boolean) } export const getApiSideBabelConfigPath = () => { diff --git a/packages/babel-config/src/common.ts b/packages/babel-config/src/common.ts index b05f18a42a16..5aeb57b5ad49 100644 --- a/packages/babel-config/src/common.ts +++ b/packages/babel-config/src/common.ts @@ -1,7 +1,7 @@ import fs from 'fs' import path from 'path' -import type { TransformOptions, PluginItem } from '@babel/core' +import type { PluginItem, PluginOptions, TransformOptions } from '@babel/core' import { parseConfigFileTextToJson } from 'typescript' import { getPaths } from '@redwoodjs/project-config' @@ -61,7 +61,7 @@ if (!RUNTIME_CORE_JS_VERSION) { ) } -export const getCommonPlugins = () => { +export const getCommonPlugins = (): Array<[string, PluginOptions]> => { return [ ['@babel/plugin-transform-class-properties', { loose: true }], // Note: The private method loose mode configuration setting must be the From 25047fb5679263ad43a957946c8c32c27eb9d465 Mon Sep 17 00:00:00 2001 From: Daniel Choudhury Date: Mon, 15 Jan 2024 16:21:39 +0700 Subject: [PATCH 42/42] Ignore dist paths from jestconfig --- packages/babel-config/jest.config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/babel-config/jest.config.js b/packages/babel-config/jest.config.js index a191690e9a42..ca095a6ad325 100644 --- a/packages/babel-config/jest.config.js +++ b/packages/babel-config/jest.config.js @@ -1,3 +1,3 @@ module.exports = { - testPathIgnorePatterns: ['fixtures'], + testPathIgnorePatterns: ['fixtures', 'dist/*'], }