使用Rollup打包Next.js TypeScript库遇Unexpected token错误求助
解决Rollup构建Next.js TypeScript组件库时的JSX解析错误
问题场景
使用Rollup构建Next.js TypeScript组件库并托管到Github时,执行rollup -c命令触发以下错误:
[!] RollupError: Unexpected token (Note that you need plugins to import files that are not JavaScript) src/stories/Banner/Banner.tsx (2:12) 1: export default function Banner() { 2: return (<div className="banner"> ^ 3: <div className="banner__content"> 4: <h1 className="banner__title">Banner Title</h1>
所有JSX元素都会触发该错误。
核心原因
- TS配置未编译JSX:
tsconfig.json中jsx设为preserve,且emitDeclarationOnly为true,导致TypeScript仅生成类型声明文件,不会将JSX语法转换为Rollup可识别的JavaScript代码。 - Rollup输出配置错误:第一个打包任务的输出目标是
.d.ts类型文件,而非实际的JavaScript产物,混淆了编译流程。
解决方案
1. 调整TypeScript编译配置
修改tsconfig.json,让TypeScript负责编译JSX并输出正确的产物和类型声明:
{ "compilerOptions": { "lib": ["dom", "dom.iterable", "esnext"], "allowJs": true, "resolveJsonModule": true, "isolatedModules": true, "jsx": "react-jsx", // 将JSX编译为React.createElement调用 "jsxImportSource": "@emotion/react", // 保留emotion的JSX配置 "incremental": true, "target": "es5", "esModuleInterop": true, "forceConsistentCasingInFileNames": true, "strict": true, "skipLibCheck": true, "module": "ESNext", "declaration": true, "declarationDir": "dist/types", // 类型声明输出到dist/types目录 "sourceMap": true, "outDir": "dist", "moduleResolution": "node", "allowSyntheticDefaultImports": true, "emitDeclarationOnly": false // 关闭仅生成声明,让TS编译JSX为JS }, "include": [ "src/**/*.ts", "src/**/*.tsx", "next-env.d.ts" ], "exclude": ["node_modules", "dist", ".stories"] // 排除无需编译的目录 }
2. 修正Rollup打包配置
调整rollup.config.mjs,让第一个任务输出JavaScript产物,第二个任务合并类型声明:
import commonjs from "@rollup/plugin-commonjs"; import resolve from "@rollup/plugin-node-resolve"; import typescript from "@rollup/plugin-typescript"; import dts from "rollup-plugin-dts"; import peerDepsExternal from 'rollup-plugin-peer-deps-external'; export default [ { input: "src/index.tsx", output: [ { file: "dist/cjs/index.js", // 输出CommonJS格式JS文件 format: "cjs", sourcemap: true, }, { file: "dist/esm/index.js", // 输出ES模块格式JS文件 format: "esm", sourcemap: true, }, ], plugins: [ peerDepsExternal(), // 自动排除peer依赖(如react、react-dom) resolve(), commonjs(), typescript({ tsconfig: "./tsconfig.json" }), ], }, { input: "dist/types/index.d.ts", // 从TS生成的声明文件入口 output: [{ file: "dist/index.d.ts", format: "esm" }], plugins: [dts()], external: [/\.(css|less|scss)$/], }, ];
3. 补充依赖(可选)
如果使用rollup-plugin-peer-deps-external,需要先安装:
npm install rollup-plugin-peer-deps-external --save-dev
4. 清理缓存重新构建
执行构建前删除dist目录,避免旧缓存干扰:
rm -rf dist && rollup -c
内容的提问来源于stack exchange,提问作者Baldvin Bui
相关产品推荐
相关产品推荐

