在我的react组件( Coffee.jsx )的顶部,我具有以下导入:
import ReactPlayer from 'react-player';
肯定安装了软件包'react-player',位于package.json
和node_modules/
。
我的代码在docker
容器中运行。每当我旋转容器时,就像这样:
docker-compose -f docker-compose-dev.yml up -d
我收到此错误:
./src/components/Coffees.jsx
Module not found: Can't resolve 'react-player' in '/usr/src/app/src/components'
这是控制台向我显示的内容:
Brewing.jsx:22 Uncaught Error: Cannot find module 'react-player'
at webpackMissingModule (Brewing.jsx:22)
at Module../src/components/Coffees.jsx (Brewing.jsx:22)
at __webpack_require__ (bootstrap:781)
at fn (bootstrap:149)
at Module../src/App.jsx (Spotify.css:4)
at __webpack_require__ (bootstrap:781)
at fn (bootstrap:149)
at Module../src/index.js (spotify-auth.js:8)
at __webpack_require__ (bootstrap:781)
at fn (bootstrap:149)
at Object.0 (index.js:10)
at __webpack_require__ (bootstrap:781)
at checkDeferredModules (bootstrap:45)
at Array.webpackJsonpCallback [as push] (bootstrap:32)
at main.chunk.js:1
docker-compose-dev.yml :
client:
build:
context: ./services/client
dockerfile: Dockerfile-dev
volumes:
- './services/client:/usr/src/app'
- '/usr/src/app/node_modules'
ports:
- 3000:3000
environment:
- NODE_ENV=development
- REACT_APP_WEB_SERVICE_URL=${REACT_APP_WEB_SERVICE_URL}
depends_on:
- web
Dockerfile-dev :
# base image
FROM node:11.12.0-alpine
# set working directory
WORKDIR /usr/src/app
# add `/usr/src/app/node_modules/.bin` to $PATH
ENV PATH /usr/src/app/node_modules/.bin:$PATH
# install and cache app dependencies
COPY package.json /usr/src/app/package.json
COPY package-lock.json /usr/src/app/package-lock.json
RUN npm ci
RUN npm install react-scripts@2.1.8 -g --silent
# start app
CMD ["npm", "start"]
文件夹结构:
services/
docker-compose-dev.yml
node_modules/
client/
Dockerfile-dev
package.json
package-lock.json
node_modules/
react-player/
临时修复:
修复此问题的技巧正在等待一段时间,同时我的代码在 Coffee.jsx 或 Brewing.jsx 中进行了一些强制性更改。
保存更改后的代码后,便找到了该程序包。
然后,当我停止容器并再次抬起它们时,问题又恢复了。我尝试在--build
之后使用标志up -d
,但无济于事。
怎么回事?我该如何解决?
更持久的修补程序:
从docker-compose-dev.yml中删除卷并重建后,如下所示:
#volumes:
#- './services/client:/usr/src/app'
#- '/usr/src/app/node_modules'
我仍然收到错误:
client_1 | > client@0.1.0 start /usr/src/app
client_1 | > react-scripts start
client_1 |
client_1 | Could not find a required file.
client_1 | Name: index.html
client_1 | Searched in: /usr/src/app/public
client_1 | npm ERR! code ELIFECYCLE
client_1 | npm ERR! errno 1
client_1 | npm ERR! client@0.1.0 start: `react-scripts start`
client_1 | npm ERR! Exit status 1
client_1 | npm ERR!
client_1 | npm ERR! Failed at the client@0.1.0 start script.
client_1 | npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
client_1 |
client_1 | npm ERR! A complete log of this run can be found in:
client_1 | npm ERR! /root/.npm/_logs/2019-11-05T15_14_42_967Z-debug.log
然后,仅当我再次取消注释卷并运行带有卷的容器时,它才起作用。解释原因的答案
a)临时修复 b)永久修复
将不胜感激。
答案 0 :(得分:3)
管理node_modules
对于docker来说是一个痛苦。关于如何在docker上运行Javascrip
应用的问题,关于stackoverflow进行了大量讨论。这是我的方法,
Dockerfile
FROM node:11.12.0-alpine
# first installed node_modules in cache and copy them to src folder
RUN mkdir /usr/src/cache
WORKDIR /usr/src/cache
COPY package.json .
RUN npm install -q
# now make a different directory for src code
RUN mkdir /usr/src/app
WORKDIR /usr/src/app
# set path to run packages from node_modules
ENV NODE_PATH=/usr/src/app/node_modules/.bin
COPY . .
docker-compose.yaml
app:
build: .
image: app
container_name: services.app
volumes:
- .:/usr/src/app
ports:
- 3000:5000
# this will copy node_modules to src folder, otherwise node_modules will be wipeed out as we don't
# have the node_modules in the host machine
command: /usr/src/app/entrypoint.sh prod
我的entrypoint.sh
文件看起来像
#!/bin/bash
cp -r /usr/src/cache/node_modules/. /usr/src/app/node_modules/
exec npm start
因此,这里的基本思想是,在构建映像时,将node_modules
存储在路径中的某个位置,但是当您实际运行它时,您复制了node_modules
并将其放置在应用程序中夹。这样,您本地的node_modules
就不会与docker中的本地冲突。
如果您想更快地node_modules
,可以在.dockerignore
中添加COPY
。
答案 1 :(得分:1)
无论何时容器安装好,它也会在启动时停止安装时,我都会去安装软件包。此外,如果可以控制机制,何时安装或何时使用构建时间模块。
#!/bin/sh
npm ci
npm install react-scripts@2.1.8 -g --silent
exec npm start
使用这种方法,容器将始终安装更新的节点模块,并且在开发过程中无需每次都构建。
此外,我们可以控制这种行为。
#!/bin/sh
if [ "$PACKAGE_UPDATE" = true ] ; then
echo 'installing fresh node modules'
# you can also remove existing modules at this step
npm ci
npm install react-scripts@2.1.8 -g --silent
fi
exec npm start
因此将运行不安装软件包的Docker
docker run -e PACKAGE_UPDATE=true -it my_image
,并将装入匿名卷以不与主机节点模块冲突。
volumes:
- './services/client:/usr/src/app'
- '/usr/src/app/node_modules'
答案 2 :(得分:0)
撰写中的卷将在运行时中覆盖您在构建过程中创建的/app
文件夹中的所有数据。我建议您删除卷'./services/client:/usr/src/app'
。另一方面,您为何使用此卷'/usr/src/app/node_modules'
,我看不到有任何理由使用这种卷
答案 3 :(得分:0)
首次服务:
docker-compose -f docker-compose-dev.yml down
然后重建服务(无缓存):
docker-compose -f docker-compose-dev.yml build --no-cache
在上次运行的服务中:
docker-compose -f docker-compose-dev.yml up