Docker化Lerna Monorepo集成Storybook时出现‘cannot find module react/package.json’错误求助
Hey there! Let's break down why you're hitting that module error and get your Dockerized Lerna setup working smoothly.
Why This Error Happens
You're running into this issue due to a few conflicting parts in your current setup:
- Volume Mounting Overrides Container Dependencies: Your
docker-compose.ymlmounts your local project directory to/appin the container. While you have an anonymous volume for/app/node_modules, your individual packages'node_modulesdirectories aren't protected. When the container runs, your localpackages/coredirectory (which might not have the right linked dependencies or even anode_modulesfolder) replaces the one built in the image. - Manual Yarn Link Conflicts: The manual
yarn linksteps you added in the Dockerfile work during the build phase, but once you mount your local directory, those links point to paths inside the container that don't exist in your local setup—breaking the React module reference. - Unoptimized Lerna Dependency Handling: Without using Lerna's built-in hoisting, dependencies like React might be installed in individual packages instead of being shared at the root, leading to inconsistent module paths.
Step-by-Step Fixes
1. Simplify & Optimize Your Dockerfile
We'll let Lerna handle dependency management instead of manual linking, and add caching layers to speed up builds:
FROM node:14.13.1-alpine ENV PATH /app/node_modules/.bin:$PATH WORKDIR /app # Copy dependency files first for better build caching COPY package.json yarn.lock ./ COPY lerna.json ./ COPY packages/core/package.json packages/core/ COPY packages/styles/package.json packages/styles/ # Install root dependencies and bootstrap Lerna with hoisting RUN yarn install --frozen-lockfile RUN yarn bootstrap --hoist # Copy the rest of your project code COPY . . # Build your core package (add this script to your root package.json first!) RUN yarn build:core CMD yarn storybook ${STORY_FILTER}
Note: Add a build:core script to your root package.json like this: "build:core": "lerna run build --scope @your-team/core" (replace the scope with your actual package name)
2. Adjust Docker Compose Volumes
Protect individual packages' node_modules directories to avoid overwriting them with your local (possibly empty) folders:
services: packages: container_name: packages image: packages build: context: . dockerfile: Dockerfile volumes: - '.:/app' # Anonymous volumes to preserve container-side dependencies - '/app/node_modules' - '/app/packages/core/node_modules' - '/app/packages/styles/node_modules' ports: - 6006:6006 environment: - CHOKIDAR_USEPOLLING=true - STORY_FILTER=packages/core/stories/forms/index
3. Verify Your Package Dependencies
Double-check that react is listed as a dependency (or devDependency, if only used in Storybook) in your packages/core/package.json. Lerna's hoist will pull it up to the root node_modules, making it accessible to all packages.
Why This Works
- Dependency Caching: By copying lock files and package manifests first, Docker can reuse the dependency installation layer unless your dependencies change.
- Lerna Hoisting: Centralizing shared dependencies like React in the root
node_modulesensures all packages reference the same module path, eliminating "module not found" errors. - Protected Node Modules: The anonymous volumes for each package's
node_moduleskeep the container-installed dependencies intact, even when you mount your local project files.
内容的提问来源于stack exchange,提问作者Dan Lincoln

