mirror of
https://github.com/apache/superset.git
synced 2026-04-07 18:35:15 +00:00
231 lines
8.9 KiB
TypeScript
231 lines
8.9 KiB
TypeScript
/**
|
|
* 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.
|
|
*/
|
|
|
|
import path from 'path';
|
|
import webpack from 'webpack';
|
|
import type { Plugin } from '@docusaurus/types';
|
|
|
|
export default function webpackExtendPlugin(): Plugin<void> {
|
|
return {
|
|
name: 'custom-webpack-plugin',
|
|
configureWebpack(config) {
|
|
const isDev = process.env.NODE_ENV === 'development';
|
|
|
|
// Use NormalModuleReplacementPlugin to forcefully replace react-table
|
|
// This is necessary because regular aliases don't work for modules in nested node_modules
|
|
const reactTableShim = path.resolve(__dirname, './shims/react-table.js');
|
|
config.plugins?.push(
|
|
new webpack.NormalModuleReplacementPlugin(
|
|
/^react-table$/,
|
|
reactTableShim,
|
|
),
|
|
);
|
|
|
|
// Stub out heavy third-party packages that are transitive dependencies of
|
|
// superset-frontend components. The barrel file (components/index.ts)
|
|
// re-exports all components, so webpack must resolve their imports even
|
|
// though these components are never rendered on the docs site.
|
|
const nullModuleShim = path.resolve(__dirname, './shims/null-module.js');
|
|
const heavyDepsPatterns = [
|
|
/^brace(\/|$)/, // ACE editor modes/themes
|
|
/^react-ace(\/|$)/,
|
|
/^ace-builds(\/|$)/,
|
|
/^react-js-cron(\/|$)/, // Cron picker + CSS
|
|
// react-resize-detector: NOT shimmed — DropdownContainer needs it at runtime
|
|
// for overflow detection. Resolves from superset-frontend/node_modules.
|
|
/^react-window(\/|$)/,
|
|
/^re-resizable(\/|$)/,
|
|
/^react-draggable(\/|$)/,
|
|
/^ag-grid-react(\/|$)/,
|
|
/^ag-grid-community(\/|$)/,
|
|
];
|
|
heavyDepsPatterns.forEach(pattern => {
|
|
config.plugins?.push(
|
|
new webpack.NormalModuleReplacementPlugin(pattern, nullModuleShim),
|
|
);
|
|
});
|
|
|
|
// Add YAML loader rule directly to existing rules
|
|
config.module?.rules?.push({
|
|
test: /\.ya?ml$/,
|
|
use: 'js-yaml-loader',
|
|
});
|
|
|
|
// Add swc-loader rule for superset-frontend files
|
|
// SWC is a Rust-based transpiler that's significantly faster than babel
|
|
const supersetFrontendPath = path.resolve(
|
|
__dirname,
|
|
'../../superset-frontend',
|
|
);
|
|
config.module?.rules?.push({
|
|
test: /\.(tsx?|jsx?)$/,
|
|
include: supersetFrontendPath,
|
|
exclude: /node_modules/,
|
|
use: {
|
|
loader: 'swc-loader',
|
|
options: {
|
|
// Ignore superset-frontend/.swcrc which references plugins not
|
|
// installed in the docs workspace (e.g. @swc/plugin-emotion)
|
|
swcrc: false,
|
|
jsc: {
|
|
parser: {
|
|
syntax: 'typescript',
|
|
tsx: true,
|
|
},
|
|
transform: {
|
|
react: {
|
|
runtime: 'automatic',
|
|
importSource: '@emotion/react',
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
});
|
|
|
|
return {
|
|
devtool: isDev ? false : config.devtool,
|
|
cache: {
|
|
type: 'filesystem' as const,
|
|
buildDependencies: {
|
|
config: [__filename],
|
|
},
|
|
},
|
|
...(isDev && {
|
|
optimization: {
|
|
...config.optimization,
|
|
minimize: false,
|
|
removeAvailableModules: false,
|
|
removeEmptyChunks: false,
|
|
splitChunks: false,
|
|
},
|
|
}),
|
|
resolve: {
|
|
// Add superset-frontend node_modules to module resolution
|
|
modules: [
|
|
...(config.resolve?.modules || []),
|
|
path.resolve(__dirname, '../../superset-frontend/node_modules'),
|
|
],
|
|
alias: {
|
|
...config.resolve.alias,
|
|
// Ensure single React instance across all modules (critical for hooks to work)
|
|
react: path.resolve(__dirname, '../node_modules/react'),
|
|
'react-dom': path.resolve(__dirname, '../node_modules/react-dom'),
|
|
// Allow importing from superset-frontend
|
|
src: path.resolve(__dirname, '../../superset-frontend/src'),
|
|
// Lightweight shim for @superset-ui/core that re-exports only the
|
|
// utilities needed by components (ensureIsArray, usePrevious, etc.).
|
|
// Avoids pulling in the full barrel which includes d3, color, query
|
|
// modules and causes OOM. Required for Rspack which is stricter about
|
|
// module resolution than webpack.
|
|
'@superset-ui/core$': path.resolve(
|
|
__dirname,
|
|
'./shims/superset-ui-core.ts',
|
|
),
|
|
// Add aliases for our components to make imports easier
|
|
'@docs/components': path.resolve(__dirname, '../src/components'),
|
|
'@superset/components': path.resolve(
|
|
__dirname,
|
|
'../../superset-frontend/packages/superset-ui-core/src/components',
|
|
),
|
|
// Also alias the full package path for internal imports within components
|
|
'@superset-ui/core/components': path.resolve(
|
|
__dirname,
|
|
'../../superset-frontend/packages/superset-ui-core/src/components',
|
|
),
|
|
// Use a shim for react-table to handle CommonJS to ES module interop
|
|
// react-table v7 is CommonJS, but Superset components import it with ES module syntax
|
|
'react-table': path.resolve(__dirname, './shims/react-table.js'),
|
|
// Extension API package - resolve @apache-superset/core and its sub-paths
|
|
// to source so the docs build doesn't depend on pre-built lib/ artifacts.
|
|
// More specific sub-path aliases must come first; webpack matches the
|
|
// longest prefix.
|
|
'@apache-superset/core/components': path.resolve(
|
|
__dirname,
|
|
'../../superset-frontend/packages/superset-core/src/components',
|
|
),
|
|
'@apache-superset/core/api/core': path.resolve(
|
|
__dirname,
|
|
'../../superset-frontend/packages/superset-core/src/api/core',
|
|
),
|
|
'@apache-superset/core': path.resolve(
|
|
__dirname,
|
|
'../../superset-frontend/packages/superset-core/src',
|
|
),
|
|
// Add proper Storybook aliases
|
|
'@storybook/blocks': path.resolve(
|
|
__dirname,
|
|
'../node_modules/@storybook/blocks',
|
|
),
|
|
'@storybook/components': path.resolve(
|
|
__dirname,
|
|
'../node_modules/@storybook/components',
|
|
),
|
|
'@storybook/theming': path.resolve(
|
|
__dirname,
|
|
'../node_modules/@storybook/theming',
|
|
),
|
|
'@storybook/client-logger': path.resolve(
|
|
__dirname,
|
|
'../node_modules/@storybook/client-logger',
|
|
),
|
|
'@storybook/core-events': path.resolve(
|
|
__dirname,
|
|
'../node_modules/@storybook/core-events',
|
|
),
|
|
// Add internal Storybook aliases
|
|
'storybook/internal/components': path.resolve(
|
|
__dirname,
|
|
'../node_modules/@storybook/components',
|
|
),
|
|
'storybook/internal/theming': path.resolve(
|
|
__dirname,
|
|
'../node_modules/@storybook/theming',
|
|
),
|
|
'storybook/internal/client-logger': path.resolve(
|
|
__dirname,
|
|
'../node_modules/@storybook/client-logger',
|
|
),
|
|
'storybook/internal/csf': path.resolve(
|
|
__dirname,
|
|
'../node_modules/@storybook/csf',
|
|
),
|
|
'storybook/internal/preview-api': path.resolve(
|
|
__dirname,
|
|
'../node_modules/@storybook/preview-api',
|
|
),
|
|
'storybook/internal/docs-tools': path.resolve(
|
|
__dirname,
|
|
'../node_modules/@storybook/docs-tools',
|
|
),
|
|
'storybook/internal/core-events': path.resolve(
|
|
__dirname,
|
|
'../node_modules/@storybook/core-events',
|
|
),
|
|
'storybook/internal/channels': path.resolve(
|
|
__dirname,
|
|
'../node_modules/@storybook/channels',
|
|
),
|
|
},
|
|
},
|
|
};
|
|
},
|
|
};
|
|
}
|