diff --git a/crates/tuono/Cargo.toml b/crates/tuono/Cargo.toml index 7bb4faf2..ddd3dc45 100644 --- a/crates/tuono/Cargo.toml +++ b/crates/tuono/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "tuono" -version = "0.1.7" +version = "0.1.8" edition = "2021" authors = ["V. Ageno "] description = "The react/rust fullstack framework" diff --git a/crates/tuono_lib/Cargo.toml b/crates/tuono_lib/Cargo.toml index e631866e..74388ee0 100644 --- a/crates/tuono_lib/Cargo.toml +++ b/crates/tuono_lib/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "tuono_lib" -version = "0.1.7" +version = "0.1.8" edition = "2021" authors = ["V. Ageno "] description = "The react/rust fullstack framework" @@ -24,5 +24,5 @@ serde = { version = "1.0.202", features = ["derive"] } erased-serde = "0.4.5" serde_json = "1.0" -tuono_lib_macros = {path = "../tuono_lib_macros", version = "0.1.7"} +tuono_lib_macros = {path = "../tuono_lib_macros", version = "0.1.8"} diff --git a/crates/tuono_lib_macros/Cargo.toml b/crates/tuono_lib_macros/Cargo.toml index d87555dd..7f140ff0 100644 --- a/crates/tuono_lib_macros/Cargo.toml +++ b/crates/tuono_lib_macros/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "tuono_lib_macros" -version = "0.1.7" +version = "0.1.8" edition = "2021" description = "The react/rust fullstack framework" homepage = "https://github.com/Valerioageno/tuono" diff --git a/package.json b/package.json index d0007a53..d64ab4e0 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,8 @@ "format": "turbo format", "format:check": "turbo format:check", "types": "turbo types", - "test": "turbo test" + "test": "turbo test", + "test:watch": "turbo test:watch" }, "workspaces": [ "tuono", diff --git a/packages/lazy-fn-vite-plugin/package.json b/packages/lazy-fn-vite-plugin/package.json index 24750f3f..45a7cea7 100644 --- a/packages/lazy-fn-vite-plugin/package.json +++ b/packages/lazy-fn-vite-plugin/package.json @@ -1,6 +1,6 @@ { "name": "tuono-lazy-fn-vite-plugin", - "version": "0.1.7", + "version": "0.1.8", "description": "Plugin for the tuono's lazy fn. Tuono is the react/rust fullstack framework", "scripts": { "dev": "vite build --watch", @@ -9,6 +9,7 @@ "format": "prettier -u --write --ignore-unknown '**/*'", "format:check": "prettier --check --ignore-unknown '**/*'", "types": "tsc --noEmit", + "test:watch": "vitest", "test": "vitest run" }, "keywords": [], diff --git a/packages/lazy-fn-vite-plugin/src/constants.ts b/packages/lazy-fn-vite-plugin/src/constants.ts new file mode 100644 index 00000000..43c931c5 --- /dev/null +++ b/packages/lazy-fn-vite-plugin/src/constants.ts @@ -0,0 +1,3 @@ +export const TUONO_DYNAMIC_FN_ID = 'dynamic' +export const REACT_LAZY_FN_ID = 'lazy' +export const TUONO_MAIN_PACKAGE = 'tuono' diff --git a/packages/lazy-fn-vite-plugin/src/index.ts b/packages/lazy-fn-vite-plugin/src/index.ts index a8024d2c..7db67fd7 100644 --- a/packages/lazy-fn-vite-plugin/src/index.ts +++ b/packages/lazy-fn-vite-plugin/src/index.ts @@ -2,6 +2,12 @@ import type { Plugin } from 'vite' import * as babel from '@babel/core' import type { PluginItem } from '@babel/core' +import { + TUONO_MAIN_PACKAGE, + TUONO_DYNAMIC_FN_ID, + REACT_LAZY_FN_ID, +} from './constants' + import * as t from '@babel/types' import type { @@ -13,15 +19,16 @@ import type { } from '@babel/types' /** - * This plugin just removes the `lazy` imported function from any tuono import + * This plugin just removes the `dynamic` imported function from any tuono import */ const RemoveTuonoLazyImport: PluginItem = { name: 'remove-tuono-lazy-import-plugin', visitor: { ImportSpecifier: (path) => { - if ((path.node.imported as Identifier).name === 'lazy') { + if ((path.node.imported as Identifier).name === TUONO_DYNAMIC_FN_ID) { if ( - (path.parentPath.node as ImportDeclaration).source.value === 'tuono' + (path.parentPath.node as ImportDeclaration).source.value === + TUONO_MAIN_PACKAGE ) { path.remove() } @@ -31,11 +38,13 @@ const RemoveTuonoLazyImport: PluginItem = { } /** - * Import { lazy } from 'react' + * This plugin adds: "Import { lazy } from 'react'" + * and translate dynamic call into a React.lazy call */ const ImportReactLazy: PluginItem = { name: 'import-react-lazy-plugin', visitor: { + // Add the import statement Program: (path: any) => { let isReactImported = false @@ -50,25 +59,36 @@ const ImportReactLazy: PluginItem = { // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition if (!isReactImported) { const importDeclaration = t.importDeclaration( - [t.importSpecifier(t.identifier('lazy'), t.identifier('lazy'))], + [ + t.importSpecifier( + t.identifier(REACT_LAZY_FN_ID), + t.identifier(REACT_LAZY_FN_ID), + ), + ], t.stringLiteral('react'), ) path.unshiftContainer('body', importDeclaration) } }, + // Update lazy function name from `dynamic` to `lazy` + CallExpression: (path: any) => { + if (path.node.callee?.name === TUONO_DYNAMIC_FN_ID) { + path.node.callee.name = REACT_LAZY_FN_ID + } + }, }, } /** * For the server side we need to statically import the lazy loaded components */ -const TurnLazyToStaticImport: PluginItem = { - name: 'turn-lazy-to-static-import-plugin', +const TurnLazyIntoStaticImport: PluginItem = { + name: 'turn-lazy-into-static-import-plugin', visitor: { VariableDeclaration: (path) => { path.node.declarations.forEach((el) => { const init = el.init as CallExpression - if ((init.callee as Identifier).name === 'lazy') { + if ((init.callee as Identifier).name === TUONO_DYNAMIC_FN_ID) { const importName = (el.id as Identifier).name const importPath = ( ( @@ -96,14 +116,17 @@ export function LazyLoadingPlugin(): Plugin { name: 'vite-plugin-tuono-lazy-loading', enforce: 'pre', transform(code, _id, opts): string | undefined | null { - if (code.includes('lazy') && code.includes('tuono')) { + if ( + code.includes(TUONO_DYNAMIC_FN_ID) && + code.includes(TUONO_MAIN_PACKAGE) + ) { const res = babel.transformSync(code, { plugins: [ ['@babel/plugin-syntax-jsx', {}], ['@babel/plugin-syntax-typescript', { isTSX: true }], [RemoveTuonoLazyImport], [!opts?.ssr ? ImportReactLazy : []], - [opts?.ssr ? TurnLazyToStaticImport : []], + [opts?.ssr ? TurnLazyIntoStaticImport : []], ], sourceMaps: true, }) diff --git a/packages/lazy-fn-vite-plugin/test/transpileSource.test.ts b/packages/lazy-fn-vite-plugin/test/transpileSource.test.ts index 70564fbd..eb48ef72 100644 --- a/packages/lazy-fn-vite-plugin/test/transpileSource.test.ts +++ b/packages/lazy-fn-vite-plugin/test/transpileSource.test.ts @@ -2,10 +2,10 @@ import { it, expect, describe } from 'vitest' import { LazyLoadingPlugin } from '../src' const SOURCE_CODE = ` -import { createRoute, lazy } from 'tuono' +import { createRoute, dynamic } from 'tuono' -const IndexImport = lazy(() => import('./../src/routes/index')) -const PokemonspokemonImport = lazy( +const IndexImport = dynamic(() => import('./../src/routes/index')) +const PokemonspokemonImport = dynamic( () => import('./../src/routes/pokemons/[pokemon]'), ) ` diff --git a/packages/tuono/package.json b/packages/tuono/package.json index 2bc2c4e6..ee3e6c5e 100644 --- a/packages/tuono/package.json +++ b/packages/tuono/package.json @@ -1,6 +1,6 @@ { "name": "tuono", - "version": "0.1.7", + "version": "0.1.8", "description": "The react/rust fullstack framework", "scripts": { "dev": "vite build --watch", @@ -9,6 +9,7 @@ "format": "prettier -u --write --ignore-unknown '**/*'", "format:check": "prettier --check --ignore-unknown '**/*'", "types": "tsc --noEmit", + "test:watch": "vitest", "test": "vitest run" }, "type": "module", diff --git a/packages/tuono/src/build/routes-generator/generator.ts b/packages/tuono/src/build/routes-generator/generator.ts index cee1038a..66d654cf 100644 --- a/packages/tuono/src/build/routes-generator/generator.ts +++ b/packages/tuono/src/build/routes-generator/generator.ts @@ -232,7 +232,7 @@ export async function routeGenerator(config = defaultConfig): Promise { ...sortedRouteNodes.map((node) => { return `const ${ node.variableName - }Import = lazy(() => import('./${replaceBackslash( + }Import = dynamic(() => import('./${replaceBackslash( removeExt( path.relative( path.dirname(config.generatedRouteTree), @@ -272,7 +272,7 @@ export async function routeGenerator(config = defaultConfig): Promise { const routeImports = [ '// This file is auto-generated by Tuono', - "import { createRoute, lazy } from 'tuono'", + "import { createRoute, dynamic } from 'tuono'", [ `import RootImport from './${replaceBackslash( path.relative( diff --git a/packages/tuono/src/index.ts b/packages/tuono/src/index.ts index b426a1b7..1862ed1d 100644 --- a/packages/tuono/src/index.ts +++ b/packages/tuono/src/index.ts @@ -4,7 +4,7 @@ import { createRouter, Link, RouterProvider, - lazy, + dynamic, } from './router' export type { TuonoProps } from './types' @@ -15,5 +15,5 @@ export { createRouter, Link, RouterProvider, - lazy, + dynamic, } diff --git a/packages/tuono/src/router/lazy.tsx b/packages/tuono/src/router/dynamic.tsx similarity index 81% rename from packages/tuono/src/router/lazy.tsx rename to packages/tuono/src/router/dynamic.tsx index 1038d292..12033bcc 100644 --- a/packages/tuono/src/router/lazy.tsx +++ b/packages/tuono/src/router/dynamic.tsx @@ -9,7 +9,7 @@ import * as React from 'react' * It can be wrapped within a React.Suspense component in order to handle its loading state. */ // eslint-disable-next-line @typescript-eslint/no-unused-vars -export const lazy = (importFn: () => JSX.Element): JSX.Element => { +export const dynamic = (importFn: () => JSX.Element): JSX.Element => { /** * * This function is just a placeholder. The real work is done by the bundler. @@ -21,8 +21,8 @@ export const lazy = (importFn: () => JSX.Element): JSX.Element => { * Example: * * // User code - * import { lazy } from 'tuono' - * const MyComponent = lazy(() => import('./my-component')) + * import { dynamic } from 'tuono' + * const MyComponent = dynamic(() => import('./my-component')) * * // Client side generated code * import { lazy } from 'react' @@ -31,6 +31,7 @@ export const lazy = (importFn: () => JSX.Element): JSX.Element => { * // Server side generated code * import MyComponent from './my-component' * + * Check the `lazy-fn-vite-plugin` package for more */ return <> } diff --git a/packages/tuono/src/router/index.tsx b/packages/tuono/src/router/index.tsx index 1f7ff843..b3d2a535 100644 --- a/packages/tuono/src/router/index.tsx +++ b/packages/tuono/src/router/index.tsx @@ -2,4 +2,4 @@ export { RouterProvider } from './components/RouterProvider' export { default as Link } from './components/Link' export { createRouter } from './router' export { createRoute, createRootRoute } from './route' -export { lazy } from './lazy' +export { dynamic } from './dynamic' diff --git a/turbo.json b/turbo.json index 773a6963..7988ed9b 100644 --- a/turbo.json +++ b/turbo.json @@ -10,6 +10,7 @@ ] }, "test": {}, + "test:watch": {}, "build": { "outputs": [ "dist/**"