Naive UI 打包tsc -b 类型错误

250 阅读2分钟

问题:NaiveUi-2.35.0 源码打包报类型错误;

image.png

本地环境信息

源码版本:NaiveUi-2.35.0

本地 pnpm 版本: v8.6.7

node 版本: v16.15.0

观察源码 package.json

{
  "name": "naive-ui",
  "version": "2.35.0",
  "description": "A Vue 3 Component Library. Fairly Complete, Theme Customizable, Uses TypeScript, Fast",
  "main": "lib/index.js",
  "module": "es/index.js",
  "types": "es/index.d.ts",
  "unpkg": "dist/index.js",
  "jsdelivr": "dist/index.js",
  "scripts": {
    ...
    "build:package": "pnpm run gen-version && pnpm run clean && pnpm run gen-volar-dts && tsc -b --force tsconfig.esm.json && node scripts/pre-build/pre-cjs-build.js && tsc -b --force tsconfig.cjs.json && rollup -c && pnpm run test:umd && node scripts/post-build && rimraf {es,lib}/*.tsbuildinfo",
    "build:es": "pnpm run clean && tsc -b --force tsconfig.esm.json && rimraf {es,lib}/*.tsbuildinfo", // 自己加到
    "clean": "rimraf site lib es dist node_modules/naive-ui themes/tusimple/es themes/tusimple/lib",
  },
  ...
}

scripts -"build:package" 就是打包产物命令,因为项目中是使用 ESModule 规范文件,发现打包是使用 tsc 生成的,自己往scripts下加个简化脚本

"build:es": "pnpm run clean && tsc -b --force tsconfig.esm.json && rimraf {es,lib}/*.tsbuildinfo",

执行 pnpm run build:es 后报类型错误

src/tree-select/src/TreeSelect.tsx:687:17 - error TS2345: Argument of type 'Ref<{ align: string; addEventListener: { <K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLDivElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | ... 1 more ... | undefined): void; (type: string, listener: EventListenerOrEventListenerObject, options?: boolean | ... 1 more ... | undefin...' is not assignable to parameter of type 'Ref<HTMLElement | null>'.
  Type '{ align: string; addEventListener: { <K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLDivElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | ... 1 more ... | undefined): void; (type: string, listener: EventListenerOrEventListenerObject, options?: boolean | ... 1 more ... | undefined):...' is not assignable to type 'HTMLElement | null'.
    Type '{ align: string; addEventListener: { <K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLDivElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | ... 1 more ... | undefined): void; (type: string, listener: EventListenerOrEventListenerObject, options?: boolean | ... 1 more ... | undefined):...' is not assignable to type 'HTMLElement'.
      Types of property 'offsetParent' are incompatible.
        Type '{ readonly attributes: { [x: number]: { readonly localName: string; readonly name: string; readonly namespaceURI: string | null; readonly ownerDocument: { readonly URL: string; alinkColor: string; readonly all: { [x: number]: ...; readonly length: number; item: (nameOrIndex?: string | undefined) => Element | ... 1 m...' is not assignable to type 'Element | null'.

687     useOnResize(menuElRef, handleTriggerOrMenuResize)
                    ~~~~~~~~~


Found 56 errors.

搜索 issues,发现问题已关闭。奇怪为什么我本地不行呢?

看问题的改动点是 vue 版本有关系,查看本地的依赖版本

执行 npm outdated

image.png

本地 vue 版本不是最新版本,(为啥默认 pnpm install 没有安装最新的依赖版本?)

解决方案

1、升级本地 pnpm版本为 v8.10.2

2、删除项目里 node_modules pnpm-lock.yaml,重新 pnpm install

依赖变成最新的,可以正常编译

打包所有包含 sourcemap 产物

1、修改下面文件

rollup.config.js

  output: {
    name: 'naive',
    format: 'umd',
    exports: 'named',
    globals: {
      vue: 'Vue'
    },
    sourcemap: true // +
  }

tsconfig.json

    "lib": ["ESNext", "DOM"],
    "sourceMap": true // +

scripts/post-build/terse-cssr.js

exports.terseCssr = async () => {
  for (const dir of outDirs) {
    for await (const p of walk(dir)) {
      if (p.includes('.cssr.js') && !p.includes('.cssr.js.map')) { // 排除 .map 文件 babel解析会报错
        const code = await fs.readFile(p, 'utf-8')
        await fs.writeFile(p, terseCssr(code))
      }
    }
  }
}

2、pnpm run build:package

image.png