const { composePlugins, withNx } = require('@nx/webpack'); const { withReact } = require('@nx/react'); const webpack = require('webpack'); const css_prefix = 'lsf-'; // Nx plugins for webpack. module.exports = composePlugins( withNx({ // Skip TypeScript type checking during build to avoid UI library type errors skipTypeChecking: true, }), withReact({ // Uncomment this line if you don't want to use SVGR // See: https://react-svgr.com/ // svgr: false }), (config) => { // Enable WebAssembly support config.experiments = { ...config.experiments, asyncWebAssembly: true, syncWebAssembly: true, topLevelAwait: true, }; // Add fallbacks for Node.js core modules config.resolve = { ...config.resolve, fallback: { ...config.resolve.fallback, path: false, fs: false, crypto: false, stream: false, buffer: false, util: false, process: false, }, // Provide empty module for problematic audio decoder alias: { ...config.resolve.alias, '@humansignal/audio-file-decoder': require.resolve('./src/utils/empty-module.js'), }, }; // Ignore source map warnings and module not found errors config.ignoreWarnings = [ /Failed to parse source map/, /export .* was not found/, /Can't resolve 'a'/, /decode-audio\.wasm/, /audio-file-decoder/, /Critical dependency: the request of a dependency is an expression/, ]; // Add plugins config.plugins = [ ...config.plugins, // Replace audio decoder with empty module new webpack.NormalModuleReplacementPlugin( /@humansignal\/audio-file-decoder/, require.resolve('./src/utils/empty-module.js') ), // Ignore specific modules that cause issues new webpack.IgnorePlugin({ resourceRegExp: /^\.\/locale$/, contextRegExp: /moment$/, }), // Define CSS_PREFIX for LabelStudio new webpack.DefinePlugin({ 'process.env.CSS_PREFIX': JSON.stringify(css_prefix), }), ]; // Configure CSS modules with lsf- prefix for LabelStudio editor styles config.module.rules.forEach((rule) => { const testString = rule.test?.toString() || ''; const isScss = testString.includes('scss'); const isCssModule = testString.includes('.module'); if (rule.test?.toString().match(/scss|sass/) && !isCssModule) { const r = rule.oneOf?.filter((r) => { // we don't need rules that don't have loaders if (!r.use) return false; const testString = r.test?.toString() || ''; // we also don't need css modules as these are used directly // in the code and don't need prefixing if (testString.match(/module|raw|antd/)) return false; // we only target pre-processors that has 'css-loader included' return testString.match(/scss|sass/) && r.use.some((u) => u.loader && u.loader.includes('css-loader')); }); r?.forEach((_r) => { const cssLoader = _r.use.find((use) => use.loader && use.loader.includes('css-loader')); if (!cssLoader) return; const isSASS = _r.use.some((use) => use.loader && use.loader.match(/sass|scss/)); if (isSASS) _r.exclude = /node_modules/; if (cssLoader.options) { cssLoader.options.modules = { localIdentName: `${css_prefix}[local]`, // Add lsf- prefix getLocalIdent(_ctx, _ident, className) { if (className.includes('ant')) return className; }, }; } }); } }); // Add rule for XML files and WASM config.module = { ...config.module, rules: [ ...config.module.rules, { test: /\.xml$/, type: 'asset/source', }, { test: /\.wasm$/, type: 'webassembly/async', }, ], }; return config; } );