-
webpack.config.js
/* eslint-disable no-console */
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
const fs = require('fs');
const path = require('path');
const webpack = require('webpack');
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
const CopyPlugin = require('copy-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
const SpeedMeasurePlugin = require('speed-measure-webpack-plugin');
const createMdxCompiler = require('@storybook/addon-docs/mdx-compiler-plugin');
const {
WebpackManifestPlugin,
getCompilerHooks,
} = require('webpack-manifest-plugin');
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
const parsedArgs = require('yargs').argv;
const getProxyConfig = require('./webpack.proxy-config');
const packageConfig = require('./package');
// input dir
const APP_DIR = path.resolve(__dirname, './');
// output dir
const BUILD_DIR = path.resolve(__dirname, '../superset/static/assets');
const ROOT_DIR = path.resolve(__dirname, '..');
const {
mode = 'development',
devserverPort = 9000,
measure = false,
analyzeBundle = false,
analyzerPort = 8888,
nameChunks = false,
} = parsedArgs;
const isDevMode = mode !== 'production';
const isDevServer = process.argv[1].includes('webpack-dev-server');
const ASSET_BASE_URL = process.env.ASSET_BASE_URL || '';
const output = {
path: BUILD_DIR,
publicPath: `${ASSET_BASE_URL}/static/assets/`,
};
if (isDevMode) {
output.filename = '[name].[contenthash:8].entry.js';
output.chunkFilename = '[name].[contenthash:8].chunk.js';
} else if (nameChunks) {
output.filename = '[name].[chunkhash].entry.js';
output.chunkFilename = '[name].[chunkhash].chunk.js';
} else {
output.filename = '[name].[chunkhash].entry.js';
output.chunkFilename = '[chunkhash].chunk.js';
}
if (!isDevMode) {
output.clean = true;
}
const plugins = [
new webpack.ProvidePlugin({
process: 'process/browser.js',
}),
// creates a manifest.json mapping of name to hashed output used in template files
new WebpackManifestPlugin({
publicPath: output.publicPath,
seed: { app: 'superset' },
// This enables us to include all relevant files for an entry
generate: (seed, files, entrypoints) => {
// Each entrypoint's chunk files in the format of
// {
// entry: {
// css: [],
// js: []
// }
// }
const entryFiles = {};
Object.entries(entrypoints).forEach(([entry, chunks]) => {
entryFiles[entry] = {
css: chunks
.filter(x => x.endsWith('.css'))
.map(x => `${output.publicPath}${x}`),
js: chunks
.filter(x => x.endsWith('.js'))
.map(x => `${output.publicPath}${x}`),
};
});
return {
...seed,
entrypoints: entryFiles,
};
},
// Also write manifest.json to disk when running `npm run dev`.
// This is required for Flask to work.
writeToFileEmit: isDevMode && !isDevServer,
}),
// expose mode variable to other modules
new webpack.DefinePlugin({
'process.env.WEBPACK_MODE': JSON.stringify(mode),
'process.env.REDUX_DEFAULT_MIDDLEWARE':
process.env.REDUX_DEFAULT_MIDDLEWARE,
}),
new CopyPlugin({
patterns: [
'package.json',
{ from: 'src/assets/images', to: 'i