Skip to content

Commit

Permalink
[build]: fix .d.ts bundle errors
Browse files Browse the repository at this point in the history
- disallow types auto-importing
- fix "`const` initializer" error
  • Loading branch information
0x009922 committed Mar 13, 2023
1 parent 4549d5d commit af6ac34
Show file tree
Hide file tree
Showing 9 changed files with 148 additions and 22 deletions.
7 changes: 0 additions & 7 deletions packages/ui/.eslintrc-auto-import.json
Original file line number Diff line number Diff line change
@@ -1,13 +1,6 @@
{
"globals": {
"Component": true,
"ComponentPublicInstance": true,
"ComputedRef": true,
"EffectScope": true,
"InjectionKey": true,
"PropType": true,
"Ref": true,
"VNode": true,
"asyncComputed": true,
"autoResetRef": true,
"computed": true,
Expand Down
5 changes: 0 additions & 5 deletions packages/ui/auto-imports.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -265,8 +265,3 @@ declare global {
const watchWithFilter: typeof import('@vueuse/core')['watchWithFilter']
const whenever: typeof import('@vueuse/core')['whenever']
}
// for type re-export
declare global {
// @ts-ignore
export type { Component, ComponentPublicInstance, ComputedRef, InjectionKey, PropType, Ref, VNode } from 'vue'
}
3 changes: 3 additions & 0 deletions packages/ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
"cypress": "^12.7.0",
"cypress-axe": "^1.0.0",
"happy-dom": "^8.9.0",
"immer": "^9.0.19",
"postcss": "^8.4.16",
"react": "^18.2.0",
"react-dom": "^18.2.0",
Expand All @@ -80,7 +81,9 @@
"sass": "^1.41.1",
"storybook": "^7.0.0-beta.62",
"tabbable": "^6.0.0",
"ts-pattern": "^4.2.1",
"typescript": "5.0.1-rc",
"unimport": "^3.0.2",
"unplugin-auto-import": "^0.15.1",
"unplugin-icons": "^0.15.3",
"vite": "^4.1.4",
Expand Down
8 changes: 7 additions & 1 deletion packages/ui/rollup.dts.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { defineConfig, type Plugin } from 'rollup'
import dtsPlugin from 'rollup-plugin-dts'
import aliasPlugin from '@rollup/plugin-alias'
import path from 'path'
import { match } from 'ts-pattern'

const shimCssPlugin = (): Plugin => {
const CSS_SUFFIX = `.css.d.ts`
Expand All @@ -22,12 +23,17 @@ export default defineConfig({
plugins: [
aliasPlugin({
entries: {
'@': path.resolve(__dirname, 'src'),
'@': path.resolve(__dirname, 'ts-build'),
},
}),
shimCssPlugin(),
dtsPlugin(),
],
onwarn(warning, defaultHandler) {
match(warning)
.with({ code: 'UNUSED_EXTERNAL_IMPORT', id: 'inject' }, () => {})
.otherwise(defaultHandler)
},
output: {
file: 'dist/lid.d.ts',
format: 'esm',
Expand Down
4 changes: 2 additions & 2 deletions packages/ui/src/components/BodyScrollLockProvider/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { MaybeElementRef } from '@vueuse/core'
import { FunctionalComponent, InjectionKey, PropType } from 'vue'
import type { VNode, InjectionKey, PropType } from 'vue'

export interface BodyScrollLockApi {
lock: (elem: Element) => void
Expand All @@ -18,7 +18,7 @@ export const SBodyScrollLockProvider = /* @__PURE__ */ defineComponent({
},
setup(props, { slots }) {
provide(BODY_SCROLL_LOCK_API_KEY, props.api)
return () => slots.default?.()
return (): VNode[] | undefined => slots.default?.()
},
})

Expand Down
4 changes: 2 additions & 2 deletions packages/ui/src/components/Popover/SPopover.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Ref, cloneVNode, PropType } from 'vue'
import { Ref, cloneVNode, PropType, type VNode } from 'vue'
import { Placement, placements, Instance, State } from '@popperjs/core'
import { MaybeElementRef } from '@vueuse/core'
import { not, or } from '@vueuse/math'
Expand Down Expand Up @@ -230,7 +230,7 @@ export default /* @__PURE__ */ defineComponent({

provide(POPOVER_API_KEY, api)

return () => {
return (): (VNode | null | undefined | false)[] => {
let trigger
{
if (!slots.trigger) {
Expand Down
4 changes: 2 additions & 2 deletions packages/ui/src/components/Toasts/SToastsProvider.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { defineComponent, PropType, provide } from 'vue'
import { defineComponent, type PropType, provide, type VNode } from 'vue'
import { defineToastsApi, TOASTS_API_KEY } from './api'

type ProvideKey = string | Symbol
Expand Down Expand Up @@ -33,6 +33,6 @@ export default /* @__PURE__ */ defineComponent({
provide(key, api)
}

return () => slots.default?.()
return (): undefined | VNode[] => slots.default?.()
},
})
52 changes: 51 additions & 1 deletion packages/ui/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,14 @@ import type { RootNode, TemplateChildNode } from '@vue/compiler-core'
import iconsPlugin from 'unplugin-icons/vite'
import svgPlugin from '@soramitsu-ui/vite-plugin-svg'
import autoImportPlugin from 'unplugin-auto-import/vite'
import { builtinPresets, type InlinePreset } from 'unimport'
import { produce } from 'immer'
import { match } from 'ts-pattern'
import path from 'path'
import fs from 'fs/promises'
import pkg from './package.json' assert { type: 'json' }
import * as url from 'url'
import { Plugin } from 'vite'

// const __filename = url.fileURLToPath(import.meta.url);
const __dirname = url.fileURLToPath(new URL('.', import.meta.url))
Expand Down Expand Up @@ -47,6 +52,35 @@ const vueCompilerTransforms = {
},
}

function rejectTypeImportsFromPreset(preset: InlinePreset): InlinePreset {
return produce(preset, (draft) => {
draft.imports = draft.imports.filter((x) => {
return match(x)
.with({ type: true }, () => false)
.otherwise(() => true)
})
})
}

/**
* When the build is done, it checks the contents of emitted TS declaration file
* and prints a warning if it detects any auto-imported types
*/
function checkAutoImportedTypesPlugin(checkDts = resolve('auto-imports.d.ts')): Plugin {
const testExportType = (dtsContent: string): boolean => {
return /export\s+type\s+\{/.test(dtsContent)
}

return {
name: 'soramitsu-ui:check-auto-imported-types',
apply: 'build',
async closeBundle() {
const content = await fs.readFile(checkDts, { encoding: 'utf-8' })
if (testExportType(content)) this.error(`Type export is detected in auto-imports (file: ${path.relative(process.cwd(), checkDts)})`)
},
}
}

export default defineConfig({
test: {
include: ['src/**/*.spec.ts'],
Expand Down Expand Up @@ -94,11 +128,27 @@ export default defineConfig({
},
}),
autoImportPlugin({
imports: ['vue', '@vueuse/core'],
imports: [
// We have a problem with bundling `.d.ts` using auto-imported types:
// AutoImport plugin sets them all in `global`, and when `vue-tsc`
// transforms the sources, these types are replaced with `globalThis.XXX`.
// `rollup-plugin-dts` bundles it without a problem, but the bundled file fails
// to pass TypeScript check, because the auto-imported types are declared in `globalThis`
// only in the scope of this library, which is incorrect for package distribution.
// Thus, we simply exclude those few types used across the library that are being
// auto-imported, and we import them explicitly instead
rejectTypeImportsFromPreset(builtinPresets.vue),

// This preset doesn't seem to auto-import any types
// ...but if it does in the future, I'd add a manual preset as
// `{ from: '@vueuse/core' }`
'@vueuse/core',
],
eslintrc: {
enabled: true,
},
}),
checkAutoImportedTypesPlugin()
],
build: {
sourcemap: true,
Expand Down
83 changes: 81 additions & 2 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit af6ac34

Please sign in to comment.