Skip to content

Commit 53d076d

Browse files
committed
refactor: use of more compatible programmes
1 parent d7d3c72 commit 53d076d

File tree

13 files changed

+237
-74
lines changed

13 files changed

+237
-74
lines changed

README.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,32 @@ export default defineNuxtConfig({
4747
```
4848

4949
That's all. Everything's automatic.
50+
51+
### Configuration
52+
53+
Of course, you can also configure it.
54+
55+
```ts
56+
// nuxt.config.ts
57+
export default defineNuxtConfig({
58+
styleExtractor: {
59+
minify: true, // Whether to enable minification
60+
removeUnused: true, // Whether to remove unused styles
61+
},
62+
});
63+
```
64+
65+
#### Custom Transformer
66+
67+
```ts
68+
// style-extractor.mjs
69+
export default (options) => {
70+
return options.css + "body { background: red }";
71+
};
72+
// nuxt.config.ts
73+
export default defineNuxtConfig({
74+
styleExtractor: {
75+
transformFile: "style-extractor.mjs",
76+
},
77+
});
78+
```

README_CN.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,33 @@ export default defineNuxtConfig({
4242
```
4343

4444
仅此而已,一切都是自动的。
45+
46+
### 配置
47+
48+
当然你也可以进行配置
49+
50+
```ts
51+
// nuxt.config.ts
52+
export default defineNuxtConfig({
53+
styleExtractor: {
54+
minify: true, // 是否开启压缩
55+
removeUnused: true, // 是否移除未使用
56+
},
57+
});
58+
```
59+
60+
#### 自定义转换器
61+
62+
```ts
63+
// style-extractor.mjs
64+
export default (options) => {
65+
return options.css + "body { background: red }";
66+
};
67+
68+
// nuxt.config.ts
69+
export default defineNuxtConfig({
70+
styleExtractor: {
71+
transformFile: "style-extractor.mjs",
72+
},
73+
});
74+
```

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,10 @@
3030
},
3131
"dependencies": {
3232
"@nuxt/kit": "^3.12.4",
33-
"ohash": "^1.1.3",
33+
"@types/csso": "^5.0.4",
3434
"cssnano": "^7.0.6",
35+
"csso": "^5.0.5",
36+
"ohash": "^1.1.3",
3537
"purgecss": "^6.0.0",
3638
"purgecss-from-html": "^6.0.0"
3739
},

playground/nuxt.config.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,9 @@ export default defineNuxtConfig({
22
modules: ['../src/module'],
33
devtools: { enabled: true },
44
compatibilityDate: '2024-08-16',
5+
sourcemap: false,
6+
styleExtractor: {
7+
removeUnused: false,
8+
minify: false,
9+
},
510
})

pnpm-lock.yaml

Lines changed: 18 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/module.ts

Lines changed: 65 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { join } from 'node:path'
2-
import fs, { readFile } from 'node:fs/promises'
2+
import fs from 'node:fs/promises'
33
import { existsSync } from 'node:fs'
4+
import { hash } from 'ohash'
45
import { addPlugin, addServerPlugin, addTemplate, addTypeTemplate, createResolver, defineNuxtModule } from '@nuxt/kit'
56

67
function emptyDir(dir: string) {
@@ -14,21 +15,51 @@ function emptyDir(dir: string) {
1415
}
1516

1617
// Module options TypeScript interface definition
17-
export interface ModuleOptions {}
18+
export interface ModuleOptions {
19+
/**
20+
* @default true
21+
*/
22+
minify: boolean
23+
/**
24+
* @default true
25+
*/
26+
removeUnused: boolean
27+
28+
/**
29+
* @default automatically use built-in modules via other configurations by default
30+
* @description Optimise css module path
31+
* @example
32+
* ```
33+
* // style-extractor.mjs
34+
* export default options => {
35+
* return options.css + 'body { background: red }'
36+
* }
37+
*
38+
* // nuxt.config.ts
39+
* export default defineNuxtConfig({
40+
* styleExtractor: {
41+
* transformFile: 'style-extractor.mjs'
42+
* }
43+
* })
44+
* ```
45+
*/
46+
transformFile: string
47+
}
1848

1949
export default defineNuxtModule<ModuleOptions>({
2050
meta: {
2151
name: 'nuxt-style-extractor',
22-
configKey: 'Extracts the style of the page as an external css when rendered on the server side | 提取服务端渲染时页面的 style 为外部 css',
52+
configKey: 'styleExtractor',
2353
},
2454
defaults: {
25-
minify: false,
55+
minify: true,
2656
removeUnused: true,
57+
transformFile: '',
2758
},
2859
async setup(_options, nuxt) {
2960
const resolver = createResolver(import.meta.url)
3061

31-
addPlugin(resolver.resolve('./runtime/inject-style-id.server'))
62+
addPlugin(resolver.resolve('./runtime/plugin.server'))
3263

3364
addServerPlugin(resolver.resolve('./runtime/server/plugins/style-extractor'))
3465

@@ -55,18 +86,43 @@ export default defineNuxtModule<ModuleOptions>({
5586
}
5687

5788
addTemplate({
58-
filename: 'nuxt-style-extractor-options.mjs',
89+
filename: 'nuxt-style-extractor-config-hash.mjs',
90+
getContents() {
91+
return `export const configHash = "${hash(_options)}"`
92+
},
93+
})
5994

95+
addTemplate({
96+
filename: 'nuxt-style-extractor-transform.mjs',
6097
getContents() {
61-
return `export default ${JSON.stringify(_options)}`
98+
if (_options.transformFile !== '') {
99+
return fs.readFile(_options.transformFile, 'utf-8')
100+
}
101+
return fs.readFile(getDefaultTransformFile(), 'utf-8')
62102
},
63103
})
64104

65105
addTypeTemplate({
66-
filename: 'nuxt-style-extractor-options.d.ts',
106+
filename: 'nuxt-style-extractor.d.ts',
67107
getContents() {
68-
return readFile(resolver.resolve('./runtime/nuxt-style-extractor-options.d.ts'), 'utf-8')
108+
return fs.readFile(resolver.resolve('./runtime/nuxt-style-extractor.d.ts'), 'utf-8')
69109
},
70110
})
111+
112+
function getDefaultTransformFile() {
113+
if (_options.minify && _options.removeUnused) {
114+
return resolver.resolve('./runtime/transforms/best.mjs')
115+
}
116+
117+
if (_options.minify) {
118+
return resolver.resolve('./runtime/transforms/minify.mjs')
119+
}
120+
121+
if (_options.removeUnused) {
122+
return resolver.resolve('./runtime/transforms/remove-unused.mjs')
123+
}
124+
125+
return resolver.resolve('./runtime/transforms/plain.mjs')
126+
}
71127
},
72128
})

src/runtime/nuxt-style-extractor-options.d.ts

Lines changed: 0 additions & 8 deletions
This file was deleted.
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
declare module '#build/nuxt-style-extractor-config-hash.mjs' {
2+
export const configHash: string
3+
}
4+
5+
declare module '#build/nuxt-style-extractor-transform.mjs' {
6+
export interface Options {
7+
html: string
8+
css: string
9+
name: string
10+
}
11+
type OptimiseCss = (options: Options) => Promise<string> | string
12+
const optimiseCss: OptimiseCss
13+
export default optimiseCss
14+
}
Lines changed: 4 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,10 @@
11
import { hash } from 'ohash'
2-
import cssnano from 'cssnano'
3-
import { PurgeCSS } from 'purgecss'
4-
import purgehtml from 'purgecss-from-html'
52
import { defineNuxtPlugin } from '#imports'
6-
import extractorOptions from '#build/nuxt-style-extractor-options.mjs'
7-
8-
interface Options {
9-
html: string
10-
css: string
11-
name: string
12-
}
13-
14-
let purgeCssCtx: PurgeCSS
15-
async function removeUnusedCss(options: Options) {
16-
const { html, css } = options
17-
if (!purgeCssCtx) {
18-
purgeCssCtx = new PurgeCSS()
19-
}
20-
const [result] = await purgeCssCtx.purge({
21-
content: [{ raw: html, extension: 'html' }],
22-
css: [{ raw: css }],
23-
extractors: [{
24-
extensions: ['html'],
25-
extractor: purgehtml,
26-
}],
27-
})
28-
return result.css || ''
29-
}
30-
31-
let cssnanoCtx: ReturnType<typeof cssnano>
32-
async function minifyCss(options: Options) {
33-
const { css, name } = options
34-
if (!cssnanoCtx) {
35-
cssnanoCtx = cssnano()
36-
}
37-
38-
const result = await cssnanoCtx.process(css, {
39-
from: name,
40-
map: false,
41-
})
42-
43-
return result.css || ''
44-
}
45-
46-
async function optimiseCss(options: Options) {
47-
if (extractorOptions.removeUnused) {
48-
options.css = await removeUnusedCss(options)
49-
}
50-
51-
if (extractorOptions.minify) {
52-
options.css = await minifyCss(options)
53-
}
54-
55-
return options.css
56-
}
3+
import optimiseCss from '#build/nuxt-style-extractor-transform.mjs'
4+
import { configHash } from '#build/nuxt-style-extractor-config-hash.mjs'
575

586
export default defineNuxtPlugin({
59-
name: 'inject-style-id',
7+
name: 'style-extractor',
608
setup(nuxt) {
619
nuxt.hook('app:rendered', async (nuxtCtx) => {
6210
const html = nuxtCtx.renderResult?.html || ''
@@ -76,7 +24,7 @@ export default defineNuxtPlugin({
7624
return
7725
}
7826

79-
const name = hash([html, style]) + '.css'
27+
const name = hash([html, style, configHash]) + '.css'
8028

8129
const oldCss = await $fetch(`/_css/${name}`)
8230

src/runtime/transforms/best.mjs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { minify } from 'csso'
2+
import { PurgeCSS } from 'purgecss'
3+
import purgehtml from 'purgecss-from-html'
4+
5+
let purgeCssCtx
6+
async function removeUnusedCss(options) {
7+
const { html, css } = options
8+
if (!purgeCssCtx) {
9+
purgeCssCtx = new PurgeCSS()
10+
}
11+
const [result] = await purgeCssCtx.purge({
12+
content: [{ raw: html, extension: 'html' }],
13+
css: [{ raw: css }],
14+
extractors: [{
15+
extensions: ['html'],
16+
extractor: purgehtml,
17+
}],
18+
})
19+
return result.css || ''
20+
}
21+
22+
function minifyCss(options) {
23+
const { css } = options
24+
25+
return minify(css || '', {
26+
sourceMap: false,
27+
}).css
28+
}
29+
30+
async function optimiseCss(options) {
31+
options.css = await removeUnusedCss(options)
32+
33+
options.css = minifyCss(options)
34+
35+
return options.css
36+
}
37+
38+
export default optimiseCss

0 commit comments

Comments
 (0)