1
votes

SyntaxError: jeton inattendu '<' lors de l'ancrage de l'application react

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


2 commentaires

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


3 Réponses :


0
votes

L'indicateur --experimental-modules peut être utilisé pour activer la prise en charge des modules ECMAScript (modules ES).

option 1

CMD exec node --experimental-modules index.js

option 2

CMD ["sh", "-c", "exec node --experimental-modules index.js"]

Documents complets:


4 commentaires

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



0
votes

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.


3 commentaires

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



0
votes

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;"]


0 commentaires