@zerows/web-zone
Version:
Zero UI ( Zone )
324 lines (314 loc) • 14 kB
JavaScript
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',
})
]
};
}