SyntaxError: Unexpected token '<' when dockerizing react app
Answer a question I have a react project with Webpack which I'm trying to dockerize it following this article. Dockerfile: FROM node:12.14.1 RUN npm install webpack -g WORKDIR /tmp COPY package.json /
Answer a question
I have a react project with Webpack which I'm trying to dockerize it following this article.
Dockerfile:
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
docker-compose.yml:
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
'
When I run docker-compose up
, everything goes well until I encounter this error:
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)
The whole project works well if I just run it by npm start
or build it by npm run build
. But I don't know why this happens in docker container.
Here is package.json
:
{
"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"
}
}
And webpack.config.js
:
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,
};
Also index.js
:
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();
Answers
Finally I've solve the issue by using nginx
and running the build version in the container getting help from this great article.
The new Dockerfile
and docker-compose.yml
follows:
Dockerfile:
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;"]
docker-compose.yml:
version: "3"
services:
explore_dashboard:
container_name: explore_dashboard
build:
context: .
dockerfile:
Dockerfile
ports:
- "8081:80"
nginx.conf:
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;
}
}
Now I'm able to run the app on http://127.0.0.1:8081/
running:
docker-compose up
更多推荐
所有评论(0)