2024-06-20 19:40:14 +02:00
|
|
|
import * as babel from '@babel/core'
|
|
|
|
|
import * as t from '@babel/types'
|
2024-12-01 10:07:35 +01:00
|
|
|
import type { Plugin } from 'vite'
|
|
|
|
|
import type { PluginItem } from '@babel/core'
|
2024-06-20 19:40:14 +02:00
|
|
|
import type {
|
|
|
|
|
Identifier,
|
|
|
|
|
CallExpression,
|
|
|
|
|
ArrowFunctionExpression,
|
|
|
|
|
StringLiteral,
|
|
|
|
|
} from '@babel/types'
|
|
|
|
|
|
2024-12-01 10:07:35 +01:00
|
|
|
import {
|
|
|
|
|
TUONO_MAIN_PACKAGE,
|
|
|
|
|
TUONO_DYNAMIC_FN_ID,
|
|
|
|
|
TUONO_LAZY_FN_ID,
|
|
|
|
|
} from './constants'
|
|
|
|
|
import { isTuonoDynamicFnImported } from './utils'
|
|
|
|
|
|
2024-06-20 19:40:14 +02:00
|
|
|
/**
|
2024-08-14 20:50:47 +02:00
|
|
|
* [SERVER build]
|
2024-06-21 18:52:58 +02:00
|
|
|
* This plugin just removes the `dynamic` imported function from any tuono import
|
2024-06-20 19:40:14 +02:00
|
|
|
*/
|
|
|
|
|
const RemoveTuonoLazyImport: PluginItem = {
|
|
|
|
|
name: 'remove-tuono-lazy-import-plugin',
|
|
|
|
|
visitor: {
|
|
|
|
|
ImportSpecifier: (path) => {
|
2024-10-16 20:41:33 +02:00
|
|
|
if (isTuonoDynamicFnImported(path)) {
|
|
|
|
|
path.remove()
|
2024-06-20 19:40:14 +02:00
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2024-08-14 20:50:47 +02:00
|
|
|
* [CLIENT build]
|
|
|
|
|
* This plugin replace the `dynamic` function with the `lazyLoadComponent` one
|
2024-06-20 19:40:14 +02:00
|
|
|
*/
|
2024-08-14 20:50:47 +02:00
|
|
|
const ReplaceTuonoLazyImport: PluginItem = {
|
|
|
|
|
name: 'remove-tuono-lazy-import-plugin',
|
2024-06-20 19:40:14 +02:00
|
|
|
visitor: {
|
2024-08-14 20:50:47 +02:00
|
|
|
ImportSpecifier: (path) => {
|
2024-10-16 20:41:33 +02:00
|
|
|
if (isTuonoDynamicFnImported(path)) {
|
|
|
|
|
;(path.node.imported as Identifier).name = TUONO_LAZY_FN_ID
|
2024-06-21 18:52:58 +02:00
|
|
|
}
|
|
|
|
|
},
|
2024-06-20 19:40:14 +02:00
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
2024-10-16 20:41:33 +02:00
|
|
|
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)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
2024-06-20 19:40:14 +02:00
|
|
|
/**
|
2024-08-14 20:50:47 +02:00
|
|
|
* [SERVER build]
|
|
|
|
|
* This plugin statically imports the lazy loaded components
|
2024-06-20 19:40:14 +02:00
|
|
|
*/
|
2024-06-21 18:52:58 +02:00
|
|
|
const TurnLazyIntoStaticImport: PluginItem = {
|
|
|
|
|
name: 'turn-lazy-into-static-import-plugin',
|
2024-06-20 19:40:14 +02:00
|
|
|
visitor: {
|
2024-10-16 20:41:33 +02:00
|
|
|
Program: (path) => {
|
|
|
|
|
path.traverse({
|
|
|
|
|
ImportSpecifier: (subPath) => {
|
|
|
|
|
if (isTuonoDynamicFnImported(subPath)) {
|
|
|
|
|
path.traverse(turnLazyIntoStatic)
|
2024-06-20 19:40:14 +02:00
|
|
|
}
|
2024-10-16 20:41:33 +02:00
|
|
|
},
|
2024-06-20 19:40:14 +02:00
|
|
|
})
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function LazyLoadingPlugin(): Plugin {
|
|
|
|
|
return {
|
|
|
|
|
name: 'vite-plugin-tuono-lazy-loading',
|
|
|
|
|
enforce: 'pre',
|
|
|
|
|
transform(code, _id, opts): string | undefined | null {
|
2024-06-21 18:52:58 +02:00
|
|
|
if (
|
|
|
|
|
code.includes(TUONO_DYNAMIC_FN_ID) &&
|
|
|
|
|
code.includes(TUONO_MAIN_PACKAGE)
|
|
|
|
|
) {
|
2024-06-20 19:40:14 +02:00
|
|
|
const res = babel.transformSync(code, {
|
|
|
|
|
plugins: [
|
|
|
|
|
['@babel/plugin-syntax-jsx', {}],
|
|
|
|
|
['@babel/plugin-syntax-typescript', { isTSX: true }],
|
2024-08-14 20:50:47 +02:00
|
|
|
[!opts?.ssr ? ReplaceTuonoLazyImport : []],
|
|
|
|
|
[opts?.ssr ? RemoveTuonoLazyImport : []],
|
2024-06-21 18:52:58 +02:00
|
|
|
[opts?.ssr ? TurnLazyIntoStaticImport : []],
|
2024-06-20 19:40:14 +02:00
|
|
|
],
|
|
|
|
|
sourceMaps: true,
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
return res?.code
|
|
|
|
|
}
|
|
|
|
|
return code
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
}
|