Возникла проблема с нашей текущей сборкой webpack.Первоначальный запуск webpack-dev-server работает нормально, а сборка webpack работает.При горячей перезагрузке мы получаем сообщение об ошибке:
Module build failed (from ./node_modules/babel-loader/lib/index.js):
SyntaxError: /component-lib/HOCFields.js: Unterminated regular expression
282 | onChange={this.onChange}
283 | value={this.state.inputValue}
> 284 | {...omit(this.props, ['value','onFocus','onBlur','onChange'])} />
| ^
285 | }
286 | }
287 | };
at raise (/node_modules/@babel/parser/lib/index.js:6344:17)
at readRegexp (/node_modules/@babel/parser/lib/index.js:7053:14)
at readToken_slash (/node_modules/@babel/parser/lib/index.js:6697:12)
at getTokenFromCode (/node_modules/@babel/parser/lib/index.js:6975:14)
at getTokenFromCode (/node_modules/@babel/parser/lib/index.js:3631:18)
at nextToken (/node_modules/@babel/parser/lib/index.js:6542:12)
at next (/node_modules/@babel/parser/lib/index.js:6482:10)
at eat (/node_modules/@babel/parser/lib/index.js:6487:12)
at expect (/node_modules/@babel/parser/lib/index.js:7645:10)
at jsxParseAttribute (/node_modules/@babel/parser/lib/index.js:3463:12)
Дело в том, что он указывает на код, который был перенесен просто прекрасными моментами ранее!Перезапуск сервера dev устраняет ошибку, и мы можем вернуться к разработке.Досадно, что очень трудно воспроизвести надежно, поскольку это не всегда происходит.Таким образом, это временная проблема, которая исчезает при перезапуске сервера.Это действительно замедляет нас, так как требуется 30 - 40 секунд для перезапуска сервера каждый раз, когда появляется ошибка.Не конец света, но накапливается.Не уверен, что это проблема конфигурации webpack или babel config на данный момент, так как это babel-loader, выдающий ошибку, но большая часть инфраструктуры webpack проходит через это, прежде чем туда попасть.
Вот наш конфиг:
webpack.common.config.js:
const webpack = require('webpack');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const path = require('path');
const SRC = path.join(__dirname, '/src');
let polyfills = ['es5-shim/es5-shim',
'es5-shim/es5-sham',
'@babel/polyfill',
'whatwg-fetch'];
module.exports = {
entry: {
app_one: [
path.resolve(SRC, './AppOne/AppOne.js'),
],
app_two: [
...polyfills,
path.resolve(SRC, './AppTwo/AppTwo.js)
]
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /.*node_modules((?!atvenu).)*$/,
use: {
loader: 'babel-loader',
// NOTE: will load presets from babel.config.js
options: {
cacheDirectory: true
}
}
},
{
test: /\.(gif|pdf|csv|jpe?g|png|svg|eot|ttf|woff)(\?[a-z0-9=&.-]+)?$/,
use: {
loader: 'url-loader',
query: {name: '[name].[hash:16].[ext]'}
}
},
{
test: /\.css$/,
use: [
{
loader: "style-loader" // creates style nodes from JS strings
},
{
loader: "css-loader" // translates CSS into CommonJS
}
]
},
{ test: /\.scss$/, loader: 'style!css!sass' },
{
test: /\.graphql?$/,
use: [
{
loader: 'webpack-graphql-loader',
options: {
minify: true
}
}
]
}
]
},
plugins: [
new CleanWebpackPlugin(['build']),
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'development'),
webpack_environment: {
SERVER1: 'http://localhost:5004',
SERVER2: 'http://localhost:5005'
}
}),
// Ignore all locale files of moment.js
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
],
optimization: {
//split out common components into two common libraries: common.js and av-c-lib.js
splitChunks: {
cacheGroups: {
clib: {
test: /component-lib/,
name: 'c-lib',
chunks: 'all',
priority: 10
},
commons: {
test: /[\\/]node_modules[\\/]/,
name: 'common',
priority: -20,
chunks: 'all'
}
}
}
},
output: {
filename: '[name].js',
path: path.join(__dirname, './build')
},
resolve: {
extensions: ['.js', '.jsx'],
modules: [path.resolve(__dirname, 'node_modules'),'node_modules'], // require to resolve modules in the atvenu-* libs
alias: {
'react-native': 'react-native-web',
}
},
};
webpack.dev.config.js
const merge = require('webpack-merge');
const common = require('./webpack.config.common.js');
const os = require('os');
const myPort = 3004;
const plugins = [];
if (process.env.SKIP_DASHBOARD) {
console.log('Skipping Webpack Dashboard')
} else {
const DashboardPlugin = require('webpack-dashboard/plugin');
const Dashboard = require('webpack-dashboard');
const dashboard = new Dashboard();
plugins.push(
new DashboardPlugin({
port: myPort,
handler: dashboard.setData
})
)
}
module.exports = merge(common, {
mode: 'development',
devtool: 'cheap-module-source-map',
devServer: {
contentBase: '../build',
public: `0.0.0.0:${myPort}`,
compress: true,
watchContentBase: true,
inline: true,
quiet: true, // important
overlay: true,
port: myPort,
host: '0.0.0.0',
disableHostCheck: true
},
plugins: plugins});
babel.config.js:
module.exports = function (api) {
api.cache(false);
const presets = ["@babel/preset-env", "@babel/preset-react"];
const plugins = ["@babel/plugin-proposal-class-properties"];
return {
presets,
plugins
};
}
Структура файла выглядит следующим образом:
myMonoRepo
├── RootApp/
│ │ babel.config.js
│ │ webpack.common.config.js
│ │ webpack.dev.config.js
│ │ package.json /* contains component-lib: link:../component-lib reference via symlink */
│ └── AppOne/
│ │ └── AppOne.js
│ └── AppTwo/
│ └── AppTwo.js
├── component-lib/
│ └── package.json
Мы запускаем webpack-dev-server через: webpack-dev-server --config ./webpack.config.dev.js
, чтобы запустить сервер разработки.
Примечание. Мы используем локальную общую папку компонентов, которые устанавливаем в виде символического модуля node_moled.Это часто, где проблема начинается, но не всегда.Не уверен, что реальная проблема - символическая ссылка или просто красная сельдь.