Prevent dynamic fn replacement when not imported by tuono (#57)

* fix: prevent dynamic fn replacement when not imported by tuono

* feat: update version to v0.10.3

* Revert "fix(deps): update dependency zustand to v5 (#55)"

This reverts commit d7a086dfb1.

* Revert "fix(deps): update dependency zustand to v4.5.5 (#37)"

This reverts commit b36dc0b897.

* Revert "chore(deps): update dependency @testing-library/react to v16 (#38)"

This reverts commit 1a1b62698c.

* Revert "chore(deps): update dependency @tanstack/config to ^0.13.0 (#32)"

This reverts commit 6c7cc62371.

* revert pnpm update

* Revert "chore(deps): update dependency vitest to v2 (#45)"

This reverts commit c5b5f6aefe.

* Revert "chore(deps): update dependency node to v20.18.0 (#33)"

This reverts commit 588326cc57.
This commit is contained in:
Valerio Ageno
2024-10-16 20:41:33 +02:00
committed by GitHub
parent d7a086dfb1
commit 002733cd99
16 changed files with 121 additions and 73 deletions
+1 -1
View File
@@ -1 +1 @@
20.18.0
v20.10.0
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "tuono"
version = "0.10.2"
version = "0.10.3"
edition = "2021"
authors = ["V. Ageno <valerioageno@yahoo.it>"]
description = "The react/rust fullstack framework"
+2 -2
View File
@@ -1,6 +1,6 @@
[package]
name = "tuono_lib"
version = "0.10.2"
version = "0.10.3"
edition = "2021"
authors = ["V. Ageno <valerioageno@yahoo.it>"]
description = "The react/rust fullstack framework"
@@ -33,7 +33,7 @@ either = "1.13.0"
tower-http = {version = "0.6.0", features = ["fs"]}
colored = "2.1.0"
tuono_lib_macros = {path = "../tuono_lib_macros", version = "0.10.2"}
tuono_lib_macros = {path = "../tuono_lib_macros", version = "0.10.3"}
# Match the same version used by axum
tokio-tungstenite = "0.24.0"
futures-util = { version = "0.3", default-features = false, features = ["sink", "std"] }
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "tuono_lib_macros"
version = "0.10.2"
version = "0.10.3"
edition = "2021"
description = "The react/rust fullstack framework"
keywords = [ "react", "typescript", "fullstack", "web", "ssr"]
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "workspace",
"packageManager": "pnpm@9.12.1",
"packageManager": "pnpm@9.1.1",
"scripts": {
"dev": "turbo watch dev",
"build": "turbo build --filter tuono",
@@ -20,7 +20,7 @@
"author": "Valerio Ageno",
"license": "MIT",
"devDependencies": {
"@tanstack/config": "^0.13.0",
"@tanstack/config": "^0.7.0",
"@types/node": "^20.12.7",
"@types/react": "^18.3.1",
"@typescript-eslint/eslint-plugin": "^8.0.0",
@@ -35,7 +35,7 @@
"prettier": "^3.2.4",
"typescript": "^5.4.5",
"vite": "^5.2.11",
"vitest": "^2.0.0"
"vitest": "^1.5.2"
},
"dependencies": {
"turbo": "^2.0.12"
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "tuono-fs-router-vite-plugin",
"version": "0.10.2",
"version": "0.10.3",
"description": "Plugin for the tuono's file system router. Tuono is the react/rust fullstack framework",
"scripts": {
"dev": "vite build --watch",
@@ -44,8 +44,8 @@
"vite": "^5.2.11"
},
"devDependencies": {
"@tanstack/config": "^0.13.0",
"@tanstack/config": "^0.7.11",
"@types/babel__core": "^7.20.5",
"vitest": "^2.0.0"
"vitest": "^1.5.2"
}
}
@@ -1,11 +1,11 @@
import { defineConfig, mergeConfig } from 'vitest/config'
import { tanstackViteConfig } from '@tanstack/config/vite'
import { tanstackBuildConfig } from '@tanstack/config/build'
const config = defineConfig({})
export default mergeConfig(
config,
tanstackViteConfig({
tanstackBuildConfig({
entry: './src/index.ts',
srcDir: './src',
}),
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "tuono-lazy-fn-vite-plugin",
"version": "0.10.2",
"version": "0.10.3",
"description": "Plugin for the tuono's lazy fn. Tuono is the react/rust fullstack framework",
"scripts": {
"dev": "vite build --watch",
@@ -43,9 +43,9 @@
"vite": "^5.2.11"
},
"devDependencies": {
"@tanstack/config": "^0.13.0",
"@tanstack/config": "^0.7.11",
"@types/babel__core": "^7.20.5",
"prettier": "^3.2.4",
"vitest": "^2.0.0"
"vitest": "^1.5.2"
}
}
+37 -35
View File
@@ -1,6 +1,7 @@
import type { Plugin } from 'vite'
import * as babel from '@babel/core'
import type { PluginItem } from '@babel/core'
import { isTuonoDynamicFnImported } from './utils'
import {
TUONO_MAIN_PACKAGE,
@@ -12,7 +13,6 @@ import * as t from '@babel/types'
import type {
Identifier,
ImportDeclaration,
CallExpression,
ArrowFunctionExpression,
StringLiteral,
@@ -26,13 +26,8 @@ const RemoveTuonoLazyImport: PluginItem = {
name: 'remove-tuono-lazy-import-plugin',
visitor: {
ImportSpecifier: (path) => {
if ((path.node.imported as Identifier).name === TUONO_DYNAMIC_FN_ID) {
if (
(path.parentPath.node as ImportDeclaration).source.value ===
TUONO_MAIN_PACKAGE
) {
path.remove()
}
if (isTuonoDynamicFnImported(path)) {
path.remove()
}
},
},
@@ -46,18 +41,39 @@ const ReplaceTuonoLazyImport: PluginItem = {
name: 'remove-tuono-lazy-import-plugin',
visitor: {
ImportSpecifier: (path) => {
if ((path.node.imported as Identifier).name === TUONO_DYNAMIC_FN_ID) {
if (
(path.parentPath.node as ImportDeclaration).source.value ===
TUONO_MAIN_PACKAGE
) {
;(path.node.imported as Identifier).name = TUONO_LAZY_FN_ID
}
if (isTuonoDynamicFnImported(path)) {
;(path.node.imported as Identifier).name = TUONO_LAZY_FN_ID
}
},
},
}
const turnLazyIntoStatic = {
VariableDeclaration: (path: babel.NodePath<t.VariableDeclaration>): void => {
path.node.declarations.forEach((el) => {
const init = el.init as CallExpression
if ((init.callee as Identifier).name === TUONO_DYNAMIC_FN_ID) {
const importName = (el.id as Identifier).name
const importPath = (
(
(init.arguments[0] as ArrowFunctionExpression)
.body as CallExpression
).arguments[0] as StringLiteral
).value
if (importName && importPath) {
const importDeclaration = t.importDeclaration(
[t.importDefaultSpecifier(t.identifier(importName))],
t.stringLiteral(importPath),
)
path.replaceWith(importDeclaration)
}
}
})
},
}
/**
* [SERVER build]
* This plugin statically imports the lazy loaded components
@@ -65,27 +81,13 @@ const ReplaceTuonoLazyImport: PluginItem = {
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 === TUONO_DYNAMIC_FN_ID) {
const importName = (el.id as Identifier).name
const importPath = (
(
(init.arguments[0] as ArrowFunctionExpression)
.body as CallExpression
).arguments[0] as StringLiteral
).value
if (importName && importPath) {
const importDeclaration = t.importDeclaration(
[t.importDefaultSpecifier(t.identifier(importName))],
t.stringLiteral(importPath),
)
path.replaceWith(importDeclaration)
Program: (path) => {
path.traverse({
ImportSpecifier: (subPath) => {
if (isTuonoDynamicFnImported(subPath)) {
path.traverse(turnLazyIntoStatic)
}
}
},
})
},
},
+19
View File
@@ -0,0 +1,19 @@
import { TUONO_MAIN_PACKAGE, TUONO_DYNAMIC_FN_ID } from './constants'
import type * as t from '@babel/types'
import type { Identifier, ImportDeclaration } from '@babel/types'
export const isTuonoDynamicFnImported = (
path: babel.NodePath<t.ImportSpecifier>,
): boolean => {
if ((path.node.imported as Identifier).name !== TUONO_DYNAMIC_FN_ID) {
return false
}
if (
(path.parentPath.node as ImportDeclaration).source.value !==
TUONO_MAIN_PACKAGE
) {
return false
}
return true
}
@@ -10,24 +10,51 @@ const PokemonspokemonImport = dynamic(
)
`
const CLIENT_RESULT = `import { createRoute, lazyLoadComponent as dynamic } from 'tuono';
const IndexImport = dynamic(() => import('./../src/routes/index'));
const PokemonspokemonImport = dynamic(() => import('./../src/routes/pokemons/[pokemon]'));`
const NON_DYNAMIC_SOURCE = `
import { createRoute } from 'tuono'
import {dynamic} from 'external-lib'
const SERVER_RESULT = `import { createRoute } from 'tuono';
import IndexImport from "./../src/routes/index";
import PokemonspokemonImport from "./../src/routes/pokemons/[pokemon]";`
const IndexImport = dynamic(() => import('./../src/routes/index'))
const PokemonspokemonImport = dynamic(
() => import('./../src/routes/pokemons/[pokemon]'),
)
`
describe('Transpile tuono source', () => {
it('Into the client bundle', () => {
const bundle = LazyLoadingPlugin().transform?.(SOURCE_CODE, 'id')
expect(bundle).toBe(CLIENT_RESULT)
expect(bundle)
.toBe(`import { createRoute, lazyLoadComponent as dynamic } from 'tuono';
const IndexImport = dynamic(() => import('./../src/routes/index'));
const PokemonspokemonImport = dynamic(() => import('./../src/routes/pokemons/[pokemon]'));`)
})
it('Into the server bundle', () => {
const bundle = LazyLoadingPlugin().transform?.(SOURCE_CODE, 'id', {
ssr: true,
})
expect(bundle).toBe(SERVER_RESULT)
expect(bundle).toBe(`import { createRoute } from 'tuono';
import IndexImport from "./../src/routes/index";
import PokemonspokemonImport from "./../src/routes/pokemons/[pokemon]";`)
})
})
describe('Non tuono dynamic function', () => {
it('Into the client bundle', () => {
const bundle = LazyLoadingPlugin().transform?.(NON_DYNAMIC_SOURCE, 'id')
expect(bundle).toBe(`import { createRoute } from 'tuono';
import { dynamic } from 'external-lib';
const IndexImport = dynamic(() => import('./../src/routes/index'));
const PokemonspokemonImport = dynamic(() => import('./../src/routes/pokemons/[pokemon]'));`)
})
it('Into the server bundle', () => {
const bundle = LazyLoadingPlugin().transform?.(NON_DYNAMIC_SOURCE, 'id', {
ssr: true,
})
expect(bundle).toBe(`import { createRoute } from 'tuono';
import { dynamic } from 'external-lib';
const IndexImport = dynamic(() => import('./../src/routes/index'));
const PokemonspokemonImport = dynamic(() => import('./../src/routes/pokemons/[pokemon]'));`)
})
})
+2 -2
View File
@@ -1,11 +1,11 @@
import { defineConfig, mergeConfig } from 'vitest/config'
import { tanstackViteConfig } from '@tanstack/config/vite'
import { tanstackBuildConfig } from '@tanstack/config/build'
const config = defineConfig({})
export default mergeConfig(
config,
tanstackViteConfig({
tanstackBuildConfig({
entry: './src/index.ts',
srcDir: './src',
}),
+6 -6
View File
@@ -1,6 +1,6 @@
{
"name": "tuono-router",
"version": "0.10.2",
"version": "0.10.3",
"description": "React routing component for the framework tuono. Tuono is the react/rust fullstack framework",
"scripts": {
"dev": "vite build --watch",
@@ -44,14 +44,14 @@
"dependencies": {
"react-intersection-observer": "^9.13.0",
"vite": "^5.2.11",
"zustand": "5.0.0"
"zustand": "4.4.7"
},
"devDependencies": {
"@tanstack/config": "^0.13.0",
"@tanstack/config": "^0.7.11",
"@testing-library/jest-dom": "^6.4.5",
"@testing-library/react": "^16.0.0",
"jsdom": "^25.0.0",
"@testing-library/react": "^15.0.7",
"jsdom": "^24.0.0",
"prettier": "^3.2.4",
"vitest": "^2.0.0"
"vitest": "^1.5.2"
}
}
+2 -2
View File
@@ -1,7 +1,7 @@
/// <reference types="vitest" />
/// <reference types="vite/client" />
import { defineConfig, mergeConfig } from 'vitest/config'
import { tanstackViteConfig } from '@tanstack/config/vite'
import { tanstackBuildConfig } from '@tanstack/config/build'
import react from '@vitejs/plugin-react'
const config = defineConfig({
@@ -16,7 +16,7 @@ const config = defineConfig({
export default mergeConfig(
config,
tanstackViteConfig({
tanstackBuildConfig({
entry: './src/index.ts',
srcDir: './src',
}),
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "tuono",
"version": "0.10.2",
"version": "0.10.3",
"description": "The react/rust fullstack framework",
"scripts": {
"dev": "vite build --watch",
@@ -99,7 +99,7 @@
"@types/react": "^18.3.3",
"@types/react-dom": "^18.3.0",
"prettier": "^3.2.4",
"vitest": "^2.0.0"
"vitest": "^1.5.2"
},
"sideEffects": false,
"keywords": [
+2 -2
View File
@@ -1,7 +1,7 @@
/// <reference types="vitest" />
/// <reference types="vite/client" />
import { defineConfig, mergeConfig } from 'vitest/config'
import { tanstackViteConfig } from '@tanstack/config/vite'
import { tanstackBuildConfig } from '@tanstack/config/build'
import react from '@vitejs/plugin-react'
const config = defineConfig({
@@ -10,7 +10,7 @@ const config = defineConfig({
export default mergeConfig(
config,
tanstackViteConfig({
tanstackBuildConfig({
entry: [
'./src/index.ts',
'./src/build/index.ts',