You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Yarn2环境执行rollup -c报错Cannot find module 'react'如何解决

Yarn2环境下React组件库Rollup构建问题解答

问题背景

在Yarn2环境下开发React组件库,直接执行yarn rollup -c会抛出找不到react模块的TS2307错误,先执行yarn tsc再执行rollup命令可规避该报错。

相关配置

1. tsconfig.json

{
    "compilerOptions": {
      "declaration": true,
      "declarationDir": "dist/types",
      "target": "es5",
      "lib": ["dom", "dom.iterable", "esnext"],
      "skipLibCheck": true,
      "esModuleInterop": true,
      "allowSyntheticDefaultImports": true,
      "strict": true,
      "module": "es6",
      "moduleResolution": "node",
      "resolveJsonModule": true,
      "jsx": "react",
      "typeRoots": ["@types"],
      "noImplicitAny": false,
      "baseUrl": ".",
      "paths": {
        "@/*": ["/*"],
        "~/*": ["src/*"]
      },
    },
    "include": ["**/*.tsx", "**/*.ts", "@types", "index.ts", "src/index.ts"],
    "exclude": ["build", "dist", "lib", "**/stories", "**/*.stories.tsx", "rollup.config.js"]
}

2. rollup.config.js

import pkg from './package.json';
import typescript from 'rollup-plugin-typescript2';
import peerDepsExternal from 'rollup-plugin-peer-deps-external';
import postcss from 'rollup-plugin-postcss';
import postcssPrefixer from 'postcss-prefixer';
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import json from '@rollup/plugin-json';
import babel from 'rollup-plugin-babel';
import svgr from '@svgr/rollup';
import url from 'rollup-plugin-url';

const extensions = ['.js', '.jsx', '.ts', '.tsx', '.scss'];
process.env.BABEL_ENV = 'production';

function setUpRollup({ input, output }) {
    return {
      input,
      output,
      watch: {
        include: '*',
        exclude: '.yarn/**'
      },
      plugins: [
        peerDepsExternal(),
        json(),
        resolve({ extensions }),
        commonjs(),
        babel({ extensions, runtimeHelpers: true }),
        url(),
        svgr(),
        typescript({
          exclude: [ '**/stories', '**/*.stories'],
          useTsconfigDeclarationDir: true
        }),
        postcss({
          extract: true,
          modules: true,
          sourceMap: true,
          use: ['sass'],
          plugins: [
            postcssPrefixer({
              prefix: `${pkg.name}__`,
            }),
          ],
        }),
      ],
      external: ['react', 'react-dom'],
    };
  };

  export default [
    setUpRollup({
      input: 'src/index.ts',
      output: {
        file: pkg.cjs,
        sourcemap: true,
        format: 'cjs',
      },
    }),
    setUpRollup({
      input: 'src/index.ts',
      output: {
        file: pkg.esm,
        sourcemap: true,
        format: 'esm',
      },
    }),
  ];

3. package.json

{
  "name": "custom-reactfullpage.js",
  "version": "1.0.0",
  "cjs": "dist/cjs.js",
  "esm": "dist/esm.js",
  "main": "dist/index.js",
  "repository": "https://github.com/remigailard80/fullpageLib.js",
  "author": "KIMMINSEOK",
  "license": "NO LICENSE",
  "types": "dist/types/index.d.ts",
  "module": "dist/cjs.js",
  "type": "module",
  "files": [
    "/dist"
  ],
  "devDependencies": {
    "@babel/core": "^7.15.0",
    "@mdx-js/react": "^1.6.22",
    "@rollup/plugin-commonjs": "^20.0.0",
    "@rollup/plugin-json": "^4.1.0",
    "@rollup/plugin-node-resolve": "^13.0.4",
    "@storybook/addon-actions": "^6.3.8",
    "@storybook/addon-docs": "^6.3.8",
    "@storybook/addon-essentials": "^6.3.8",
    "@storybook/addon-links": "^6.3.8",
    "@storybook/cli": "^6.3.8",
    "@storybook/react": "^6.3.8",
    "@svgr/rollup": "^5.5.0",
    "@types/esm": "^3",
    "@types/jest": "^27.0.1",
    "@types/mdx-js__react": "^1",
    "@types/node": "^16.7.10",
    "@types/react": "^17",
    "@types/react-dom": "^17.0.9",
    "@yarnpkg/pnpify": "^3.0.1-rc.2",
    "@yarnpkg/sdks": "^2.4.2-rc.2",
    "babel-loader": "^8.2.2",
    "babel-preset-react-app": "^10.0.0",
    "esm": "^3.2.25",
    "postcss": "^8.3.6",
    "postcss-prefixer": "^2.1.3",
    "react": "^17.0.2",
    "react-docgen-typescript-loader": "^3.7.2",
    "react-dom": "^17.0.2",
    "rollup": "^2.56.3",
    "rollup-plugin-babel": "^4.4.0",
    "rollup-plugin-commonjs": "^10.1.0",
    "rollup-plugin-node-resolve": "^5.2.0",
    "rollup-plugin-peer-deps-external": "^2.2.4",
    "rollup-plugin-postcss": "^4.0.1",
    "rollup-plugin-typescript2": "^0.30.0",
    "rollup-plugin-url": "^3.0.1",
    "typescript": "^4.4.2"
  },
  "peerDependencies": {
    "react": "*",
    "react-dom": "*"
  },
  "scripts": {
    "sb": "start-storybook -p 6006",
    "build-storybook": "build-storybook"
  }
}

问题解答

1. 为什么先执行yarn tsc就能规避找不到react模块的报错?

Yarn2默认使用PNP模式管理依赖,所有依赖路径都由pnp.cjs统一解析。yarn tsc调用的是Yarn SDK包装过的TypeScript实例,执行时会自动加载pnp.cjs的解析逻辑,能正确识别PNP管理的react及其类型文件,同时会生成TS模块解析缓存和类型产物。
而rollup-plugin-typescript2默认会优先使用自身依赖的typescript实例,不会调用Yarn SDK的TS版本,因此直接执行rollup时无法识别PNP的依赖路径,抛出找不到模块的错误。先执行过yarn tsc后,rollup-plugin-typescript2会复用已生成的TS缓存和类型产物,不需要重新走全量模块解析,因此不会触发报错。

2. 如何配置才能无需提前执行tsc,直接执行rollup命令完成构建?

以下三个方案任选其一即可:

  • 方案1:指定rollup使用Yarn SDK的TypeScript实例
    修改rollup.config.js中typescript插件的配置,手动指定TS来源:
    typescript({
      exclude: [ '**/stories', '**/*.stories'],
      useTsconfigDeclarationDir: true,
      typescript: require('typescript') // 新增该行
    })
    
    用yarn执行rollup时,require('typescript')会自动指向Yarn SDK包装的TS实例,加载PNP解析逻辑。
  • 方案2:用pnpify包装rollup命令
    在package.json的scripts中新增构建命令,用pnpify注入PNP解析能力:
    "scripts": {
      "build": "yarn pnpify rollup -c"
    }
    
  • 方案3:兼容传统node_modules模式
    在项目根目录的.yarnrc.yml中添加配置nodeLinker: node-modules,执行yarn install重新生成node_modules目录,即可和传统包管理器行为一致,无需额外适配。

内容的提问来源于stack exchange,提问作者djangoboi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 20:39:02