У меня есть реактивный проект с Webpack, который я пытаюсь докеризировать, следуя этой статье .
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
'
Когда я запускаю docker-compose up
, все идет хорошо, пока не возникнет эта ошибка:
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)
Весь проект работает хорошо, если я просто запустил его npm start
или собрал npm run build
. Но я не знаю, почему это происходит в docker контейнере.
Вот 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"
}
}
И 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,
};
Также 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();