Я получаю следующую ошибку при попытке загрузить компонент реагирования, который включает импорт mapbox.
SyntaxError: /home/superset/superset/assets/src/visualizations/AlarmMap/index.js: Support for the experimental syntax 'dynamicImport' isn't currently enabled (35:24):
Это приложение, на котором я основал эту конфигурацию:
https://github.com/apache-superset/superset-ui-plugins/tree/master/packages/superset-ui-legacy-plugin-chart-map-box
Я в основном переместил его в локальное приложение вместо того, чтобы импортировать его из другого, и, несмотря на то, что внутри него все еще есть package.json, я думаю, что он подчиняется тем же конфигурациям webpack и bablel.
МОЕ ПОДДЕРЖКА:
Я полагаю, что это связано со следующей конкретной конфигурацией Webpack, поскольку она даже помечена как особый случай, но я не знаю, как перезаписатьили игнорируйте его.
context: APP_DIR, // to automatically find tsconfig.json
module: {
// Uglifying mapbox-gl results in undefined errors, see
// https://github.com/mapbox/mapbox-gl-js/issues/4359#issuecomment-288001933
noParse: /(mapbox-gl)\.js$/,
rules: [
{
test: /datatables\.net.*/,
loader: 'imports-loader?define=>false',
},
Вот конфигурация babel:
{
"presets" : ["airbnb", "@babel/preset-react", "@babel/preset-env"],
"plugins": ["lodash", "@babel/plugin-syntax-dynamic-import", "react-hot-loader/babel"],
"env": {
"test": {
"plugins": [
"babel-plugin-dynamic-import-node"
]
}
}
}
и вот конфигурация WebPack:
const config = {
node: {
fs: 'empty',
},
entry: {
theme: path.join(APP_DIR, '/src/theme.js'),
preamble: PREAMBLE,
addSlice: addPreamble('/src/addSlice/index.jsx'),
explore: addPreamble('/src/explore/index.jsx'),
dashboard: addPreamble('/src/dashboard/index.jsx'),
sqllab: addPreamble('/src/SqlLab/index.jsx'),
welcome: addPreamble('/src/welcome/index.jsx'),
profile: addPreamble('/src/profile/index.jsx'),
showSavedQuery: [path.join(APP_DIR, '/src/showSavedQuery/index.jsx')],
},
output,
optimization: {
splitChunks: {
chunks: 'all',
automaticNameDelimiter: '-',
minChunks: 2,
cacheGroups: {
default: false,
major: {
name: 'vendors-major',
test: /[\\/]node_modules\/(brace|react[-]dom|@superset[-]ui\/translation)[\\/]/,
},
},
},
},
resolve: {
alias: {
src: path.resolve(APP_DIR, './src'),
},
extensions: ['.ts', '.tsx', '.js', '.jsx'],
symlinks: false,
},
context: APP_DIR, // to automatically find tsconfig.json
module: {
// Uglifying mapbox-gl results in undefined errors, see
// https://github.com/mapbox/mapbox-gl-js/issues/4359#issuecomment-288001933
noParse: /(mapbox-gl)\.js$/,
rules: [
{
test: /datatables\.net.*/,
loader: 'imports-loader?define=>false',
},
{
test: /\.tsx?$/,
use: [
{ loader: 'cache-loader' },
{
loader: 'thread-loader',
options: {
// there should be 1 cpu for the fork-ts-checker-webpack-plugin
workers: os.cpus().length - 1,
},
},
{
loader: 'ts-loader',
options: {
// transpile only in happyPack mode
// type checking is done via fork-ts-checker-webpack-plugin
happyPackMode: true,
},
},
],
},
{
test: /\.jsx?$/,
exclude: /node_modules/,
include: APP_DIR,
loader: 'babel-loader',
},
{
// handle symlinked modules
// for debugging @superset-ui packages via npm link
test: /\.jsx?$/,
include: /node_modules\/[@]superset[-]ui.+\/src/,
use: [
{
loader: 'babel-loader',
options: {
presets: ['airbnb', '@babel/preset-react', '@babel/preset-env'],
plugins: ['lodash', '@babel/plugin-syntax-dynamic-import', 'react-hot-loader/babel'],
},
},
],
},
{
test: /\.css$/,
include: [
APP_DIR,
/superset[-]ui.+\/src/,
],
use: [
isDevMode ? 'style-loader' : MiniCssExtractPlugin.loader,
'css-loader',
],
},
{
test: /\.less$/,
include: APP_DIR,
use: [
isDevMode ? 'style-loader' : MiniCssExtractPlugin.loader,
'css-loader',
'less-loader',
],
},
/* for css linking images */
{
test: /\.png$/,
loader: 'url-loader',
options: {
limit: 10000,
name: '[name].[hash:8].[ext]',
},
},
{
test: /\.(jpg|gif)$/,
loader: 'file-loader',
options: {
name: '[name].[hash:8].[ext]',
},
},
/* for font-awesome */
{
test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
loader: 'url-loader?limit=10000&mimetype=application/font-woff',
},
{
test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
loader: 'file-loader',
},
],
},
externals: {
cheerio: 'window',
'react/lib/ExecutionEnvironment': true,
'react/lib/ReactContext': true,
},
plugins,
devtool: isDevMode ? 'cheap-module-eval-source-map' : false,
devServer: {
historyApiFallback: true,
hot: true,
index: '', // This line is needed to enable root proxying
inline: true,
stats: { colors: true },
overlay: true,
port: devserverPort,
// Only serves bundled files from webpack-dev-server
// and proxy everything else to Superset backend
proxy: {
context: () => true,
'/': `http://localhost:${supersetPort}`,
target: `http://localhost:${supersetPort}`,
},
contentBase: path.join(process.cwd(), '../static/assets/dist'),
},
};
if (!isDevMode) {
config.optimization.minimizer = [
new TerserPlugin({
cache: '.terser-plugin-cache/',
parallel: true,
extractComments: true,
}),
];
}
И, наконец, вот содержимоеимпортируемый файл:
const NOOP = () => {};
export const DEFAULT_MAX_ZOOM = 16;
export const DEFAULT_POINT_RADIUS = 60;
const propTypes = {
width: PropTypes.number,
height: PropTypes.number,
aggregatorName: PropTypes.string,
clusterer: PropTypes.object,
globalOpacity: PropTypes.number,
hasCustomMetric: PropTypes.bool,
mapStyle: PropTypes.string,
mapboxApiKey: PropTypes.string.isRequired,
onViewportChange: PropTypes.func,
pointRadius: PropTypes.number,
pointRadiusUnit: PropTypes.string,
renderWhileDragging: PropTypes.bool,
rgb: PropTypes.array,
bounds: PropTypes.array,
};
const defaultProps = {
width: 400,
height: 400,
globalOpacity: 1,
onViewportChange: NOOP,
pointRadius: DEFAULT_POINT_RADIUS,
pointRadiusUnit: 'Pixels',
};
class MapBox extends React.Component {
constructor(props) {
super(props);
const { width, height, bounds } = this.props;
// Get a viewport that fits the given bounds, which all marks to be clustered.
// Derive lat, lon and zoom from this viewport. This is only done on initial
// render as the bounds don't update as we pan/zoom in the current design.
const mercator = new ViewportMercator({
width,
height,
}).fitBounds(bounds);
const { latitude, longitude, zoom } = mercator;
this.state = {
viewport: {
longitude,
latitude,
zoom,
},
};
this.handleViewportChange = this.handleViewportChange.bind(this);
}
handleViewportChange(viewport) {
this.setState({ viewport });
const { onViewportChange } = this.props;
onViewportChange(viewport);
}
render() {
const {
width,
height,
aggregatorName,
clusterer,
globalOpacity,
mapStyle,
mapboxApiKey,
pointRadius,
pointRadiusUnit,
renderWhileDragging,
rgb,
hasCustomMetric,
bounds,
} = this.props;
const { viewport } = this.state;
const isDragging = viewport.isDragging === undefined ? false : viewport.isDragging;
// Compute the clusters based on the original bounds and current zoom level. Note when zoom/pan
// to an area outside of the original bounds, no additional queries are made to the backend to
// retrieve additional data.
const bbox = [bounds[0][0], bounds[0][1], bounds[1][0], bounds[1][1]];
const clusters = clusterer.getClusters(bbox, Math.round(viewport.zoom));
return (
<MapGL
{...viewport}
mapStyle={mapStyle}
width={width}
height={height}
mapboxApiAccessToken={mapboxApiKey}
onViewportChange={this.handleViewportChange}
>
<ScatterPlotGlowOverlay
{...viewport}
isDragging={isDragging}
locations={Immutable.fromJS(clusters)}
dotRadius={pointRadius}
pointRadiusUnit={pointRadiusUnit}
rgb={rgb}
globalOpacity={globalOpacity}
compositeOperation="screen"
renderWhileDragging={renderWhileDragging}
aggregation={hasCustomMetric ? aggregatorName : null}
lngLatAccessor={location => {
const coordinates = location.get('geometry').get('coordinates');
return [coordinates.get(0), coordinates.get(1)];
}}
/>
</MapGL>
);
}
}
MapBox.propTypes = propTypes;
MapBox.defaultProps = defaultProps;
export default MapBox;
И, наконец, вот ссылка github на ветку с неисправным приложением:
Файлы конфигурации: https://github.com/paula-everis/incubator-superset/tree/faultymap/superset/assets
Файлы приложения:
https://github.com/paula-everis/incubator-superset/tree/faultymap/superset/assets/src/visualizations/AlarmMap
Большое спасибо заранее:)