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 代码打包混淆

相关推荐
奔跑草-10 小时前
【前端】深入浅出 - TypeScript 的详细讲解
前端·javascript·react.js·typescript
新星_13 小时前
构造函数类型
typescript
清灵xmf15 小时前
TypeScript 中的 ! 和 ? 操作符
前端·javascript·typescript·?·
葫芦鱼16 小时前
怎么打造一个舒适的nodejs开发环境
前端·typescript
niech_cn19 小时前
项目启动运行npm run dev报错digital envelope routines::unsupported at new Hash
前端·npm·哈希算法
fukaiit1 天前
vue项目npm run serve出现【- Network: unavailable】(从排查到放弃)
npm·vue·node·win11
promise-render1 天前
npm、yarn、pnpm 切换查看镜像源笔记
前端·笔记·npm
修复bug1 天前
npm完整发包流程(亲测可验证)
前端·npm·开源
丁总学Java1 天前
使用 npm 安装 Yarn
前端·npm·node.js
丁总学Java1 天前
npm list @types/node 命令用于列出当前项目中 @types/node 包及其依赖关系
前端·npm·node.js