UNPKG

@zerows/web-zone

Version:
324 lines (314 loc) 14 kB
const path = require('path'); const chalk = require("chalk"); const TerserPlugin = require('terser-webpack-plugin'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const CssMinimizerPlugin = require('css-minimizer-webpack-plugin'); const ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin'); const paths = require('./webpack.paths'); const modules = require('./webpack.modules'); const getStyleLoaders = require("./webpack.config.style"); const getCSSModuleLocalIdent = require('react-dev-utils/getCSSModuleLocalIdent'); const BundleAnalyzerPlugin = require('webpack-bundle-analyzer')['BundleAnalyzerPlugin']; const ProgressBarPlugin = require('progress-bar-webpack-plugin'); const reactRefreshRuntimeEntry = require.resolve('react-refresh/runtime'); const reactRefreshWebpackPluginRuntimeEntry = require.resolve( '@pmmmwh/react-refresh-webpack-plugin' ); const babelRuntimeEntry = require.resolve('babel-preset-react-app'); const babelRuntimeEntryHelpers = require.resolve( '@babel/runtime/helpers/esm/assertThisInitialized', {paths: [babelRuntimeEntry]} ); const babelRuntimeRegenerator = require.resolve('@babel/runtime/regenerator', { paths: [babelRuntimeEntry], }); const cssRegex = /\.css$/; const cssModuleRegex = /\.module\.css$/; const sassRegex = /\.(scss|sass)$/; const sassModuleRegex = /\.module\.(scss|sass)$/; process.env.NODE_ENV = 'production'; module.exports = (webpackEnv) => { const isEnvProductionProfile = process.argv.includes('--profile'); const shouldUseSourceMap = process.env.GENERATE_SOURCEMAP !== 'false'; const imageInlineSizeLimit = parseInt( process.env.IMAGE_INLINE_SIZE_LIMIT || '10000' ); const hasJsxRuntime = (() => { if (process.env.DISABLE_NEW_JSX_TRANSFORM === 'true') { return false; } try { require.resolve('react/jsx-runtime'); return true; } catch (e) { return false; } })(); return { entry: path.resolve(__dirname, "../src/index.js"), output: { path: path.resolve(__dirname, '../dist'), filename: 'index.js', library: '@zerows/web-zone', // 将你的库命名为 YourLibraryName libraryTarget: 'umd', umdNamedDefine: true, }, mode: "production", optimization: { minimize: true, minimizer: [ new TerserPlugin({ terserOptions: { parse: { ecma: 8, }, compress: { ecma: 5, warnings: false, comparisons: false, inline: 2, }, mangle: { safari10: true, }, keep_classnames: isEnvProductionProfile, keep_fnames: isEnvProductionProfile, output: { ecma: 5, comments: false, ascii_only: true, }, }, }), new CssMinimizerPlugin(), ], }, resolve: { fallback: { crypto: require.resolve('crypto-browserify'), buffer: require.resolve("buffer/"), stream: require.resolve('stream-browserify/'), util: require.resolve('util/'), fs: false, }, modules: ['node_modules', paths.appNodeModules].concat( modules.additionalModulePaths || [] ), extensions: paths.moduleFileExtensions .map(ext => `.${ext}`), alias: { 'react-native': 'react-native-web', ...(isEnvProductionProfile && { 'react-dom$': 'react-dom/profiling', 'scheduler/tracing': 'scheduler/tracing-profiling', }), ...(modules.webpackAliases || {}), }, plugins: [ new ModuleScopePlugin(paths.appSrc, [ paths.appPackageJson, paths.appFix, reactRefreshRuntimeEntry, reactRefreshWebpackPluginRuntimeEntry, babelRuntimeEntry, babelRuntimeEntryHelpers, babelRuntimeRegenerator, ]), ] }, module: { strictExportPresence: true, rules: [ shouldUseSourceMap && { enforce: 'pre', exclude: /(@babel(?:\/|\\{1,2})runtime)|ant-design-pro|@antv|dagre-compound|mutationobserver-shim/, test: /\.(js|mjs|jsx|ts|tsx|css)$/, use: [ require.resolve('source-map-loader') ].filter(Boolean) }, { oneOf: [ { test: [/\.avif$/], type: 'asset', mimetype: 'image/avif', parser: { dataUrlCondition: { maxSize: imageInlineSizeLimit, }, }, }, { test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/], type: 'asset', parser: { dataUrlCondition: { maxSize: imageInlineSizeLimit, }, }, }, { test: /\.svg$/, use: [ { loader: require.resolve('@svgr/webpack'), options: { prettier: false, svgo: false, svgoConfig: { plugins: [{removeViewBox: false}], }, titleProp: true, ref: true, }, }, { loader: require.resolve('file-loader'), options: { name: 'static/media/[name].[hash].[ext]', }, }, ].filter(Boolean), issuer: { and: [/\.(ts|tsx|js|jsx|md|mdx)$/], }, }, { test: /\.(js|mjs|jsx|ts|tsx)$/, include: paths.appSrc, use: [ { loader: require.resolve('babel-loader'), options: { customize: require.resolve( 'babel-preset-react-app/webpack-overrides' ), presets: [ [ require.resolve('babel-preset-react-app'), { runtime: hasJsxRuntime ? 'automatic' : 'classic', }, ], ], plugins: [ [ require.resolve('babel-plugin-named-asset-import'), { loaderMap: { svg: { ReactComponent: '@svgr/webpack?-svgo,+titleProp,+ref![path]', }, }, }, ], ].filter(Boolean), cacheDirectory: true, cacheCompression: false, compact: true, }, } ].filter(Boolean), }, { test: /\.(js|mjs)$/, exclude: /@babel(?:\/|\\{1,2})runtime/, use: [ { loader: require.resolve('babel-loader'), options: { babelrc: false, configFile: false, compact: false, presets: [ [ require.resolve('babel-preset-react-app/dependencies'), {helpers: true}, ], ], cacheDirectory: true, cacheCompression: false, sourceMaps: shouldUseSourceMap, inputSourceMap: shouldUseSourceMap, }, } ].filter(Boolean), }, { test: cssRegex, exclude: cssModuleRegex, use: getStyleLoaders(webpackEnv, { importLoaders: 1, sourceMap: shouldUseSourceMap, modules: { mode: 'icss', }, }), sideEffects: true, }, { test: cssModuleRegex, use: getStyleLoaders(webpackEnv, { importLoaders: 1, sourceMap: shouldUseSourceMap, modules: { mode: 'local', getLocalIdent: getCSSModuleLocalIdent, }, }), }, { test: sassRegex, exclude: sassModuleRegex, use: getStyleLoaders( webpackEnv, { importLoaders: 3, sourceMap: shouldUseSourceMap, modules: { mode: 'icss', }, }, 'sass-loader' ), sideEffects: true, }, { test: sassModuleRegex, use: getStyleLoaders( webpackEnv, { importLoaders: 3, sourceMap: shouldUseSourceMap, modules: { mode: 'local', getLocalIdent: getCSSModuleLocalIdent, }, }, 'sass-loader' ), }, { exclude: [/^$/, /\.(js|mjs|jsx|ts|tsx)$/, /\.html$/, /\.json$/], type: 'asset/resource', }, ], }, ].filter(Boolean), }, plugins: [ new ProgressBarPlugin({ format: `:msg [:bar] ${chalk.green.bold(':percent')} (:elapsed s)` }), new BundleAnalyzerPlugin(), new MiniCssExtractPlugin({ // Options similar to the same options in webpackOptions.output // both options are optional filename: 'static/css/[name].[contenthash:8].css', chunkFilename: 'static/css/[name].[contenthash:8].chunk.css', }) ] }; }