rollup+ts开发npm包的知识点总结

开始

使用 rollup + ts 开发插件时遇到的一些问题和知识点,谨以此篇记录自己的学习过程,方便日后复习,也希望能帮助到其他同学。

往期推荐:

解决ts+rollup打包报错以及警告 - 掘金 (juejin.cn)

用ts重构基于rollup的npm包踩坑记录 - 掘金 (juejin.cn)

rollup 版本相关问题

1、rollup 3.x版本配置文件es6语法报错

在使用 2.x 版本打包时, rollup.config.js 配置文件中是可以写 es6 的语法的

然而当升级到最新版本 rollup: 4.14.3rollup.config.js 配置文件中却不能使用 es6 import 语法了!

打包命令: "dev": "rollup -c rollup.config.js -w"

版本: rollup: ^2.78.0 时正常

版本: rollup: 4.14.3 时报错:SyntaxError: Cannot use import statement outside a module

  • 解决方法1

    打包命令添加: --bundleConfigAsCjs

    修改打包命令: "dev": "rollup -c rollup.config.js --bundleConfigAsCjs -w" 重新执行则解决

  • 解决方法2

    package.json 中添加:"type": "module",

    这样设置只是支持 es6语法,但 import 语法是不可以引入 .json文件的!

2、TypeError: Unknown file extension ".json" 报错

rollup.config.js 配置文件中使用了 importrequire 引入了 json 文件报错!

js 复制代码
// import pkg from './package.json'
const pkg = require('./package.json')

注意import、require 是不能引入一个 json文件的!!! 可能是前端脚手架项目 做的多了,以为啥都能 import 进来,但那其实是 Webpack/Rollup 等构建工具带来的额外能力

  • 方案1(只了解,不推荐)

    ES 中有一个新提案 Import Assertions,可以导入非 JS 模块。但只是语法上 Modules Import 类似(注意是类似,并不完全一样),实质上两者并不是同一个语法。就像 ESM 的部分命名导入和对象解构赋值一样,看起来都用了花括号,实际上是完全不同的语法。

    需要显式地声明类型,如:

    python 复制代码
    import data from './xxx.json' assert { type: 'json' };
    
    // 也支持异步导入
    import data = await import('./xxx.json', { assert: { type: 'json' } });

    assert 关键字是一个运行时的类型断言语法,它用于显式地指定导入模块的类型。

    在上面例子中,assert 用于指定导入的 package.json 文件是一个 JSON 文件类型。

    但是这样写是会报语法错误的: SyntaxError: Unexpected identifier

  • 解决方案2(推荐)

    package.json 中设置:"type": "module", config 配置文件使用nodefs 模块 来读取文件

    js 复制代码
    import { readFileSync } from 'fs';
    const pkg = JSON.parse(readFileSync('package.json', { encoding:'utf8' }))
  • 解决方案3

    正常使用 import pkg from './package.json', 打包命令添加:--bundleConfigAsCjs

3、TypeError: nodeResolve is not a function

上面2个问题解决后我的项目又出现了这个报错:

仔细排查发现我在 rollup 配置文件中使用了该插件 :import nodeResolve from '@rollup/plugin-node-resolve';

正确使用方法应该是导出 nodeResolve 方法使用

修改后解决: import { nodeResolve } from '@rollup/plugin-node-resolve';

相关知识点

mjs、cjs相关

  • .mjs文件总是以 ES6 模块规范来加载;

  • .cjs文件总是以 CommonJS 规范模块加载;

  • .js 文件的加载取决于package.json里面type 字段的设置

  • ES6 模块与 CommonJS 模块尽量不要混用
    require命令不能加载.mjs文件,会报错! 只有 import 命令才可以加载.mjs文件

    反之,.mjs文件里面也不能使用 require 命令,必须使用 import

  • 在Vue2项目中我们可以使用 require 是因为 Vue2 的构建工具(如Webpack)提供了对 CommonJS 模块的支持。

插件库开发时注意事项

我们在开发一个公共库、插件时,需要注意的是不应该将 commonjs 和 es6 混用

而且使用 rollup 作为打包工具时,rollup 并不支持 commonjs规定,如果需要支持,必须借助@rollup/plugin-commonjs 插件来完成

开发一个库/插件的打包分类

当你想封装实现一个库或插件包时,你的源码打包可以分成两类:

  • commonjs 规范提供给工程化项目(vue、react项目)使用的npm包

  • es6规范提供给工程化项目(vue、react项目)使用的npm包

  • umd 规范(umd是兼容 cjs/esm/iife/amd/cmd/ 的通用打包格式)可以提供给工程化、非工程化项目使用

package文件中main、module、browser字段

我的rollup工程中 package.json 文件:

js 复制代码
{
  "name": "plugin-zip-pack",
  "version": "1.0.0",
  "description": "用于项目build阶段压缩指定目录资源为.zip包",
  "main": "build/index.umd.js",
  "module": "build/index.mjs",
  "browser": "build/index.browser.js",
  "types": "index.d.ts",
}
  • main字段

    main字段默认输出对应(CommonJS)规范的文件; 所以设置打包输出文件为: build 目录下 index.umd.js(当然也可以是index.cjs

    因为我在 rollup.config.js配置中打包为 umd 通用格式 ,所以这里也就直接输出 index.umd.js

  • module字段

    esm模块 (ES Module)规范,build目录下 打包出 index.mjs

  • browser字段

    适用于script标签方式

基于rollup+ts开发npm包的常用插件

  • pnpm install @babel/core 安装 babel

    es6+语法写起来很爽,但是浏览器不兼容,想写的代码在浏览器上跑起来就需要使用 babel

    babel 可以将我们写的es6+的语法转换为浏览器兼容的语法,比如将箭头函数转换为普通函数等

  • pnpm install @babel/core -D 使用babel需要安装核心模块

  • pnpm install rollup-plugin-babel -D rollup 与 babel 关联

  • pnpm install @babel/preset-env -D 浏览器兼容:将 ES6 语法转译为 ES5

  • pnpm install @rollup/plugin-commonjs -D rollup 默认仅支持es6的模块, 如果工程中使用了 commonjs该插件将commonjs 模块转成es6

  • pnpm install @rollup/plugin-typescript -D 让rollup支持 ts

  • pnpm install @rollup/plugin-node-resolve -D

    rollup 并不知道如何寻找路径以外的依赖如node_module中的依赖。帮助程序可以在项目依赖中找到对应文件

    用于解析Node.js模块。它可以让Rollup打包时使用Node.js模块(包括外部依赖),而不仅仅是ES模块。该插件将检查模块的package.json文件以确定模块的主文件位置,并解决模块之间的依赖关系。此外,它还可以解析模块的绝对路径和相对路径,确保正确地解析和加载模块。

  • pnpm install rollup-plugin-peer-deps-external -D 当开发一个第三方库时,我们不希望第三库和用户安装的依赖发生版本上的冲突, peerDependencies就可以将决定权交给使用者。

  • pnpm install @rollup/plugin-json -D 让rollup支持使用 import导入json文件

  • pnpm install rollup-plugin-dts -D 打包出ts类型文件

  • pnpm install rollup-plugin-terser 代码打包混淆

相关推荐
jonjia1 天前
模块、脚本与声明文件
typescript
jonjia1 天前
配置 TypeScript
typescript
jonjia1 天前
TypeScript 工具函数开发
typescript
jonjia1 天前
注解与断言
typescript
jonjia1 天前
IDE 超能力
typescript
jonjia1 天前
对象类型
typescript
jonjia1 天前
快速搭建 TypeScript 开发环境
typescript
jonjia1 天前
TypeScript 的奇怪之处
typescript
jonjia1 天前
类型派生
typescript
jonjia1 天前
开发流程中的 TypeScript
typescript