J'ai un projet de réaction avec Webpack que j'essaye de l'ancrer en suivant cet article .
Dockerfile:
import React from 'react'; import ReactDOM from 'react-dom'; import { Provider } from 'react-redux'; import store from './redux/store'; import App from './components/App'; import './scss/main.scss'; ReactDOM.render( <Provider store={store}> <App /> </Provider>, document.getElementById('app'), ); module.hot.accept();
docker- compose.yml:
const webpack = require('webpack'); const path = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const { env } = process; module.exports = { entry: './src/index.js', mode: env.NODE_ENV, module: { rules: [ { test: /\.(js|jsx)$/, exclude: /node_modules/, use: ['babel-loader', 'eslint-loader'], }, { test: /\.s[ac]ss$/i, use: [ // Creates `style` nodes from JS strings 'style-loader', // Translates CSS into CommonJS 'css-loader', // Compiles Sass to CSS 'sass-loader', ], }, ], }, resolve: { extensions: ['*', '.js', '.jsx'], }, output: { path: path.join(__dirname, '/build'), publicPath: '/', filename: 'bundle.js', }, plugins: [ new webpack.DefinePlugin({ 'process.env.NODE_ENV': JSON.stringify(env.NODE_ENV) }), new HtmlWebpackPlugin({ template: path.resolve('./src/index.html'), }), ], devServer: { contentBase: './build', hot: true, }, devtool: env.NODE_ENV === 'development' ? 'cheap-module-eval-source-map' : undefined, };
Quand j'exécute docker-compose up
, tout se passe bien jusqu'à ce que je rencontre cette erreur: p >
{ "name": "explore_dashboard", "version": "1.0.0", "description": "A dashboard for the Explore project", "main": "index.js", "type": "module", "scripts": { "start": "cross-env NODE_ENV=development webpack-dev-server --hot", "build": "cross-env NODE_ENV=production webpack", "lint": "eslint ./src", "test": "echo \"Error: no test specified\" && exit 1" }, "repository": { "type": "git", "url": "https://gitlab.basalam.dev/data/explore_dashboard.git" }, "author": "Gh.Sherafati", "license": "ISC", "resolve": { "alias": { "react-dom": "@hot-loader/react-dom" } }, "devDependencies": { "@babel/core": "^7.8.4", "@babel/plugin-transform-runtime": "^7.8.3", "@babel/preset-env": "^7.8.4", "@babel/preset-react": "^7.8.3", "babel-eslint": "^10.0.3", "babel-loader": "^8.0.6", "cross-env": "^7.0.0", "css-loader": "^3.4.2", "eslint": "^6.1.0", "eslint-config-airbnb": "^18.0.1", "eslint-loader": "^3.0.3", "eslint-plugin-import": "^2.20.0", "eslint-plugin-jsx-a11y": "^6.2.3", "eslint-plugin-react": "^7.18.0", "eslint-plugin-react-hooks": "^1.7.0", "html-webpack-plugin": "^3.2.0", "node-sass": "^4.13.1", "sass-loader": "^8.0.2", "style-loader": "^1.1.3", "webpack": "^4.41.5", "webpack-cli": "^3.3.10", "webpack-dev-server": "^3.10.2" }, "dependencies": { "@fortawesome/fontawesome-svg-core": "^1.2.27", "@fortawesome/free-solid-svg-icons": "^5.12.1", "@fortawesome/react-fontawesome": "^0.1.8", "@hot-loader/react-dom": "^16.11.0", "@types/react": "^16.9.19", "axios": "^0.19.2", "react": "^16.12.0", "react-beautiful-dnd": "^12.2.0", "react-dom": "^16.12.0", "react-hot-loader": "^4.12.19", "react-redux": "^7.1.3", "redux": "^4.0.5", "redux-saga": "^1.1.3" } }
L'ensemble du projet fonctionne bien si je l'exécute simplement par npm start
ou si je le construis par npm run build
. Mais je ne sais pas pourquoi cela se produit dans le conteneur du docker.
Voici package.json
:
ex_dashboard_1 | (node:18) ExperimentalWarning: The ESM module loader is experimental. ex_dashboard_1 | file:///usr/app/src/index.js:9 ex_dashboard_1 | <Provider store={store}> ex_dashboard_1 | ^ ex_dashboard_1 | ex_dashboard_1 | SyntaxError: Unexpected token '<' ex_dashboard_1 | at Loader.moduleStrategy (internal/modules/esm/translators.js:66:18) ex_dashboard_1 | at async link (internal/modules/esm/module_job.js:37:21)
Et webpack.config.js :
ex_dashboard: build: . ports: - "80:4000" volumes: - .:/usr/app/:rw environment: - NODE_ENV=dev command: > sh -c ' if test -d node_modules; then echo node_modules_exists ; else cp -a /tmp/node_modules /usr/app/dashboard; fi && npm install && /usr/local/bin/node --experimental-modules ./src/index.js '
Aussi index.js
:
FROM node:12.14.1 RUN npm install webpack -g WORKDIR /tmp COPY package.json /tmp/ RUN npm config set registry http://registry.npmjs.org/ && npm install WORKDIR /usr/app COPY . /usr/app/ RUN cp -a /tmp/node_modules /usr/app/ RUN webpack ENV NODE_ENV=production ENV PORT=4000 CMD [ "/usr/local/bin/node", "--experimental-modules", "./src/index.js" ] EXPOSE 4000
3 Réponses :
L'indicateur --experimental-modules
peut être utilisé pour activer la prise en charge des modules ECMAScript (modules ES).
CMD exec node --experimental-modules index.js
CMD ["sh", "-c", "exec node --experimental-modules index.js"]
J'ai ajouté le drapeau à la fois dans Dockerfile
et docker-compose.yml
, mais cela n'a pas aidé.
Pouvez-vous s'il vous plaît partager le fichier package.json?
Merci, veuillez également mettre à jour l'indicateur dans Dockerfile et docker-compose.yml dans la question.
Veuillez essayer de changer le fichier Docker en: CMD / usr / local / bin / node --experimental-modules ./src/index.js
Dans votre fichier docker-compose.yml
, supprimez les volumes:
et la commande plutôt longue:
.
La chose importante qui se passe ici est que votre fichier index.js
inclut en fait des constructions JSX que React utilise; ce n'est pas du Javascript pur et simple et node
ne peut pas l'exécuter directement. Dans votre Dockerfile
, vous RUN webpack
, qui transpile ceci en Javascript brut. Les volumes :
écrasent tout cela avec le contenu de votre système local; qui n'inclut pas d'étape de transpilation, vous n'avez donc pas de Javascript valide pour Node à exécuter.
(Cela peut fonctionner de placer un appel explicite à webpack
dans cette commande:
. Cela suppose que votre hôte et votre conteneur node_modules
sont compatibles, et il duplique littéralement tout ce que fait le Dockerfile
pour construire l'image dans le fichier docker-compose.yml
.)
Rien ne vous empêche d'installer Node sur votre système hôte (si vous ne l'avez pas déjà), de faire du développement en direct à l'aide du serveur de développement Webpack, puis d'utiliser Docker pour une étape finale d'empaquetage. C’est probablement beaucoup plus pratique que d’introduire un système d’isolation comme Docker, puis d’essayer de contourner toutes ses fonctionnalités pour émuler une configuration de développement locale.
J'ai supprimé volumes:
et la partie commande:
mais l'erreur persiste. J'ai besoin de docker pour m'assurer que le service est toujours en cours d'exécution sur la machine cible. Je ne connais pas d'autre moyen de le faire
Avez-vous également besoin de pointer node
à la sortie de Webpack; Nœud CMD ./dist/index.js
?
Désolé mais je ne suis pas. Je ne suis pas doué pour l'ancrage et je ne suis pas sûr de la meilleure pratique pour exécuter l'application. Dans la machine locale, je l'exécute par npm start
, mais ce n'est pas le cas pour exécuter la production de production ici
Enfin, j'ai résolu le problème en utilisant nginx
et en exécutant la version de compilation dans le conteneur en obtenant de l'aide de cet excellent article .
Les nouveaux Dockerfile
et docker-compose. yml
suit:
Dockerfile:
docker-compose up
docker-compose.yml: strong >
server { listen 80; location / { root /usr/share/nginx/html; index index.html index.htm; try_files $uri $uri/ /index.html; } error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; } }
nginx.conf:
version: "3" services: explore_dashboard: container_name: explore_dashboard build: context: . dockerfile: Dockerfile ports: - "8081:80"
Je suis maintenant en mesure d'exécuter le application sur http://127.0.0.1:8081/
en cours d'exécution:
FROM node:12.14.1 as build WORKDIR /app COPY . /app ENV PATH /app/node_modules/.bin:$PATH RUN npm install RUN npm run build FROM nginx:alpine COPY --from=build /app/build /usr/share/nginx/html COPY nginx.conf /etc/nginx/conf.d EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]
assurez-vous d'utiliser la même version de nœud sur votre docker et votre hôte. Quelle version utilisez-vous pour votre hébergeur?
@Smankusors c'est
12.14.1
et j'ai essayéFROM node: 12.14.1
. Mais ça n'a pas aidé non plus