@unhead/addons 3.0.0-beta.8 → 3.0.0-rc.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +3 -18
- package/dist/index.d.ts +3 -18
- package/dist/index.mjs +2 -12
- package/dist/vite.d.mts +2 -6
- package/dist/vite.d.ts +2 -6
- package/dist/vite.mjs +2 -17
- package/dist/webpack.d.mts +2 -5
- package/dist/webpack.d.ts +2 -5
- package/dist/webpack.mjs +3 -17
- package/package.json +9 -24
- package/README.md +0 -124
- package/dist/shared/addons.51MZ0zeg.d.mts +0 -28
- package/dist/shared/addons.51MZ0zeg.d.ts +0 -28
- package/dist/shared/addons.CqpZJkhe.mjs +0 -264
- package/vite.d.ts +0 -1
- package/webpack.d.ts +0 -1
package/dist/index.d.mts
CHANGED
|
@@ -1,18 +1,3 @@
|
|
|
1
|
-
export
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
htmlAttrs: {
|
|
5
|
-
lang: string;
|
|
6
|
-
};
|
|
7
|
-
meta: ({
|
|
8
|
-
charset: string;
|
|
9
|
-
name?: undefined;
|
|
10
|
-
content?: undefined;
|
|
11
|
-
} | {
|
|
12
|
-
name: string;
|
|
13
|
-
content: string;
|
|
14
|
-
charset?: undefined;
|
|
15
|
-
})[];
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
export { DefaultCriticalTags };
|
|
1
|
+
export * from '@unhead/bundler';
|
|
2
|
+
import '@unhead/bundler/vite';
|
|
3
|
+
import '@unhead/bundler/webpack';
|
package/dist/index.d.ts
CHANGED
|
@@ -1,18 +1,3 @@
|
|
|
1
|
-
export
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
htmlAttrs: {
|
|
5
|
-
lang: string;
|
|
6
|
-
};
|
|
7
|
-
meta: ({
|
|
8
|
-
charset: string;
|
|
9
|
-
name?: undefined;
|
|
10
|
-
content?: undefined;
|
|
11
|
-
} | {
|
|
12
|
-
name: string;
|
|
13
|
-
content: string;
|
|
14
|
-
charset?: undefined;
|
|
15
|
-
})[];
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
export { DefaultCriticalTags };
|
|
1
|
+
export * from '@unhead/bundler';
|
|
2
|
+
import '@unhead/bundler/vite';
|
|
3
|
+
import '@unhead/bundler/webpack';
|
package/dist/index.mjs
CHANGED
|
@@ -1,13 +1,3 @@
|
|
|
1
|
-
export
|
|
1
|
+
export * from '@unhead/bundler';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
htmlAttrs: {
|
|
5
|
-
lang: "en"
|
|
6
|
-
},
|
|
7
|
-
meta: [
|
|
8
|
-
{ charset: "utf-8" },
|
|
9
|
-
{ name: "viewport", content: "width=device-width, initial-scale=1" }
|
|
10
|
-
]
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
export { DefaultCriticalTags };
|
|
3
|
+
console.warn("[unhead] `@unhead/addons` is deprecated. Please migrate to `@unhead/bundler` instead.");
|
package/dist/vite.d.mts
CHANGED
|
@@ -1,6 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
declare const _default: (options?: UnpluginOptions) => Plugin[];
|
|
5
|
-
|
|
6
|
-
export { UnpluginOptions, _default as default };
|
|
1
|
+
export * from '@unhead/bundler/vite';
|
|
2
|
+
export { Unhead as default } from '@unhead/bundler/vite';
|
package/dist/vite.d.ts
CHANGED
|
@@ -1,6 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
declare const _default: (options?: UnpluginOptions) => Plugin[];
|
|
5
|
-
|
|
6
|
-
export { UnpluginOptions, _default as default };
|
|
1
|
+
export * from '@unhead/bundler/vite';
|
|
2
|
+
export { Unhead as default } from '@unhead/bundler/vite';
|
package/dist/vite.mjs
CHANGED
|
@@ -1,18 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
import 'node:url';
|
|
3
|
-
import 'magic-string';
|
|
4
|
-
import 'oxc-parser';
|
|
5
|
-
import 'oxc-walker';
|
|
6
|
-
import 'ufo';
|
|
7
|
-
import 'unplugin';
|
|
8
|
-
import 'node:vm';
|
|
9
|
-
import 'unhead/utils';
|
|
1
|
+
export { Unhead as default } from '@unhead/bundler/vite';
|
|
10
2
|
|
|
11
|
-
|
|
12
|
-
return [
|
|
13
|
-
TreeshakeServerComposables.vite({ filter: options.filter, sourcemap: options.sourcemap, ...options.treeshake }),
|
|
14
|
-
UseSeoMetaTransform.vite({ filter: options.filter, sourcemap: options.sourcemap, ...options.transformSeoMeta })
|
|
15
|
-
];
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
export { vite as default };
|
|
3
|
+
console.warn("[unhead] `@unhead/addons/vite` is deprecated. Please migrate to `@unhead/bundler/vite` instead.");
|
package/dist/webpack.d.mts
CHANGED
|
@@ -1,5 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
declare const _default: (options?: UnpluginOptions) => any[];
|
|
4
|
-
|
|
5
|
-
export { UnpluginOptions, _default as default };
|
|
1
|
+
export * from '@unhead/bundler/webpack';
|
|
2
|
+
export { default } from '@unhead/bundler/webpack';
|
package/dist/webpack.d.ts
CHANGED
|
@@ -1,5 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
declare const _default: (options?: UnpluginOptions) => any[];
|
|
4
|
-
|
|
5
|
-
export { UnpluginOptions, _default as default };
|
|
1
|
+
export * from '@unhead/bundler/webpack';
|
|
2
|
+
export { default } from '@unhead/bundler/webpack';
|
package/dist/webpack.mjs
CHANGED
|
@@ -1,18 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
import 'magic-string';
|
|
4
|
-
import 'oxc-parser';
|
|
5
|
-
import 'oxc-walker';
|
|
6
|
-
import 'ufo';
|
|
7
|
-
import 'unplugin';
|
|
8
|
-
import 'node:vm';
|
|
9
|
-
import 'unhead/utils';
|
|
1
|
+
export * from '@unhead/bundler/webpack';
|
|
2
|
+
export { default } from '@unhead/bundler/webpack';
|
|
10
3
|
|
|
11
|
-
|
|
12
|
-
return [
|
|
13
|
-
TreeshakeServerComposables.webpack({ filter: options.filter, sourcemap: options.sourcemap, ...options.treeshake || {} }),
|
|
14
|
-
UseSeoMetaTransform.webpack({ filter: options.filter, sourcemap: options.sourcemap, ...options.transformSeoMeta || {} })
|
|
15
|
-
];
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
export { webpack as default };
|
|
4
|
+
console.warn("[unhead] `@unhead/addons/webpack` is deprecated. Please migrate to `@unhead/bundler/webpack` instead.");
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@unhead/addons",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "3.0.0-
|
|
5
|
-
"description": "
|
|
4
|
+
"version": "3.0.0-rc.3",
|
|
5
|
+
"description": "Deprecated. Use @unhead/bundler instead.",
|
|
6
6
|
"author": "Harlan Wilton <harlan@harlanzw.com>",
|
|
7
7
|
"license": "MIT",
|
|
8
8
|
"funding": "https://github.com/sponsors/harlan-zw",
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"repository": {
|
|
11
11
|
"type": "git",
|
|
12
12
|
"url": "git+https://github.com/unjs/unhead.git",
|
|
13
|
-
"directory": "packages/addons"
|
|
13
|
+
"directory": "packages-aliased/addons"
|
|
14
14
|
},
|
|
15
15
|
"publishConfig": {
|
|
16
16
|
"access": "public",
|
|
@@ -19,19 +19,19 @@
|
|
|
19
19
|
"bugs": {
|
|
20
20
|
"url": "https://github.com/unjs/unhead/issues"
|
|
21
21
|
},
|
|
22
|
-
"sideEffects":
|
|
22
|
+
"sideEffects": true,
|
|
23
23
|
"exports": {
|
|
24
24
|
".": {
|
|
25
25
|
"types": "./dist/index.d.ts",
|
|
26
|
-
"
|
|
26
|
+
"import": "./dist/index.mjs"
|
|
27
27
|
},
|
|
28
28
|
"./vite": {
|
|
29
29
|
"types": "./dist/vite.d.ts",
|
|
30
|
-
"
|
|
30
|
+
"import": "./dist/vite.mjs"
|
|
31
31
|
},
|
|
32
32
|
"./webpack": {
|
|
33
33
|
"types": "./dist/webpack.d.ts",
|
|
34
|
-
"
|
|
34
|
+
"import": "./dist/webpack.mjs"
|
|
35
35
|
}
|
|
36
36
|
},
|
|
37
37
|
"main": "dist/index.mjs",
|
|
@@ -48,28 +48,13 @@
|
|
|
48
48
|
}
|
|
49
49
|
},
|
|
50
50
|
"files": [
|
|
51
|
-
"*.d.ts",
|
|
52
51
|
"dist"
|
|
53
52
|
],
|
|
54
53
|
"peerDependencies": {
|
|
55
|
-
"unhead": "3.0.0-
|
|
56
|
-
},
|
|
57
|
-
"dependencies": {
|
|
58
|
-
"@rollup/pluginutils": "^5.3.0",
|
|
59
|
-
"magic-string": "^0.30.21",
|
|
60
|
-
"oxc-parser": "^0.106.0",
|
|
61
|
-
"oxc-walker": "^0.7.0",
|
|
62
|
-
"ufo": "^1.6.2",
|
|
63
|
-
"unplugin": "^2.3.11"
|
|
64
|
-
},
|
|
65
|
-
"devDependencies": {
|
|
66
|
-
"rollup": "^4.55.1",
|
|
67
|
-
"vite": "^7.2.2",
|
|
68
|
-
"unhead": "3.0.0-beta.8"
|
|
54
|
+
"@unhead/bundler": "3.0.0-rc.3"
|
|
69
55
|
},
|
|
70
56
|
"scripts": {
|
|
71
57
|
"build": "unbuild",
|
|
72
|
-
"stub": "unbuild --stub"
|
|
73
|
-
"test:attw": "attw --pack"
|
|
58
|
+
"stub": "unbuild --stub"
|
|
74
59
|
}
|
|
75
60
|
}
|
package/README.md
DELETED
|
@@ -1,124 +0,0 @@
|
|
|
1
|
-
# @unhead/addons
|
|
2
|
-
|
|
3
|
-
> Unhead addons for build tools and bundlers
|
|
4
|
-
|
|
5
|
-
[![npm version][npm-version-src]][npm-version-href]
|
|
6
|
-
[![npm downloads][npm-downloads-src]][npm-downloads-href]
|
|
7
|
-
[![License][license-src]][license-href]
|
|
8
|
-
|
|
9
|
-
## Features
|
|
10
|
-
|
|
11
|
-
- 🛠️ Build-time optimizations for Unhead
|
|
12
|
-
- 🌲 Tree-shake server composables from client bundles
|
|
13
|
-
- ⚡ Transform `useSeoMeta` calls for better performance
|
|
14
|
-
- 📦 Support for Vite, Webpack, and other bundlers
|
|
15
|
-
|
|
16
|
-
## Installation
|
|
17
|
-
|
|
18
|
-
```bash
|
|
19
|
-
# npm
|
|
20
|
-
npm install @unhead/addons
|
|
21
|
-
|
|
22
|
-
# yarn
|
|
23
|
-
yarn add @unhead/addons
|
|
24
|
-
|
|
25
|
-
# pnpm
|
|
26
|
-
pnpm add @unhead/addons
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
## Usage
|
|
30
|
-
|
|
31
|
-
### Vite Plugin
|
|
32
|
-
|
|
33
|
-
```ts
|
|
34
|
-
import UnheadVite from '@unhead/addons/vite'
|
|
35
|
-
// vite.config.ts
|
|
36
|
-
import { defineConfig } from 'vite'
|
|
37
|
-
|
|
38
|
-
export default defineConfig({
|
|
39
|
-
plugins: [
|
|
40
|
-
UnheadVite({
|
|
41
|
-
// Options
|
|
42
|
-
})
|
|
43
|
-
]
|
|
44
|
-
})
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
### Webpack Plugin
|
|
48
|
-
|
|
49
|
-
```js
|
|
50
|
-
// webpack.config.js
|
|
51
|
-
const UnheadWebpack = require('@unhead/addons/webpack')
|
|
52
|
-
|
|
53
|
-
module.exports = {
|
|
54
|
-
plugins: [
|
|
55
|
-
UnheadWebpack({
|
|
56
|
-
// Options
|
|
57
|
-
})
|
|
58
|
-
]
|
|
59
|
-
}
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
### Options
|
|
63
|
-
|
|
64
|
-
```ts
|
|
65
|
-
interface UnpluginOptions {
|
|
66
|
-
// Tree-shake server-only composables from client bundles
|
|
67
|
-
treeshakeServerComposables?: boolean | TreeshakeServerComposablesOptions
|
|
68
|
-
|
|
69
|
-
// Transform useSeoMeta calls for better performance
|
|
70
|
-
useSeoMetaTransform?: boolean | UseSeoMetaTransformOptions
|
|
71
|
-
}
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
## Build Optimizations
|
|
75
|
-
|
|
76
|
-
### Tree-shake Server Composables
|
|
77
|
-
|
|
78
|
-
Automatically removes server-only Unhead composables from client bundles:
|
|
79
|
-
|
|
80
|
-
```ts
|
|
81
|
-
// Before (in client bundle):
|
|
82
|
-
import { useServerHead } from '@unhead/vue'
|
|
83
|
-
|
|
84
|
-
useServerHead({ /* ... */ })
|
|
85
|
-
|
|
86
|
-
// After (removed from client bundle):
|
|
87
|
-
// (code is completely removed)
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
### SEO Meta Transform
|
|
91
|
-
|
|
92
|
-
Optimizes `useSeoMeta` calls for better performance:
|
|
93
|
-
|
|
94
|
-
```ts
|
|
95
|
-
// Before:
|
|
96
|
-
useSeoMeta({
|
|
97
|
-
title: 'My Page',
|
|
98
|
-
description: 'Page description'
|
|
99
|
-
})
|
|
100
|
-
|
|
101
|
-
// After (optimized):
|
|
102
|
-
useHead({
|
|
103
|
-
title: 'My Page',
|
|
104
|
-
meta: [{ name: 'description', content: 'Page description' }]
|
|
105
|
-
})
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
## Documentation
|
|
109
|
-
|
|
110
|
-
Visit the [Unhead documentation](https://unhead.unjs.io/) for more details.
|
|
111
|
-
|
|
112
|
-
## License
|
|
113
|
-
|
|
114
|
-
[MIT](./LICENSE)
|
|
115
|
-
|
|
116
|
-
<!-- Badges -->
|
|
117
|
-
[npm-version-src]: https://img.shields.io/npm/v/@unhead/addons/latest.svg?style=flat&colorA=18181B&colorB=28CF8D
|
|
118
|
-
[npm-version-href]: https://npmjs.com/package/@unhead/addons
|
|
119
|
-
|
|
120
|
-
[npm-downloads-src]: https://img.shields.io/npm/dm/@unhead/addons.svg?style=flat&colorA=18181B&colorB=28CF8D
|
|
121
|
-
[npm-downloads-href]: https://npmjs.com/package/@unhead/addons
|
|
122
|
-
|
|
123
|
-
[license-src]: https://img.shields.io/github/license/unjs/unhead.svg?style=flat&colorA=18181B&colorB=28CF8D
|
|
124
|
-
[license-href]: https://github.com/unjs/unhead/blob/main/LICENSE
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
interface TreeshakeServerComposablesOptions extends BaseTransformerTypes {
|
|
2
|
-
enabled?: boolean;
|
|
3
|
-
}
|
|
4
|
-
|
|
5
|
-
interface UseSeoMetaTransformOptions extends BaseTransformerTypes {
|
|
6
|
-
/**
|
|
7
|
-
* Whether to transform imports of `useSeoMeta` and `useServerSeoMeta` to `useHead` and `useServerHead`.
|
|
8
|
-
*/
|
|
9
|
-
imports?: boolean;
|
|
10
|
-
/**
|
|
11
|
-
* Extra import paths to consider where `useSeoMeta()` may be imported from.
|
|
12
|
-
*/
|
|
13
|
-
importPaths?: string[];
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
interface BaseTransformerTypes {
|
|
17
|
-
sourcemap?: boolean;
|
|
18
|
-
filter?: {
|
|
19
|
-
exclude?: RegExp[];
|
|
20
|
-
include?: RegExp[];
|
|
21
|
-
};
|
|
22
|
-
}
|
|
23
|
-
interface UnpluginOptions extends BaseTransformerTypes {
|
|
24
|
-
treeshake?: TreeshakeServerComposablesOptions;
|
|
25
|
-
transformSeoMeta?: UseSeoMetaTransformOptions;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export type { UnpluginOptions as U };
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
interface TreeshakeServerComposablesOptions extends BaseTransformerTypes {
|
|
2
|
-
enabled?: boolean;
|
|
3
|
-
}
|
|
4
|
-
|
|
5
|
-
interface UseSeoMetaTransformOptions extends BaseTransformerTypes {
|
|
6
|
-
/**
|
|
7
|
-
* Whether to transform imports of `useSeoMeta` and `useServerSeoMeta` to `useHead` and `useServerHead`.
|
|
8
|
-
*/
|
|
9
|
-
imports?: boolean;
|
|
10
|
-
/**
|
|
11
|
-
* Extra import paths to consider where `useSeoMeta()` may be imported from.
|
|
12
|
-
*/
|
|
13
|
-
importPaths?: string[];
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
interface BaseTransformerTypes {
|
|
17
|
-
sourcemap?: boolean;
|
|
18
|
-
filter?: {
|
|
19
|
-
exclude?: RegExp[];
|
|
20
|
-
include?: RegExp[];
|
|
21
|
-
};
|
|
22
|
-
}
|
|
23
|
-
interface UnpluginOptions extends BaseTransformerTypes {
|
|
24
|
-
treeshake?: TreeshakeServerComposablesOptions;
|
|
25
|
-
transformSeoMeta?: UseSeoMetaTransformOptions;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export type { UnpluginOptions as U };
|
|
@@ -1,264 +0,0 @@
|
|
|
1
|
-
import { pathToFileURL } from 'node:url';
|
|
2
|
-
import MagicString from 'magic-string';
|
|
3
|
-
import { parseSync } from 'oxc-parser';
|
|
4
|
-
import { walk, ScopeTracker, ScopeTrackerImport } from 'oxc-walker';
|
|
5
|
-
import { parseURL, parseQuery } from 'ufo';
|
|
6
|
-
import { createUnplugin } from 'unplugin';
|
|
7
|
-
import { createContext, runInContext } from 'node:vm';
|
|
8
|
-
import { resolveMetaKeyType, resolveMetaKeyValue, resolvePackedMetaObjectValue } from 'unhead/utils';
|
|
9
|
-
|
|
10
|
-
const functionNames = [
|
|
11
|
-
"useServerHead",
|
|
12
|
-
"useServerHeadSafe",
|
|
13
|
-
"useServerSeoMeta",
|
|
14
|
-
// plugins
|
|
15
|
-
"useSchemaOrg"
|
|
16
|
-
];
|
|
17
|
-
const TreeshakeServerComposables = createUnplugin((options = {}) => {
|
|
18
|
-
options.enabled = options.enabled !== void 0 ? options.enabled : true;
|
|
19
|
-
return {
|
|
20
|
-
name: "unhead:remove-server-composables",
|
|
21
|
-
enforce: "post",
|
|
22
|
-
transformInclude(id) {
|
|
23
|
-
if (!options.enabled)
|
|
24
|
-
return false;
|
|
25
|
-
const { pathname, search } = parseURL(decodeURIComponent(pathToFileURL(id).href));
|
|
26
|
-
const { type } = parseQuery(search);
|
|
27
|
-
if (pathname.match(/[\\/]node_modules[\\/]/))
|
|
28
|
-
return false;
|
|
29
|
-
if (options.filter?.include?.some((pattern) => id.match(pattern)))
|
|
30
|
-
return true;
|
|
31
|
-
if (options.filter?.exclude?.some((pattern) => id.match(pattern)))
|
|
32
|
-
return false;
|
|
33
|
-
if (pathname.endsWith(".vue") && (type === "script" || !search))
|
|
34
|
-
return true;
|
|
35
|
-
if (pathname.match(/\.((c|m)?j|t)sx?$/g))
|
|
36
|
-
return true;
|
|
37
|
-
return false;
|
|
38
|
-
},
|
|
39
|
-
transform(code, id) {
|
|
40
|
-
if (!code.includes("useServerHead") && !code.includes("useServerHeadSafe") && !code.includes("useServerSeoMeta") && !code.includes("useSchemaOrg")) {
|
|
41
|
-
return;
|
|
42
|
-
}
|
|
43
|
-
const ast = parseSync(id, code);
|
|
44
|
-
const s = new MagicString(code);
|
|
45
|
-
walk(ast.program, {
|
|
46
|
-
enter(node) {
|
|
47
|
-
if (node.type === "ExpressionStatement" && node.expression.type === "CallExpression" && node.expression.callee.type === "Identifier" && functionNames.includes(node.expression.callee.name)) {
|
|
48
|
-
s.remove(node.start, node.end);
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
});
|
|
52
|
-
if (s.hasChanged()) {
|
|
53
|
-
return {
|
|
54
|
-
code: s.toString(),
|
|
55
|
-
map: s.generateMap({ includeContent: true, source: id })
|
|
56
|
-
};
|
|
57
|
-
}
|
|
58
|
-
},
|
|
59
|
-
webpack(ctx) {
|
|
60
|
-
if (ctx.name === "server")
|
|
61
|
-
options.enabled = false;
|
|
62
|
-
},
|
|
63
|
-
vite: {
|
|
64
|
-
apply(config, env) {
|
|
65
|
-
if (env.ssrBuild || env.isSsrBuild) {
|
|
66
|
-
options.enabled = false;
|
|
67
|
-
return true;
|
|
68
|
-
}
|
|
69
|
-
return false;
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
};
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
const SEO_META_NAMES = /* @__PURE__ */ new Set(["useSeoMeta", "useServerSeoMeta"]);
|
|
76
|
-
const UseSeoMetaTransform = createUnplugin((options = {}) => {
|
|
77
|
-
options.imports = options.imports || true;
|
|
78
|
-
function isValidPackage(s) {
|
|
79
|
-
if (s === "unhead" || s.startsWith("@unhead")) {
|
|
80
|
-
return true;
|
|
81
|
-
}
|
|
82
|
-
return [...options.importPaths || []].includes(s);
|
|
83
|
-
}
|
|
84
|
-
return {
|
|
85
|
-
name: "unhead:use-seo-meta-transform",
|
|
86
|
-
enforce: "post",
|
|
87
|
-
transformInclude(id) {
|
|
88
|
-
const { pathname, search } = parseURL(decodeURIComponent(pathToFileURL(id).href));
|
|
89
|
-
const { type } = parseQuery(search);
|
|
90
|
-
if (pathname.match(/[\\/]node_modules[\\/]/))
|
|
91
|
-
return false;
|
|
92
|
-
if (options.filter?.include?.some((pattern) => id.match(pattern)))
|
|
93
|
-
return true;
|
|
94
|
-
if (options.filter?.exclude?.some((pattern) => id.match(pattern)))
|
|
95
|
-
return false;
|
|
96
|
-
if (pathname.endsWith(".vue") && (type === "script" || !search))
|
|
97
|
-
return true;
|
|
98
|
-
if (pathname.match(/\.((c|m)?j|t)sx?$/g))
|
|
99
|
-
return true;
|
|
100
|
-
return false;
|
|
101
|
-
},
|
|
102
|
-
async transform(code, id) {
|
|
103
|
-
if (!code.includes("useSeoMeta") && !code.includes("useServerSeoMeta"))
|
|
104
|
-
return;
|
|
105
|
-
const scopeTracker = new ScopeTracker();
|
|
106
|
-
const ast = parseSync(id, code);
|
|
107
|
-
const s = new MagicString(code);
|
|
108
|
-
const importRewrites = /* @__PURE__ */ new Map();
|
|
109
|
-
const valueReferenced = /* @__PURE__ */ new Set();
|
|
110
|
-
walk(ast.program, {
|
|
111
|
-
scopeTracker,
|
|
112
|
-
enter(node, parent) {
|
|
113
|
-
if (node.type === "Identifier" && !(parent?.type === "CallExpression" && parent.callee === node) && parent?.type !== "ImportSpecifier") {
|
|
114
|
-
const decl2 = scopeTracker.getDeclaration(node.name);
|
|
115
|
-
if (decl2 instanceof ScopeTrackerImport && isValidPackage(decl2.importNode.source.value) && SEO_META_NAMES.has(decl2.node.imported.name)) {
|
|
116
|
-
valueReferenced.add(decl2.node.imported.name);
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
if (node.type !== "CallExpression" || node.callee.type !== "Identifier")
|
|
120
|
-
return;
|
|
121
|
-
const decl = scopeTracker.getDeclaration(node.callee.name);
|
|
122
|
-
let originalName;
|
|
123
|
-
let importDecl = null;
|
|
124
|
-
if (decl instanceof ScopeTrackerImport) {
|
|
125
|
-
if (!isValidPackage(decl.importNode.source.value))
|
|
126
|
-
return;
|
|
127
|
-
originalName = decl.node.imported.name;
|
|
128
|
-
importDecl = decl.importNode;
|
|
129
|
-
} else if (!decl && SEO_META_NAMES.has(node.callee.name)) {
|
|
130
|
-
originalName = node.callee.name;
|
|
131
|
-
} else {
|
|
132
|
-
return;
|
|
133
|
-
}
|
|
134
|
-
if (!SEO_META_NAMES.has(originalName))
|
|
135
|
-
return;
|
|
136
|
-
const properties = node.arguments[0]?.properties;
|
|
137
|
-
if (!properties)
|
|
138
|
-
return;
|
|
139
|
-
let output = [];
|
|
140
|
-
const title = properties.find((property) => property.key?.name === "title");
|
|
141
|
-
const titleTemplate = properties.find((property) => property.key?.name === "titleTemplate");
|
|
142
|
-
const meta = properties.filter((property) => property.key?.name !== "title" && property.key?.name !== "titleTemplate");
|
|
143
|
-
if (title || titleTemplate || originalName === "useSeoMeta") {
|
|
144
|
-
output.push("useHead({");
|
|
145
|
-
if (title) {
|
|
146
|
-
output.push(` title: ${code.substring(title.value.start, title.value.end)},`);
|
|
147
|
-
}
|
|
148
|
-
if (titleTemplate) {
|
|
149
|
-
output.push(` titleTemplate: ${code.substring(titleTemplate.value.start, titleTemplate.value.end)},`);
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
if (originalName === "useServerSeoMeta") {
|
|
153
|
-
if (output.length)
|
|
154
|
-
output.push("});");
|
|
155
|
-
output.push("useServerHead({");
|
|
156
|
-
}
|
|
157
|
-
if (meta.length)
|
|
158
|
-
output.push(" meta: [");
|
|
159
|
-
meta.forEach((property) => {
|
|
160
|
-
if (property.type === "SpreadElement") {
|
|
161
|
-
output = false;
|
|
162
|
-
return;
|
|
163
|
-
}
|
|
164
|
-
if (property.key.type !== "Identifier" || !property.value) {
|
|
165
|
-
output = false;
|
|
166
|
-
return;
|
|
167
|
-
}
|
|
168
|
-
if (output === false)
|
|
169
|
-
return;
|
|
170
|
-
const propertyKey = property.key;
|
|
171
|
-
let key = resolveMetaKeyType(propertyKey.name);
|
|
172
|
-
const keyValue = resolveMetaKeyValue(propertyKey.name);
|
|
173
|
-
let valueKey = "content";
|
|
174
|
-
if (keyValue === "charset") {
|
|
175
|
-
valueKey = "charset";
|
|
176
|
-
key = "charset";
|
|
177
|
-
}
|
|
178
|
-
let value = code.substring(property.value.start, property.value.end);
|
|
179
|
-
if (property.value.type === "ArrayExpression") {
|
|
180
|
-
if (output === false)
|
|
181
|
-
return;
|
|
182
|
-
const elements = property.value.elements;
|
|
183
|
-
if (!elements.length)
|
|
184
|
-
return;
|
|
185
|
-
const metaTags = elements.map((element) => {
|
|
186
|
-
if (element.type !== "ObjectExpression")
|
|
187
|
-
return ` { ${key}: '${keyValue}', ${valueKey}: ${code.substring(element.start, element.end)} },`;
|
|
188
|
-
return element.properties.map((p) => {
|
|
189
|
-
const propKey = p.key.name;
|
|
190
|
-
const propValue = code.substring(p.value.start, p.value.end);
|
|
191
|
-
return ` { ${key}: '${keyValue}:${propKey}', ${valueKey}: ${propValue} },`;
|
|
192
|
-
}).join("\n");
|
|
193
|
-
});
|
|
194
|
-
output.push(metaTags.join("\n"));
|
|
195
|
-
return;
|
|
196
|
-
} else if (property.value.type === "ObjectExpression") {
|
|
197
|
-
const isStatic = property.value.properties.every((p) => p.value.type === "StringLiteral" && typeof p.value.value === "string");
|
|
198
|
-
if (!isStatic) {
|
|
199
|
-
output = false;
|
|
200
|
-
return;
|
|
201
|
-
}
|
|
202
|
-
const context = createContext({
|
|
203
|
-
resolvePackedMetaObjectValue
|
|
204
|
-
});
|
|
205
|
-
const start = property.value.start;
|
|
206
|
-
const end = property.value.end;
|
|
207
|
-
try {
|
|
208
|
-
value = JSON.stringify(runInContext(`resolvePackedMetaObjectValue(${code.slice(start, end)})`, context));
|
|
209
|
-
} catch {
|
|
210
|
-
output = false;
|
|
211
|
-
return;
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
if (valueKey === "charset")
|
|
215
|
-
output.push(` { ${key}: ${value} },`);
|
|
216
|
-
else
|
|
217
|
-
output.push(` { ${key}: '${keyValue}', ${valueKey}: ${value} },`);
|
|
218
|
-
});
|
|
219
|
-
if (output) {
|
|
220
|
-
if (meta.length)
|
|
221
|
-
output.push(" ]");
|
|
222
|
-
output.push("})");
|
|
223
|
-
s.overwrite(node.start, node.end, output.join("\n"));
|
|
224
|
-
if (importDecl) {
|
|
225
|
-
if (!importRewrites.has(importDecl))
|
|
226
|
-
importRewrites.set(importDecl, /* @__PURE__ */ new Set());
|
|
227
|
-
importRewrites.get(importDecl).add(originalName);
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
});
|
|
232
|
-
if (options.imports && importRewrites.size > 0) {
|
|
233
|
-
for (const [importNode, transformedNames] of importRewrites) {
|
|
234
|
-
const newSpecifiers = /* @__PURE__ */ new Set();
|
|
235
|
-
for (const spec of importNode.specifiers) {
|
|
236
|
-
if (spec.type !== "ImportSpecifier")
|
|
237
|
-
continue;
|
|
238
|
-
const importedName = spec.imported.name;
|
|
239
|
-
if (transformedNames.has(importedName)) {
|
|
240
|
-
newSpecifiers.add(importedName.includes("Server") ? "useServerHead" : "useHead");
|
|
241
|
-
if (valueReferenced.has(importedName))
|
|
242
|
-
newSpecifiers.add(importedName);
|
|
243
|
-
} else {
|
|
244
|
-
newSpecifiers.add(importedName);
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
s.overwrite(
|
|
248
|
-
importNode.specifiers[0].start,
|
|
249
|
-
importNode.specifiers[importNode.specifiers.length - 1].end,
|
|
250
|
-
[...newSpecifiers].join(", ")
|
|
251
|
-
);
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
if (s.hasChanged()) {
|
|
255
|
-
return {
|
|
256
|
-
code: s.toString(),
|
|
257
|
-
map: s.generateMap({ includeContent: true, source: id })
|
|
258
|
-
};
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
};
|
|
262
|
-
});
|
|
263
|
-
|
|
264
|
-
export { TreeshakeServerComposables as T, UseSeoMetaTransform as U };
|
package/vite.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './dist/client'
|
package/webpack.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './dist/plugins'
|