开始
使用 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.3
后rollup.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
配置文件中使用了import
或require
引入了 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 的部分命名导入和对象解构赋值一样,看起来都用了花括号,实际上是完全不同的语法。需要显式地声明类型,如:
pythonimport 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 配置文件使用node
的fs
模块 来读取文件jsimport { 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
安装 babeles6+语法写起来很爽,但是浏览器不兼容,想写的代码在浏览器上跑起来就需要使用 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
代码打包混淆