Skip to content
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

vscode unocss plugin doesn't work well with the transformer #53

Closed
a1mersnow opened this issue Apr 24, 2023 · 4 comments
Closed

vscode unocss plugin doesn't work well with the transformer #53

a1mersnow opened this issue Apr 24, 2023 · 4 comments

Comments

@a1mersnow
Copy link

I found that vscode unocss plugin doesn't work well with the unocss-preset-weapp/transformer, below is the reason:

First, the vscode unocss plugin use the getMatchedPositionsFromCode function to extract all positions which need to be styled with a dashed underline:

async function getMatchedPositionsFromCode(uno, code, id = '') {
  const s = new MagicString(code)
  const tokens = new Set()
  const ctx = { uno, tokens }

  const transformers = uno.config.transformers?.filter(i => !ignoreTransformers.includes(i.name))
  for (const i of transformers?.filter(i => i.enforce === 'pre') || [])
    await i.transform(s, id, ctx)
  for (const i of transformers?.filter(i => !i.enforce || i.enforce === 'default') || [])
    await i.transform(s, id, ctx)
  for (const i of transformers?.filter(i => i.enforce === 'post') || [])
    await i.transform(s, id, ctx)
  const hasVariantGroup = !!uno.config.transformers?.find(i => i.name === '@unocss/transformer-variant-group')

  const result = await uno.generate(s.toString(), { preflights: false })
  console.log(result.matched)
  return getMatchedPositions(code, [...result.matched], hasVariantGroup, false, uno)
}

Result.matched is all class names that catched by unocss core engine.
Before unocss core engine generate the result, transformers are applied.
So, if the source code is <template><view class="text-#f00">123</view></template>, transformer will transform it to <template><view class="text-_wn_f00">123</view></template>.

However, text-_wn_f00 isn't in original source code which vscode use to find the positions.

This is why.

I found a workaround, but I doesn't know whether it should be adopted into this repo, so I didn't create a pr.

The workaround is:
When we transform the code, we also inject a comment, the comment's content is all class names collected while transforming. The comment's format depends on that the source code is .vue file or .jsx? file.

Here is the key code:

function transformCode(code, rules = defaultRules) {
  const classNames = getClass(code)

  classNames.forEach((c) => {
    let currentClass = c[0]
    c.slice(1).forEach((selector) => {
      currentClass = currentClass.replace(selector, transformSelector(selector, rules))
    })
    code = code.replace(c[0], currentClass)
  })

  const classSet = new Set(classNames.map(x => x[1]).filter(x => x).flatMap(x => x.split(' ')))
  return preserveOriginalClass(code, [...classSet])
}

function preserveOriginalClass(code, uniqueClassList) {
  const injectStr = uniqueClassList.join(' ')
  if (/<template>/.test(code)) {
    return code.replace('<template>', `<template>\n<!-- ${injectStr} -->\n`)
  } else {
    return `/* ${injectStr} */\n` + code
  }
}
@MellowCo
Copy link
Owner

Do you mean it should not be displayed as c_lfl__wn_157_lfr__60 ?

image

@MellowCo
Copy link
Owner

I understand what you mean

@MellowCo
Copy link
Owner

So it's because I wrote c-[#157]_60 twice in the demo, so I didn't notice this issue

image

image

@a1mersnow
Copy link
Author

So it's because I wrote c-[#157]_60 twice in the demo, so I didn't notice this issue

image

image

Yes!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants