poveste 0.2.0 → 0.3.0
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/node/build.js +0 -3
- package/dist/node/builtin-plugins/tailwind-tokens.d.ts +6 -1
- package/dist/node/builtin-plugins/tailwind-tokens.d.ts.map +1 -1
- package/dist/node/builtin-plugins/tailwind-tokens.js +169 -33
- package/dist/node/builtin-plugins/vanilla-support/MountStory.d.ts +3 -3
- package/dist/node/builtin-plugins/vanilla-support/RenderStory.d.ts +5 -5
- package/dist/node/collect/index.d.ts.map +1 -1
- package/dist/node/collect/index.js +1 -3
- package/dist/node/config.d.ts +2 -18
- package/dist/node/config.d.ts.map +1 -1
- package/dist/node/config.js +3 -0
- package/dist/node/dom/env.d.ts.map +1 -1
- package/dist/node/dom/env.js +10 -6
- package/dist/node/index.d.ts +0 -7
- package/dist/node/index.d.ts.map +1 -1
- package/dist/node/markdown.d.ts.map +1 -1
- package/dist/node/markdown.js +21 -3
- package/dist/node/stories.js +1 -1
- package/dist/node/style-isolation/entry-css-merger.d.ts.map +1 -1
- package/dist/node/style-isolation/entry-css-merger.js +8 -7
- package/dist/node/vite.js +1 -1
- package/package.json +10 -12
- package/src/node/__tests__/dom-env.spec.ts +19 -1
- package/src/node/build.ts +2 -6
- package/src/node/builtin-plugins/tailwind-tokens.ts +190 -34
- package/src/node/collect/index.ts +1 -3
- package/src/node/config.ts +3 -0
- package/src/node/dom/env.ts +10 -6
- package/src/node/index.ts +0 -8
- package/src/node/markdown.ts +25 -3
- package/src/node/stories.ts +1 -1
- package/src/node/style-isolation/__tests__/entry-css-merger.spec.ts +37 -18
- package/src/node/style-isolation/entry-css-merger.ts +10 -9
- package/src/node/vite.ts +4 -4
- package/tsconfig.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Rolldown } from 'vite'
|
|
2
2
|
import { describe, expect, it } from 'vitest'
|
|
3
3
|
import { entryCssMergerPlugin } from '../entry-css-merger.js'
|
|
4
4
|
import { USER_CSS_MARK_END, USER_CSS_MARK_START } from '../vite-plugin.js'
|
|
@@ -30,25 +30,44 @@ function mark(css: string): string {
|
|
|
30
30
|
return `${USER_CSS_MARK_START}\n${css}\n${USER_CSS_MARK_END}\n`
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
+
// Rolldown ignores assignment to `bundle` in generateBundle, so merged CSS is
|
|
34
|
+
// added via this.emitFile. Capture those emits to assert on them.
|
|
35
|
+
function runMerger(plugin: any, bundle: Rolldown.OutputBundle) {
|
|
36
|
+
const emitted = new Map<string, any>()
|
|
37
|
+
const ctx = {
|
|
38
|
+
emitFile: (file: any) => {
|
|
39
|
+
emitted.set(file.fileName, file)
|
|
40
|
+
return file.fileName
|
|
41
|
+
},
|
|
42
|
+
}
|
|
43
|
+
;(plugin.generateBundle as any).call(ctx, {}, bundle)
|
|
44
|
+
return emitted
|
|
45
|
+
}
|
|
46
|
+
|
|
33
47
|
describe('entry-css-merger', () => {
|
|
34
48
|
it('produces one CSS asset per entry chunk', async () => {
|
|
35
49
|
const plugin = entryCssMergerPlugin()
|
|
36
|
-
const bundle: OutputBundle = {
|
|
50
|
+
const bundle: Rolldown.OutputBundle = {
|
|
37
51
|
'bundle-main.js': fakeChunk('bundle-main', ['route1.css', 'route2.css']),
|
|
38
52
|
'bundle-sandbox.js': fakeChunk('bundle-sandbox', ['sandbox-route.css']),
|
|
39
53
|
'route1.css': fakeAsset('route1.css', 'a {}'),
|
|
40
54
|
'route2.css': fakeAsset('route2.css', 'b {}'),
|
|
41
55
|
'sandbox-route.css': fakeAsset('sandbox-route.css', 'c {}'),
|
|
42
56
|
}
|
|
43
|
-
|
|
57
|
+
const emitted = runMerger(plugin, bundle)
|
|
44
58
|
|
|
45
|
-
const cssAssets =
|
|
59
|
+
const cssAssets = [...emitted.values()].filter(a => a.fileName.endsWith('.css'))
|
|
46
60
|
expect(cssAssets).toHaveLength(2)
|
|
47
|
-
const mainCss =
|
|
48
|
-
const sandboxCss =
|
|
61
|
+
const mainCss = emitted.get('bundle-main.css')
|
|
62
|
+
const sandboxCss = emitted.get('bundle-sandbox.css')
|
|
49
63
|
expect(mainCss?.source).toContain('a {}')
|
|
50
64
|
expect(mainCss?.source).toContain('b {}')
|
|
51
65
|
expect(sandboxCss?.source).toContain('c {}')
|
|
66
|
+
|
|
67
|
+
// The per-chunk CSS assets are dropped from the bundle once merged.
|
|
68
|
+
expect(bundle['route1.css']).toBeUndefined()
|
|
69
|
+
expect(bundle['route2.css']).toBeUndefined()
|
|
70
|
+
expect(bundle['sandbox-route.css']).toBeUndefined()
|
|
52
71
|
})
|
|
53
72
|
|
|
54
73
|
it('wraps marked user CSS in @scope on the main entry when isolation is enabled', async () => {
|
|
@@ -57,14 +76,14 @@ describe('entry-css-merger', () => {
|
|
|
57
76
|
scopeRoot: '.__poveste-render-story',
|
|
58
77
|
mainEntryName: 'bundle-main',
|
|
59
78
|
})
|
|
60
|
-
const bundle: OutputBundle = {
|
|
79
|
+
const bundle: Rolldown.OutputBundle = {
|
|
61
80
|
'bundle-main.js': fakeChunk('bundle-main', ['user.css', 'chrome.css']),
|
|
62
81
|
'user.css': fakeAsset('user.css', mark('body { color: red }')),
|
|
63
82
|
'chrome.css': fakeAsset('chrome.css', '@scope (.poveste-app-root) { .x {} }'),
|
|
64
83
|
}
|
|
65
|
-
|
|
84
|
+
const emitted = runMerger(plugin, bundle)
|
|
66
85
|
|
|
67
|
-
const main =
|
|
86
|
+
const main = emitted.get('bundle-main.css')
|
|
68
87
|
expect(main.source).toContain('@scope (.__poveste-render-story)')
|
|
69
88
|
expect(main.source).toContain('color: red')
|
|
70
89
|
expect(main.source).toContain('@scope (.poveste-app-root)')
|
|
@@ -77,13 +96,13 @@ describe('entry-css-merger', () => {
|
|
|
77
96
|
scopeRoot: '.__poveste-render-story',
|
|
78
97
|
mainEntryName: 'bundle-main',
|
|
79
98
|
})
|
|
80
|
-
const bundle: OutputBundle = {
|
|
99
|
+
const bundle: Rolldown.OutputBundle = {
|
|
81
100
|
'bundle-sandbox.js': fakeChunk('bundle-sandbox', ['user.css']),
|
|
82
101
|
'user.css': fakeAsset('user.css', mark('body { color: red }')),
|
|
83
102
|
}
|
|
84
|
-
|
|
103
|
+
const emitted = runMerger(plugin, bundle)
|
|
85
104
|
|
|
86
|
-
const sandbox =
|
|
105
|
+
const sandbox = emitted.get('bundle-sandbox.css')
|
|
87
106
|
expect(sandbox.source).toContain('body')
|
|
88
107
|
expect(sandbox.source).toContain('color: red')
|
|
89
108
|
expect(sandbox.source).not.toContain('@scope')
|
|
@@ -95,14 +114,14 @@ describe('entry-css-merger', () => {
|
|
|
95
114
|
const main = fakeChunk('bundle-main', ['app.css'], '', { imports: ['vendor.js'], isEntry: true })
|
|
96
115
|
main.fileName = 'bundle-main.js'
|
|
97
116
|
const vendor = { ...fakeChunk('vendor', ['vendor.css']), isEntry: false, fileName: 'vendor.js' }
|
|
98
|
-
const bundle: OutputBundle = {
|
|
117
|
+
const bundle: Rolldown.OutputBundle = {
|
|
99
118
|
'bundle-main.js': main,
|
|
100
119
|
'vendor.js': vendor,
|
|
101
120
|
'app.css': fakeAsset('app.css', '.app {}'),
|
|
102
121
|
'vendor.css': fakeAsset('vendor.css', '.vendor {}'),
|
|
103
122
|
}
|
|
104
|
-
|
|
105
|
-
const mainCss =
|
|
123
|
+
const emitted = runMerger(plugin, bundle)
|
|
124
|
+
const mainCss = emitted.get('bundle-main.css')
|
|
106
125
|
expect(mainCss.source).toContain('.app')
|
|
107
126
|
expect(mainCss.source).toContain('.vendor')
|
|
108
127
|
})
|
|
@@ -113,13 +132,13 @@ describe('entry-css-merger', () => {
|
|
|
113
132
|
scopeRoot: '.__poveste-render-story',
|
|
114
133
|
mainEntryName: 'bundle-main',
|
|
115
134
|
})
|
|
116
|
-
const bundle: OutputBundle = {
|
|
135
|
+
const bundle: Rolldown.OutputBundle = {
|
|
117
136
|
'bundle-main.js': fakeChunk('bundle-main', ['user.css']),
|
|
118
137
|
'user.css': fakeAsset('user.css', mark('body { color: red }')),
|
|
119
138
|
}
|
|
120
|
-
|
|
139
|
+
const emitted = runMerger(plugin, bundle)
|
|
121
140
|
|
|
122
|
-
const main =
|
|
141
|
+
const main = emitted.get('bundle-main.css')
|
|
123
142
|
expect(main.source).not.toContain('@scope')
|
|
124
143
|
expect(main.source).not.toContain(USER_CSS_MARK_START)
|
|
125
144
|
})
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type { OutputBundle } from 'rollup'
|
|
2
1
|
import type { Plugin as VitePlugin } from 'vite'
|
|
3
2
|
import { STORY_SCOPE_ROOT } from './selectors.js'
|
|
4
3
|
import { wrapUserCss } from './transforms.js'
|
|
@@ -17,7 +16,7 @@ export function entryCssMergerPlugin(opts: EntryCssMergerOptions = { isolateStyl
|
|
|
17
16
|
name: 'poveste:style-isolation:entry-css-merger',
|
|
18
17
|
apply: 'build',
|
|
19
18
|
enforce: 'post',
|
|
20
|
-
generateBundle(_options, bundle
|
|
19
|
+
generateBundle(_options, bundle) {
|
|
21
20
|
function collectChunkCss(entryFileName: string, entryName: string, acc: Map<string, string[]>) {
|
|
22
21
|
const seen = new Set<string>()
|
|
23
22
|
const queue = [entryFileName]
|
|
@@ -48,6 +47,7 @@ export function entryCssMergerPlugin(opts: EntryCssMergerOptions = { isolateStyl
|
|
|
48
47
|
}
|
|
49
48
|
|
|
50
49
|
const mergedByEntry = new Map<string, string[]>()
|
|
50
|
+
const mergedCssAssets: string[] = []
|
|
51
51
|
for (const [cssName, entries] of cssAssetUsedBy) {
|
|
52
52
|
const asset = bundle[cssName]
|
|
53
53
|
if (!asset || asset.type !== 'asset') continue
|
|
@@ -59,6 +59,13 @@ export function entryCssMergerPlugin(opts: EntryCssMergerOptions = { isolateStyl
|
|
|
59
59
|
list.push(source)
|
|
60
60
|
mergedByEntry.set(entryName, list)
|
|
61
61
|
}
|
|
62
|
+
mergedCssAssets.push(cssName)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Rolldown ignores assignment to `bundle` in generateBundle, so the merged
|
|
66
|
+
// files are added with this.emitFile. The now-merged per-chunk CSS assets
|
|
67
|
+
// are dropped so they don't ship as unscoped, orphaned duplicates.
|
|
68
|
+
for (const cssName of mergedCssAssets) {
|
|
62
69
|
delete bundle[cssName]
|
|
63
70
|
}
|
|
64
71
|
|
|
@@ -68,13 +75,7 @@ export function entryCssMergerPlugin(opts: EntryCssMergerOptions = { isolateStyl
|
|
|
68
75
|
const finalSource = entryName === mainEntryName && opts.isolateStyles
|
|
69
76
|
? wrapMarkedUserCss(merged, scopeRoot)
|
|
70
77
|
: stripMarkers(merged)
|
|
71
|
-
|
|
72
|
-
type: 'asset',
|
|
73
|
-
fileName,
|
|
74
|
-
name: fileName,
|
|
75
|
-
source: finalSource,
|
|
76
|
-
needsCodeReference: false,
|
|
77
|
-
} as any
|
|
78
|
+
this.emitFile({ type: 'asset', fileName, source: finalSource })
|
|
78
79
|
}
|
|
79
80
|
|
|
80
81
|
// Re-point CSS metadata: entries claim their own merged file; non-entry
|
package/src/node/vite.ts
CHANGED
|
@@ -30,9 +30,9 @@ export async function mergePovesteViteConfig(viteConfig: InlineConfig, ctx: Cont
|
|
|
30
30
|
const command = ctx.mode === 'dev' ? 'serve' : 'build'
|
|
31
31
|
const overrides = typeof ctx.config.vite === 'function'
|
|
32
32
|
? await ctx.config.vite(viteConfig as ViteConfig, {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
33
|
+
mode: ctx.mode,
|
|
34
|
+
command,
|
|
35
|
+
})
|
|
36
36
|
: ctx.config.vite
|
|
37
37
|
if (overrides) {
|
|
38
38
|
viteConfig = mergeViteConfig(viteConfig, overrides)
|
|
@@ -324,7 +324,7 @@ export async function getViteConfigWithPlugins(isServer: boolean, ctx: Context):
|
|
|
324
324
|
name: 'poveste:flags',
|
|
325
325
|
enforce: 'pre',
|
|
326
326
|
transform(code, id) {
|
|
327
|
-
if (
|
|
327
|
+
if (/\.(?:vue|js)(?:$|\?)/.test(id)) {
|
|
328
328
|
const original = code
|
|
329
329
|
for (const flag in flags) {
|
|
330
330
|
code = code.replace(new RegExp(flag, 'g'), flags[flag])
|