Skip to content
This repository was archived by the owner on Jul 6, 2025. It is now read-only.

Commit fa37994

Browse files
committed
refactor: improve css-loader plugin
1 parent a49b8e3 commit fa37994

File tree

1 file changed

+40
-39
lines changed

1 file changed

+40
-39
lines changed

plugins/css.ts

Lines changed: 40 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
import CleanCSS from 'https://esm.sh/[email protected]?no-check'
2-
import type { AcceptedPlugin } from 'https://esm.sh/[email protected]'
3-
import PostCSS from 'https://esm.sh/[email protected]'
1+
import CleanCSS from 'https://esm.sh/[email protected]?no-check'
2+
import PostCSS, { AcceptedPlugin } from 'https://esm.sh/[email protected]'
43
import { path } from '../deps.ts'
54
import { existsFileSync } from '../shared/fs.ts'
65
import util from '../shared/util.ts'
@@ -16,47 +15,22 @@ type Options = {
1615
}
1716

1817
export default (options?: Options): LoaderPlugin => {
19-
let postcss: any = null
20-
let loading = (async () => {
21-
if (options?.postcss) {
22-
postcss = PostCSS(await loadPostcssPlugins(options.postcss.plugins))
23-
return
24-
}
25-
26-
for (const name of Array.from(['ts', 'js', 'json']).map(ext => `postcss.config.${ext}`)) {
27-
const p = path.join(Deno.cwd(), name)
28-
if (existsFileSync(p)) {
29-
let config: any = null
30-
if (name.endsWith('.json')) {
31-
config = JSON.parse(await Deno.readTextFile(p))
32-
} else {
33-
const mod = await import('file://' + p)
34-
config = mod.default
35-
if (util.isFunction(config)) {
36-
config = await config()
37-
}
38-
}
39-
if (isPostcssConfig(config)) {
40-
postcss = PostCSS(await loadPostcssPlugins(config.plugins))
41-
return
42-
}
43-
}
44-
}
18+
const isDev = Deno.env.get('BUILD_MODE') === 'production'
19+
const decoder = new TextDecoder()
4520

46-
postcss = PostCSS(await loadPostcssPlugins(['autoprefixer']))
47-
})()
21+
let pcssProcessor: any = null
4822

4923
return {
5024
name: 'css-loader',
5125
type: 'loader',
5226
test: /\.p?css$/i,
5327
acceptHMR: true,
5428
async transform({ url, content }) {
55-
if (postcss == null) {
56-
await loading
29+
if (pcssProcessor == null) {
30+
pcssProcessor = await initPostCSSProcessor(options)
5731
}
58-
const pcss = (await postcss!.process((new TextDecoder).decode(content)).async()).content
59-
const css = Deno.env.get('BUILD_MODE') === 'production' ? cleanCSS.minify(pcss).styles : pcss
32+
const { content: pcss } = await pcssProcessor.process(decoder.decode(content)).async()
33+
const css = isDev ? cleanCSS.minify(pcss).styles : pcss
6034
if (url.startsWith('#inline-style-')) {
6135
return {
6236
code: css,
@@ -75,6 +49,33 @@ export default (options?: Options): LoaderPlugin => {
7549
}
7650
}
7751

52+
async function initPostCSSProcessor(options?: Options) {
53+
if (options?.postcss) {
54+
return PostCSS(await loadPostcssPlugins(options.postcss.plugins))
55+
}
56+
57+
for (const name of Array.from(['ts', 'js', 'json']).map(ext => `postcss.config.${ext}`)) {
58+
const p = path.join(Deno.cwd(), name)
59+
if (existsFileSync(p)) {
60+
let config: any = null
61+
if (name.endsWith('.json')) {
62+
config = JSON.parse(await Deno.readTextFile(p))
63+
} else {
64+
const mod = await import('file://' + p)
65+
config = mod.default
66+
if (util.isFunction(config)) {
67+
config = await config()
68+
}
69+
}
70+
if (isPostcssConfig(config)) {
71+
return PostCSS(await loadPostcssPlugins(config.plugins))
72+
}
73+
}
74+
}
75+
76+
return PostCSS(await loadPostcssPlugins(['autoprefixer']))
77+
}
78+
7879
async function loadPostcssPlugins(plugins: (string | [string, any] | AcceptedPlugin)[]) {
7980
const isDev = Deno.env.get('BUILD_MODE') === 'development'
8081
return await Promise.all(plugins.filter(p => {
@@ -88,17 +89,17 @@ async function loadPostcssPlugins(plugins: (string | [string, any] | AcceptedPlu
8889
return true
8990
}).map(async p => {
9091
if (util.isNEString(p)) {
91-
return await importPostcssPlugin(p)
92+
return await importPostcssPluginByName(p)
9293
} else if (Array.isArray(p)) {
93-
const Plugin = await importPostcssPlugin(p[0])
94+
const Plugin = await importPostcssPluginByName(p[0])
9495
return [Plugin, p[1]]
9596
} else {
9697
return p
9798
}
98-
}) || [])
99+
}))
99100
}
100101

101-
async function importPostcssPlugin(name: string) {
102+
async function importPostcssPluginByName(name: string) {
102103
const { default: Plugin } = await import(`https://esm.sh/${name}[email protected]&no-check`)
103104
return Plugin
104105
}

0 commit comments

Comments
 (0)