Skip to content

Commit

Permalink
feat(webpack): support pre transformer (#1133)
Browse files Browse the repository at this point in the history
Co-authored-by: Anthony Fu <anthonyfu117@hotmail.com>
  • Loading branch information
PatrickChen928 and antfu committed Jul 14, 2022
1 parent 8f1e0b9 commit 2d54cc5
Show file tree
Hide file tree
Showing 7 changed files with 42 additions and 26 deletions.
7 changes: 6 additions & 1 deletion examples/vue-cli/vue.config.js
@@ -1,9 +1,14 @@
const UnoCSS = require('@unocss/webpack').default
const { transformerVariantGroup } = require('unocss')

module.exports = {
configureWebpack: {
plugins: [
UnoCSS(),
UnoCSS({
transformers: [
transformerVariantGroup(),
],
}),
],
},
chainWebpack(config) {
Expand Down
4 changes: 2 additions & 2 deletions package.json
Expand Up @@ -5,7 +5,7 @@
"packageManager": "pnpm@7.3.0",
"scripts": {
"bench": "npm -C bench run bench",
"build": "rimraf packages/*/dist && esno scripts/copy-files.ts && pnpm -r --filter !playground --filter !interactive run build && pnpm -r run build-post",
"build": "rimraf packages/*/dist && esno scripts/copy-files.ts && pnpm -r --filter=./packages/* run build && pnpm -r run build-post",
"dev": "nr stub",
"deploy": "nr stub && npm -C playground run build && npm -C interactive run build",
"interactive": "npm -C interactive run dev",
Expand All @@ -14,7 +14,7 @@
"play": "npm -C playground run dev",
"release": "bumpp package.json packages/**/package.json",
"size": "esno scripts/size.ts",
"stub": "pnpm -r --parallel run stub",
"stub": "pnpm -r --filter=./packages/* --parallel run stub",
"typecheck": "tsc --noEmit",
"test": "vitest",
"test:update": "vitest -u"
Expand Down
2 changes: 0 additions & 2 deletions packages/core/src/types.ts
Expand Up @@ -594,8 +594,6 @@ export interface PluginOptions {

/**
* Custom transformers to the source code
*
* Currently only supported in Vite
*/
transformers?: SourceCodeTransformer[]
}
Expand Down
2 changes: 2 additions & 0 deletions packages/webpack/package.json
Expand Up @@ -40,9 +40,11 @@
"webpack": "^4 || ^5"
},
"dependencies": {
"@ampproject/remapping": "^2.2.0",
"@rollup/pluginutils": "^4.2.1",
"@unocss/config": "workspace:*",
"@unocss/core": "workspace:*",
"magic-string": "^0.26.2",
"unplugin": "^0.7.0",
"webpack-sources": "^3.2.3"
},
Expand Down
47 changes: 27 additions & 20 deletions packages/webpack/src/index.ts
Expand Up @@ -2,18 +2,11 @@ import type { UserConfig, UserConfigDefaults } from '@unocss/core'
import type { ResolvedUnpluginOptions, UnpluginOptions } from 'unplugin'
import { createUnplugin } from 'unplugin'
import WebpackSources from 'webpack-sources'
import {
HASH_PLACEHOLDER_RE,
LAYER_MARK_ALL,
LAYER_PLACEHOLDER_RE,
createContext,
getHash,
getHashPlaceholder,
getLayerPlaceholder,
getPath,
resolveId,
resolveLayer,
} from '../../shared-integration/src'
import { createContext } from '../../shared-integration/src/context'
import { getHash } from '../../shared-integration/src/hash'
import { HASH_PLACEHOLDER_RE, LAYER_MARK_ALL, LAYER_PLACEHOLDER_RE, getHashPlaceholder, getLayerPlaceholder, resolveId, resolveLayer } from '../../shared-integration/src/layers'
import { applyTransformers } from '../../shared-integration/src/transformers'
import { getPath } from '../../shared-integration/src/utils'

export interface WebpackPluginOptions<Theme extends {} = {}> extends UserConfig<Theme> {}

Expand All @@ -29,28 +22,42 @@ export default function WebpackPlugin<Theme extends {}>(
defaults?: UserConfigDefaults,
) {
return createUnplugin(() => {
const context = createContext(configOrPath, defaults)
const { uno, tokens, filter, extract, onInvalidate } = context
const ctx = createContext<WebpackPluginOptions>(configOrPath as any, defaults)
const { uno, tokens, filter, extract, onInvalidate } = ctx

let timer: any
onInvalidate(() => {
clearTimeout(timer)
timer = setTimeout(updateModules, UPDATE_DEBOUNCE)
})

const nonPreTransformers = ctx.uno.config.transformers?.filter(i => i.enforce !== 'pre')
if (nonPreTransformers?.length) {
console.warn(
// eslint-disable-next-line prefer-template
'[unocss] webpack integration only supports "pre" enforce transformers currently.'
+ 'the following transformers will be ignored\n'
+ nonPreTransformers.map(i => ` - ${i.name}`).join('\n'),
)
}

const tasks: Promise<any>[] = []
const entries = new Set<string>()
const hashs = new Map<string, string>()
const hashes = new Map<string, string>()

const plugin = <UnpluginOptions>{
name: 'unocss:webpack',
enforce: 'pre',
transformInclude(id) {
return filter('', id)
},
transform(code, id) {
tasks.push(extract(code, id))
return null
async transform(code, id) {
const result = await applyTransformers(ctx, code, id, 'pre')
if (result == null)
tasks.push(extract(code, id))
else
tasks.push(extract(result.code, id))
return result
},
resolveId(id) {
const entry = resolveId(id)
Expand All @@ -72,7 +79,7 @@ export default function WebpackPlugin<Theme extends {}>(
if (entry)
layer = resolveLayer(entry)
}
const hash = hashs.get(id)
const hash = hashes.get(id)
if (layer)
return (hash ? getHashPlaceholder(hash) : '') + getLayerPlaceholder(layer)
},
Expand Down Expand Up @@ -131,7 +138,7 @@ export default function WebpackPlugin<Theme extends {}>(
: result.getLayer(layer) || ''

const hash = getHash(code)
hashs.set(path, hash)
hashes.set(path, hash)
plugin.__vfs.writeModule(id, code)
})
}
Expand Down
4 changes: 4 additions & 0 deletions pnpm-lock.yaml

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

2 changes: 1 addition & 1 deletion test/fixtures/vite/package.json
@@ -1,6 +1,6 @@
{
"private": true,
"version": "0.0.0",
"private": true,
"scripts": {
"dev": "vite",
"build": "vite build"
Expand Down

0 comments on commit 2d54cc5

Please sign in to comment.