Skip to content

Commit

Permalink
stash
Browse files Browse the repository at this point in the history
  • Loading branch information
nonzzz committed Dec 23, 2024
1 parent b4fec3e commit 715ef68
Show file tree
Hide file tree
Showing 6 changed files with 119 additions and 36 deletions.
2 changes: 2 additions & 0 deletions examples/vite-vue-demo/src/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import 'virtual:stylex.css'

// import 'stylex.css'

console.log(colors)

const pulse = keyframes({
'0%': { transform: 'scale(1)' },
'50%': { transform: 'scale(0.5)' },
Expand Down
5 changes: 3 additions & 2 deletions packages/babel-plugin/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,9 @@
},
"dependencies": {
"@babel/core": "^7.23.9",
"@stylexjs/shared": "^0.5.1",
"stylis": "^4.3.1"
"@stylexjs/shared": "^0.9.3",
"stylis": "^4.3.1",
"@dual-bundle/import-meta-resolve": "^4.1.0"
},
"files": [
"dist",
Expand Down
15 changes: 4 additions & 11 deletions packages/babel-plugin/src/ast/evaluate-path.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { types } from '@babel/core'
import type { NodePath } from '@babel/core'
import { utils } from '@stylexjs/shared'

import { MESSAGES } from '../ast/message'
import {
findNearestParentWithCondition,
Expand Down Expand Up @@ -30,7 +29,7 @@ import {
make
} from '../ast/shared'
import type { CSSObjectValue } from '../interface'
import { Module, importPathResolver } from '../module'
import { Module } from '../module'

interface EnvironmentMap {
path: NodePath<types.Node>
Expand Down Expand Up @@ -372,18 +371,12 @@ export function printCssAST(data: ReturnType<typeof sortAndMergeEvaluatedResult>
const importSpecifierPath = bindingPath
const imported = importSpecifierPath.node.imported
const importDeclaration = findNearestParentWithCondition(importSpecifierPath, isImportDeclaration)
const abs = importPathResolver(importDeclaration.node.source.value, mod.filename, {
unstable_moduleResolution: mod.options.unstable_moduleResolution,
aliases: mod.options.aliases
})
if (!abs) {
const hashing = mod.fileNameForHashing(importDeclaration.node.source.value + '.ts')
if (!hashing) {
throw new Error(MESSAGES.NO_STATIC_ATTRIBUTE)
}

// eslint-disable-next-line @typescript-eslint/no-unused-vars
const [_, value] = abs
const strToHash = utils.genFileBasedIdentifier({
fileName: value,
fileName: hashing,
exportName: getStringLikeKindValue(imported),
key: prop.node.name
})
Expand Down
4 changes: 2 additions & 2 deletions packages/babel-plugin/src/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export interface StylexBindingMeta {

export interface ModuleResolutionCommonJS {
type: 'commonJS' | 'haste'
rootDir: string
rootDir?: string
themeFileExtension?: null | undefined | string
}

Expand All @@ -17,7 +17,7 @@ export interface MOduleResolutionHaste {

export interface ModuleResolutionExperimentalCrossFileParsing {
type: 'experimental_crossFileParsing'
rootDir: string
rootDir?: string
themeFileExtension?: null | undefined | string
}

Expand Down
115 changes: 103 additions & 12 deletions packages/babel-plugin/src/module.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import type { NodePath, PluginPass as BabelPluginPass, types } from '@babel/core'
import { resolve as esmResolve } from '@dual-bundle/import-meta-resolve'
import fs from 'fs'
import path from 'path'
import url from 'url'
import * as v from 'valibot'
import type { StylexExtendBabelPluginOptions } from './interface'
import { ImportState } from './visitor/imports'
Expand Down Expand Up @@ -60,6 +63,21 @@ export class Module {
get importIdentifiers() {
return ['create', this.options.transport] as ['create', 'props' | 'attrs']
}

fileNameForHashing(relativePath: string) {
const fileName = filePathResolver(relativePath, this.filename, this.options.aliases)

const { themeFileExtension = '.stylex', type } = this.options.unstable_moduleResolution ?? {}
if (!fileName || !matchFileSuffix(themeFileExtension!)(fileName) || this.options.unstable_moduleResolution == null) {
return null
}
switch (type) {
case 'haste':
return path.basename(fileName)
default:
return getCanonicalFilePath(fileName)
}
}
}

const FILE_EXTENSIONS = ['.js', '.ts', '.tsx', '.jsx', '.mjs', '.cjs']
Expand Down Expand Up @@ -105,7 +123,15 @@ function filePathResolver(relativeFilePath: string, sourceFilePath: string, alia
return require.resolve(importPathStr, {
paths: [path.dirname(sourceFilePath)]
})
} catch {}
} catch {
const resolved = url.fileURLToPath(esmResolve(importPathStr, import.meta.url))
if (resolved) {
if (resolved.startsWith('.')) {
return path.resolve(path.dirname(sourceFilePath), resolved)
}
return resolved
}
}
}

// Otherwise, try to resolve the path with aliases
Expand All @@ -115,7 +141,16 @@ function filePathResolver(relativeFilePath: string, sourceFilePath: string, alia
return require.resolve(possiblePath, {
paths: [path.dirname(sourceFilePath)]
})
} catch {}
} catch {
const resolved = esmResolve(importPathStr, import.meta.url)

if (resolved) {
if (resolved.startsWith('.')) {
return path.resolve(path.dirname(sourceFilePath), resolved)
}
return resolved
}
}
}
}
// Failed to resolve the file path
Expand All @@ -134,31 +169,87 @@ function matchFileSuffix(allowedSuffix: string) {

export type PathResolverOptions = Pick<StylexExtendBabelPluginOptions, 'unstable_moduleResolution' | 'aliases'>

export function importPathResolver(importPath: string, filename: string, options: PathResolverOptions) {
if (!filename) { return null }
export function importPathResolver(importPath: string, fileName: string, options: PathResolverOptions) {
if (!fileName) { return false }
switch (options.unstable_moduleResolution?.type) {
case 'commonJS': {
const { rootDir, themeFileExtension = '.stylex' } = options.unstable_moduleResolution
const { aliases } = options
const { themeFileExtension = '.stylex', rootDir } = options.unstable_moduleResolution
if (!matchFileSuffix(themeFileExtension!)(importPath)) { return false }
const resolvedFilePath = filePathResolver(importPath, filename, aliases)
return resolvedFilePath ? ['Ref', path.relative(rootDir, resolvedFilePath)] : false
const resolvedFilePath = filePathResolver(
importPath,
fileName,
aliases
)
return resolvedFilePath
? ['themeNameRef', getCanonicalFilePath(resolvedFilePath, rootDir)]
: false
}
case 'haste': {
const { themeFileExtension = '.stylex' } = options.unstable_moduleResolution
if (!matchFileSuffix(themeFileExtension!)(importPath)) {
return false
}
return ['themeNameRef', addFileExtension(importPath, fileName)]
}
case 'experimental_crossFileParsing': {
const { aliases } = options
const { themeFileExtension = '.stylex' } = options.unstable_moduleResolution
if (!matchFileSuffix(themeFileExtension!)(importPath)) { return false }
const resolvedFilePath = filePathResolver(
importPath,
filename,
fileName,
aliases
)
return resolvedFilePath ? ['hasteRef', resolvedFilePath] : false
return resolvedFilePath ? ['filePath', resolvedFilePath] : false
}
case 'experimental_crossFileParsing':
// TODO
return false
default:
return false
}
}

// Path: https://github.com/facebook/stylex/blob/main/packages/babel-plugin/src/utils/state-manager.js
// After 0.9.0 this is live

export function getCanonicalFilePath(filePath: string, rootDir?: string) {
const pkgNameAndPath = getPackageNameAndPath(filePath)
if (pkgNameAndPath === null) {
if (rootDir) {
return path.relative(rootDir, filePath)
}
const fileName = path.relative(path.dirname(filePath), filePath)
return `_unknown_path_:${fileName}`
}
const [packageName, packageDir] = pkgNameAndPath
return `${packageName}:${path.relative(packageDir, filePath)}`
}

export function getPackageNameAndPath(filePath: string) {
const folder = path.dirname(filePath)
const hasPackageJSON = fs.existsSync(path.join(folder, 'package.json'))
if (hasPackageJSON) {
try {
const json = JSON.parse(fs.readFileSync(path.join(folder, 'package.json'), 'utf8')) as { name: string }
return [json.name, folder]
} catch (error) {
console.error(error)
return null
}
}
if (folder === path.parse(folder).root || folder === '') {
return null
}
return getPackageNameAndPath(folder)
}

export function addFileExtension(importedFilePath: string, sourceFile: string) {
if (FILE_EXTENSIONS.some((ext) => importedFilePath.endsWith(ext))) {
return importedFilePath
}
const fileExtension = path.extname(sourceFile)
// NOTE: This is unsafe. We are assuming the all files in your project
// use the same file extension.
// However, in a haste module system we have no way to resolve the
// *actual* file to get the actual file extension used.
return importedFilePath + fileExtension
}
14 changes: 5 additions & 9 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 715ef68

Please sign in to comment.