Skip to content

Commit c0297cb

Browse files
committed
feat(module): make server features fully opt-in (lighten nitro bundle)
1 parent baffdc6 commit c0297cb

File tree

13 files changed

+236
-208
lines changed

13 files changed

+236
-208
lines changed

build.config.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,18 @@ export default defineBuildConfig({
1212
input: './src/formats.ts',
1313
builder: 'rollup',
1414
name: 'formats'
15+
},
16+
{
17+
input: './src/generate.ts',
18+
builder: 'rollup',
19+
name: 'generate'
1520
}
1621
],
1722
externals: [
23+
// ??
24+
'formats.mjs',
25+
'generate.mjs',
26+
// ??
1827
'#design-tokens',
1928
'browser-style-dictionary',
2029
'ufo',

docs/content/1.guide/3.API.md

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -70,13 +70,15 @@ Theme tokens gets processed by [Style Dictionary](https://amzn.github.io/style-d
7070

7171
- **Composable usage**
7272
```ts
73-
const token = useTokens('colors.primary')
73+
const { $dt } = useTokens()
74+
75+
const primaryColor = $dt('colors.primary')
7476
```
7577

7678
- **`<template>` usage**
7779
```vue
7880
<template>
79-
<div :style="{ backgroundColor: $tokens('colors.primary') }">
81+
<div :style="{ backgroundColor: $dt('colors.primary') }">
8082
Hello World
8183
</div>
8284
</template>
@@ -86,20 +88,20 @@ Theme tokens gets processed by [Style Dictionary](https://amzn.github.io/style-d
8688
```vue
8789
<style lang="postcss" scoped>
8890
.header {
89-
background-color: v-bind($tokens('colors.primary'));
91+
background-color: v-bind($dt('colors.primary'));
9092
}
9193
</style>
9294
```
9395

9496
- **`import` usage**
9597
```ts [tailwind.config.ts]
96-
import { $tokens } from './.nuxt/theme/tokens.ts'
98+
import { $dt } from '@nuxtjs/design-tokens'
9799

98100
export default {
99101
theme: {
100102
extend: {
101103
colors: {
102-
primary: $tokens('colors.primary')
104+
primary: $dt('colors.primary')
103105
}
104106
}
105107
}
@@ -108,7 +110,7 @@ Theme tokens gets processed by [Style Dictionary](https://amzn.github.io/style-d
108110

109111
- **`server` usage**
110112
```ts [server/api/token.ts]
111-
import { $tokens } from '#theme-tokens'
113+
import { $dt } from '#design-tokens'
112114

113115
export default defineHandler(() => {
114116
return $tokens('colors.base')

package.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,14 @@
1818
"./module": {
1919
"import": "./dist/module.mjs",
2020
"require": "./dist/module.cjs"
21+
},
22+
"./formats": {
23+
"import": "./dist/formats.mjs",
24+
"require": "./dist/formats.cjs"
25+
},
26+
"./generate": {
27+
"import": "./dist/generate.mjs",
28+
"require": "./dist/generate.cjs"
2129
}
2230
},
2331
"main": "./dist/index.mjs",
@@ -29,6 +37,8 @@
2937
"scripts": {
3038
"build": "nuxt-module-build",
3139
"dev": "nuxi dev playground",
40+
"build:dev": "nuxi build playground",
41+
"generate:dev": "nuxi generate playground",
3242
"dev:build": "nuxi build playground",
3343
"dev:prepare": "nuxi prepare playground && nuxt-module-build --stub",
3444
"dev:fixtures": "./.github/scripts/fixture.sh",

playground/nuxt.config.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ export default defineNuxtConfig({
1616

1717
extends: [resolveThemeDir('./theme')],
1818

19-
theme: {
20-
tokens: true
19+
designTokens: {
20+
server: false
2121
}
2222
})

playground/pages/index.vue

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,12 @@
3838
</div>
3939
</template>
4040

41+
<script setup lang="ts">
42+
const { fetch: fetchTokens, $t } = useTokens()
43+
44+
const { data } = await useAsyncData(fetchTokens)
45+
</script>
46+
4147
<style scoped lang="postcss">
4248
.app {
4349
height: 100vh;

src/generate.ts

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
import { existsSync } from 'fs'
2+
import { rm, writeFile } from 'fs/promises'
3+
import type { Core as Instance } from 'browser-style-dictionary/types/browser'
4+
import StyleDictionary from 'browser-style-dictionary/browser.js'
5+
import { tsTypesDeclaration, tsFull, jsFull } from './formats'
6+
import type { NuxtDesignTokens } from './index'
7+
8+
export const stubTokens = async (buildPath: string, force = false) => {
9+
const files = {
10+
'tokens.css': () => '/* This file is empty because no tokens has been provided. */',
11+
'tokens.scss': () => '/* This file is empty because no tokens has been provided. */',
12+
'tokens.json': () => '{}',
13+
'index.js': jsFull,
14+
'index.ts': tsFull,
15+
'types.d.ts': tsTypesDeclaration
16+
}
17+
18+
for (const [file, stubbingFunction] of Object.entries(files)) {
19+
const path = `${buildPath}${file}`
20+
21+
if (force && existsSync(path)) { await rm(path) }
22+
23+
if (!existsSync(path)) { await writeFile(path, stubbingFunction ? stubbingFunction({ tokens: {} }) : '') }
24+
}
25+
}
26+
27+
export const generateTokens = async (
28+
tokens: NuxtDesignTokens,
29+
buildPath: string,
30+
silent = true
31+
) => {
32+
if (!tokens || !Object.keys(tokens).length) {
33+
await stubTokens(buildPath, true)
34+
return
35+
}
36+
37+
let styleDictionary: Instance = StyleDictionary
38+
39+
styleDictionary.fileHeader = {}
40+
41+
styleDictionary.registerTransformGroup({
42+
name: 'tokens-js',
43+
transforms: ['name/cti/kebab', 'size/px', 'color/hex']
44+
})
45+
46+
styleDictionary.registerFormat({
47+
name: 'typescript/types-declaration',
48+
formatter ({ dictionary }) {
49+
return tsTypesDeclaration(dictionary)
50+
}
51+
})
52+
53+
styleDictionary.registerFormat({
54+
name: 'typescript/full',
55+
formatter ({ dictionary }) {
56+
return tsFull(dictionary)
57+
}
58+
})
59+
60+
styleDictionary.registerFormat({
61+
name: 'javascript/full',
62+
formatter ({ dictionary }) {
63+
return jsFull(dictionary)
64+
}
65+
})
66+
67+
styleDictionary = await styleDictionary.extend({
68+
tokens,
69+
platforms: {
70+
scss: {
71+
transformGroup: 'tokens-js',
72+
buildPath,
73+
files: [
74+
{
75+
destination: 'tokens.scss',
76+
format: 'scss/variables'
77+
}
78+
]
79+
},
80+
81+
json: {
82+
transformGroup: 'tokens-js',
83+
buildPath,
84+
files: [
85+
{
86+
destination: 'tokens.json',
87+
format: 'json/flat'
88+
}
89+
]
90+
},
91+
92+
ts: {
93+
transformGroup: 'tokens-js',
94+
buildPath,
95+
files: [
96+
{
97+
destination: 'index.ts',
98+
format: 'typescript/full'
99+
},
100+
{
101+
destination: 'types.d.ts',
102+
format: 'typescript/types-declaration'
103+
}
104+
]
105+
},
106+
107+
js: {
108+
transformGroup: 'tokens-js',
109+
buildPath,
110+
files: [
111+
{
112+
destination: 'index.js',
113+
format: 'javascript/full'
114+
}
115+
]
116+
},
117+
118+
css: {
119+
transformGroup: 'tokens-js',
120+
buildPath,
121+
files: [
122+
{
123+
destination: 'tokens.css',
124+
format: 'css/variables'
125+
}
126+
]
127+
}
128+
}
129+
})
130+
131+
// Weird trick to disable nasty logging
132+
if (silent) {
133+
// @ts-ignore
134+
// eslint-disable-next-line no-console
135+
console._log = console.log
136+
// eslint-disable-next-line no-console
137+
console.log = () => {}
138+
}
139+
140+
styleDictionary.cleanAllPlatforms()
141+
142+
await new Promise(resolve => setTimeout(resolve, 10))
143+
144+
styleDictionary.buildAllPlatforms()
145+
146+
await new Promise(resolve => setTimeout(resolve, 10))
147+
148+
// Weird trick to disable nasty logging
149+
if (silent) {
150+
// @ts-ignore
151+
// eslint-disable-next-line no-console
152+
console.log = console._log
153+
}
154+
}

src/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ export interface NuxtDesignTokens extends ThemeTokens, DesignTokens {
1010
}
1111

1212
export interface NuxtDesignTokensConfig {
13+
server?: boolean
1314
tokens?: NuxtDesignTokens | boolean | string
1415
}
1516

@@ -28,6 +29,7 @@ export interface ModulePublicRuntimeConfig {
2829
// Non-reactive data taken from initial boot
2930
export interface ModulePrivateRuntimeConfig {
3031
tokensDir?: string
32+
server?: boolean
3133
tokensFilePaths?: Array<string>
3234
}
3335

0 commit comments

Comments
 (0)