这是indexloc提供的服务,不要输入任何密码
Skip to content

Prevent dynamic fn replacement when not imported by tuono #57

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Oct 16, 2024
Merged
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20.18.0
v20.10.0
2 changes: 1 addition & 1 deletion crates/tuono/Cargo.toml
Original file line number Diff line number Diff line change
@@ -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"
Expand Down
4 changes: 2 additions & 2 deletions crates/tuono_lib/Cargo.toml
Original file line number Diff line number Diff line change
@@ -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"
Expand Down Expand Up @@ -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"] }
Expand Down
2 changes: 1 addition & 1 deletion crates/tuono_lib_macros/Cargo.toml
Original file line number Diff line number Diff line change
@@ -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"]
Expand Down
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -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",
Expand All @@ -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",
Expand All @@ -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"
Expand Down
6 changes: 3 additions & 3 deletions packages/fs-router-vite-plugin/package.json
Original file line number Diff line number Diff line change
@@ -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",
Expand Down Expand Up @@ -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"
}
}
4 changes: 2 additions & 2 deletions packages/fs-router-vite-plugin/vite.config.ts
Original file line number Diff line number Diff line change
@@ -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',
}),
Expand Down
6 changes: 3 additions & 3 deletions packages/lazy-fn-vite-plugin/package.json
Original file line number Diff line number Diff line change
@@ -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",
Expand Down Expand Up @@ -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"
}
}
72 changes: 37 additions & 35 deletions packages/lazy-fn-vite-plugin/src/index.ts
Original file line number Diff line number Diff line change
@@ -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,
Expand All @@ -12,7 +13,6 @@ import * as t from '@babel/types'

import type {
Identifier,
ImportDeclaration,
CallExpression,
ArrowFunctionExpression,
StringLiteral,
Expand All @@ -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()
}
},
},
Expand All @@ -46,46 +41,53 @@ 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
*/
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)
}
}
},
})
},
},
Expand Down
19 changes: 19 additions & 0 deletions packages/lazy-fn-vite-plugin/src/utils.ts
Original file line number Diff line number Diff line change
@@ -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
}
43 changes: 35 additions & 8 deletions packages/lazy-fn-vite-plugin/test/transpileSource.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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]'));`)
})
})
4 changes: 2 additions & 2 deletions packages/lazy-fn-vite-plugin/vite.config.ts
Original file line number Diff line number Diff line change
@@ -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',
}),
Expand Down
12 changes: 6 additions & 6 deletions packages/router/package.json
Original file line number Diff line number Diff line change
@@ -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",
Expand Down Expand Up @@ -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"
}
}
4 changes: 2 additions & 2 deletions packages/router/vite.config.ts
Original file line number Diff line number Diff line change
@@ -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({
Expand All @@ -16,7 +16,7 @@ const config = defineConfig({

export default mergeConfig(
config,
tanstackViteConfig({
tanstackBuildConfig({
entry: './src/index.ts',
srcDir: './src',
}),
Expand Down
4 changes: 2 additions & 2 deletions packages/tuono/package.json
Original file line number Diff line number Diff line change
@@ -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",
Expand Down Expand Up @@ -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": [
Expand Down
Loading