Skip to content

Commit

Permalink
Move babel transforms into an independent subfolder. add babel transf…
Browse files Browse the repository at this point in the history
…orms as part of the public api (for non-vite integrations) (#295)
  • Loading branch information
thetarnav authored Apr 1, 2024
2 parents 1598114 + 505d48b commit 7c95245
Show file tree
Hide file tree
Showing 16 changed files with 195 additions and 166 deletions.
5 changes: 5 additions & 0 deletions .changeset/cold-games-flash.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'solid-devtools': minor
---

Expose the babel plugins currently used by vite: `devtoolsJsxLocationPlugin` and `devtoolsNamePlugin`
5 changes: 5 additions & 0 deletions .changeset/wicked-clocks-sing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'solid-devtools': minor
---

exposed babel plugins
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"----------------------BUILD----------------------": "",
"build": "turbo run build --filter=./packages/*",
"----------------------TEST----------------------": "",
"test:unit": "turbo run test --filter=./packages/*",
"test:unit": "turbo run test:unit --filter=./packages/*",
"test:types": "turbo run test:types --filter=./packages/*",
"test:lint": "eslint **/*.{js,ts,tsx,jsx} --ignore-path .gitignore --max-warnings 0",
"test:e2e": "cross-env PW_CHROMIUM_ATTACH_TO_OTHER=1 playwright test -c e2e/playwright.config.ts",
Expand Down
9 changes: 9 additions & 0 deletions packages/main/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,12 @@
"default": "./dist/vite.js"
}
},
"./babel": {
"import": {
"types": "./dist/babel.d.ts",
"default": "./dist/babel.js"
}
},
"./package.json": "./package.json"
},
"typesVersions": {
Expand All @@ -89,6 +95,9 @@
],
"vite": [
"./dist/vite.d.ts"
],
"babel": [
"./dist/babel.d.ts"
]
}
},
Expand Down
3 changes: 3 additions & 0 deletions packages/main/src/babel.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export {DevtoolsModule} from './babel/shared.js'
export {jsxLocationPlugin, JsxLocationPluginConfig} from './babel/location.js'
export {namePlugin} from './babel/name.js'
Original file line number Diff line number Diff line change
@@ -1,18 +1,23 @@
import {assertTransform, cwd, file} from './setup'
import {assertTransform, cwd, file} from './setup_test'

import {LOCATION_ATTRIBUTE_NAME, WINDOW_PROJECTPATH_PROPERTY} from '@solid-devtools/debugger/types'
import {describe, test} from 'vitest'
import {Module, SET_COMPONENT_LOC, SET_COMPONENT_LOC_LOCAL} from '../constants'
import getPlugin from '../location'
import {DevtoolsModule} from './shared'
import {
jsxLocationPlugin,
JsxLocationPluginConfig,
SET_COMPONENT_LOC,
SET_COMPONENT_LOC_LOCAL,
} from './location'

const setLocationImport = `import { ${SET_COMPONENT_LOC} as ${SET_COMPONENT_LOC_LOCAL} } from "${Module.Setup}";`
const setLocationImport = `import { ${SET_COMPONENT_LOC} as ${SET_COMPONENT_LOC_LOCAL} } from "${DevtoolsModule.Setup}";`

describe('location', () => {
const testData: [
name: string,
src: string,
expected: string,
options: Parameters<typeof getPlugin>[0],
options: JsxLocationPluginConfig,
][] = [
[
'function component',
Expand Down Expand Up @@ -55,7 +60,7 @@ globalThis.${WINDOW_PROJECTPATH_PROPERTY} = "${cwd}";`,

testData.forEach(([name, src, expected, options]) => {
test(name, () => {
assertTransform(src, expected, getPlugin(options))
assertTransform(src, expected, jsxLocationPlugin(options))
})
})
})
126 changes: 126 additions & 0 deletions packages/main/src/babel/location.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
import {PluginObj, template} from '@babel/core'
import {NodePath} from '@babel/traverse'
import * as t from '@babel/types'
import {
LOCATION_ATTRIBUTE_NAME,
LocationAttr,
WINDOW_PROJECTPATH_PROPERTY,
} from '@solid-devtools/debugger/types'
import p from 'path'
import {importFromRuntime} from './shared'

const cwd = process.cwd()

export const SET_COMPONENT_LOC = 'setComponentLocation'
export const SET_COMPONENT_LOC_LOCAL = `_$${SET_COMPONENT_LOC}`

const projectPathAst = template(`globalThis.${WINDOW_PROJECTPATH_PROPERTY} = %%loc%%;`)({
loc: t.stringLiteral(cwd),
}) as t.Statement

const buildMarkComponent = template(`${SET_COMPONENT_LOC_LOCAL}(%%loc%%);`) as (
...args: Parameters<ReturnType<typeof template>>
) => t.Statement

const isUpperCase = (s: string): boolean => /^[A-Z]/.test(s)

const getLocationAttribute = (filePath: string, line: number, column: number): LocationAttr =>
`${filePath}:${line}:${column}`

function getNodeLocationAttribute(
node: t.Node,
state: {filename?: unknown},
isJSX = false,
): string | undefined {
if (!node.loc || typeof state.filename !== 'string') return
return getLocationAttribute(
p.relative(cwd, state.filename),
node.loc.start.line,
// 2 is added to place the caret after the "<" character
node.loc.start.column + (isJSX ? 2 : 0),
)
}

let transformCurrentFile = false
let importedRuntime = false

function importComponentSetter(path: NodePath): void {
if (importedRuntime) return
importFromRuntime(path, SET_COMPONENT_LOC, SET_COMPONENT_LOC_LOCAL)
importedRuntime = true
}

export type JsxLocationPluginConfig = {
jsx: boolean
components: boolean
}

export function jsxLocationPlugin(config: JsxLocationPluginConfig): PluginObj<any> {
return {
name: '@solid-devtools/location',
visitor: {
Program(path, state) {
transformCurrentFile = false
importedRuntime = false
// target only project files
if (typeof state.filename !== 'string' || !state.filename.includes(cwd)) return
transformCurrentFile = true

// inject projectPath variable
path.node.body.push(projectPathAst)
},
...(config.jsx && {
JSXOpeningElement(path, state) {
const {openingElement} = path.container as t.JSXElement
if (!transformCurrentFile || openingElement.name.type !== 'JSXIdentifier') return

// Filter native elements
if (isUpperCase(openingElement.name.name)) return

const location = getNodeLocationAttribute(openingElement, state, true)
if (!location) return

openingElement.attributes.push(
t.jsxAttribute(
t.jsxIdentifier(LOCATION_ATTRIBUTE_NAME),
t.stringLiteral(location),
),
)
},
}),
...(config.components && {
FunctionDeclaration(path, state) {
if (!transformCurrentFile || !path.node.id || !isUpperCase(path.node.id.name))
return

const location = getNodeLocationAttribute(path.node, state)
if (!location) return

importComponentSetter(path)

path.node.body.body.unshift(buildMarkComponent({loc: t.stringLiteral(location)}))
},
VariableDeclarator(path, state) {
const {init, id} = path.node
if (
!transformCurrentFile ||
!('name' in id) ||
!isUpperCase(id.name) ||
!init ||
(init.type !== 'FunctionExpression' &&
init.type !== 'ArrowFunctionExpression') ||
init.body.type !== 'BlockStatement'
)
return

const location = getNodeLocationAttribute(path.node, state)
if (!location) return

importComponentSetter(path)

init.body.body.unshift(buildMarkComponent({loc: t.stringLiteral(location)}))
},
}),
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {describe, test} from 'vitest'
import plugin from '../name'
import {assertTransform, testTransform} from './setup'
import {namePlugin} from './name'
import {assertTransform, testTransform} from './setup_test'

describe('returning primitives', () => {
// Positive tests
Expand All @@ -26,7 +26,7 @@ describe('returning primitives', () => {
const signal = ${creator}(undefined, ${extraArg}{
name: "signal"
});`,
plugin,
namePlugin,
true,
)

Expand All @@ -38,7 +38,7 @@ describe('returning primitives', () => {
const signal = ${creator}(5, ${extraArg}{
name: "signal"
});`,
plugin,
namePlugin,
true,
)

Expand All @@ -54,7 +54,7 @@ describe('returning primitives', () => {
name: "signal"
});`,

plugin,
namePlugin,
true,
)

Expand All @@ -72,7 +72,7 @@ describe('returning primitives', () => {
...rest
});`,

plugin,
namePlugin,
true,
)

Expand All @@ -90,7 +90,7 @@ describe('returning primitives', () => {
...rest
});`,

plugin,
namePlugin,
true,
)

Expand All @@ -104,7 +104,7 @@ describe('returning primitives', () => {
name: "signal"
});`,

plugin,
namePlugin,
true,
)

Expand All @@ -118,7 +118,7 @@ describe('returning primitives', () => {
name: "signal"
});`,

plugin,
namePlugin,
true,
)
})
Expand All @@ -137,14 +137,14 @@ describe('returning primitives', () => {
test(`no import`, () => {
const src = `const signal = ${create}();`

assertTransform(src, src, plugin, true)
assertTransform(src, src, namePlugin, true)
})

test(`incorrect import`, () => {
const src = `import { ${create} } from "${module}";
const signal = ${create}();`

assertTransform(src, src, plugin, true)
assertTransform(src, src, namePlugin, true)
})
})
}
Expand Down Expand Up @@ -174,7 +174,7 @@ describe('effect primitives', () => {
name: "in_${fnName}"
});
}`,
plugin,
namePlugin,
true,
)
})
Expand All @@ -191,7 +191,7 @@ describe('effect primitives', () => {
name: "in_${fnName}"
});
};`,
plugin,
namePlugin,
true,
)

Expand All @@ -207,7 +207,7 @@ describe('effect primitives', () => {
name: "in_${fnName}"
});
};`,
plugin,
namePlugin,
true,
)

Expand All @@ -223,7 +223,7 @@ describe('effect primitives', () => {
name: "to_${fnName}"
});
});`,
plugin,
namePlugin,
true,
)
}
Expand All @@ -238,7 +238,7 @@ describe('effect primitives', () => {
${create}(() => {});
}`

assertTransform(src, src, plugin, true)
assertTransform(src, src, namePlugin, true)
})
})
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ function getTarget(
let Sources: Record<Source, Comparable[]>
let FileWithImports: boolean = false

const namePlugin: PluginObj<any> = {
export const namePlugin: PluginObj<any> = {
name: '@solid-devtools/name',
visitor: {
Program() {
Expand Down Expand Up @@ -229,6 +229,4 @@ const namePlugin: PluginObj<any> = {
})
},
},
}

export default namePlugin
}
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import {NodePath} from '@babel/traverse'
import * as t from '@babel/types'

export const enum DevtoolsModule {
Main = 'solid-devtools',
Setup = 'solid-devtools/setup',
}

export function getProgram(path: NodePath): NodePath<t.Program> {
while (!path.isProgram()) {
path = path.parentPath!
Expand Down
7 changes: 0 additions & 7 deletions packages/main/src/vite/constants.ts

This file was deleted.

Loading

0 comments on commit 7c95245

Please sign in to comment.