blob: eb4f06e2955324a9625552aeaeffe10a8bb5fa4f [file] [log] [blame]
San3yuan4d0e8032025-04-04 17:21:40 +08001const { platform } = require('os')
2const path = require('path')
3const rootPath = path.resolve(__dirname, '..')
4const HtmlWebpackPlugin = require("html-webpack-plugin")
5const MiniCssExtractPlugin = require('mini-css-extract-plugin')
6const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
7const webpack = require('webpack');
8const CircularDependencyPlugin = require('circular-dependency-plugin')
San3yuan2534d422025-04-08 21:43:18 +08009const { isNamedExports } = require('typescript')
San3yuan4d0e8032025-04-04 17:21:40 +080010
San3yuan2534d422025-04-08 21:43:18 +080011const isDev = process.env.NODE_ENV === 'development' // 判断是否是开发环境
San3yuan4d0e8032025-04-04 17:21:40 +080012
13module.exports = {
14 entry: path.resolve(__dirname, '../src/index.tsx'),
15 output: {
16 path: path.resolve(__dirname, '../dist'), // 打包后的代码放在dist目录下
17 filename: '[name].[contenthash:8].js', // 打包的文件名
阳菜,放晴!7e1e3a52025-06-05 23:00:51 +080018
19 publicPath: '/',
San3yuan4d0e8032025-04-04 17:21:40 +080020 },
21 resolve: {
22 alias: {
San3yuan6f2ed692025-04-16 20:24:49 +080023 '@': path.resolve(rootPath, 'src'),
24 '&': path.resolve(rootPath)
San3yuan4d0e8032025-04-04 17:21:40 +080025 },
26 // 配置 extensions 来告诉 webpack 在没有书写后缀时,以什么样的顺序去寻找文件
27 extensions: ['.mjs','.js', '.json', '.jsx', '.ts', '.tsx'], // 如果项目中只有 tsx 或 ts 可以将其写在最前面
28 },
29 module: {
30 rules: [
31 {
32 test: /.(jsx?)|(tsx?)$/,
33 exclude: /node_modules/,
34 use: {
35 loader: 'babel-loader',
36 options: {
37 presets: [
38 [
39 '@babel/preset-env',
40 {
41 targets: 'iOS 9, Android 4.4, last 2 versions, > 0.2%, not dead', // 根据项目去配置
42 useBuiltIns: 'usage', // 会根据配置的目标环境找出需要的polyfill进行部分引入
43 corejs: 3, // 使用 core-js@3 版本
44 },
45 ],
46 ['@babel/preset-typescript'],
47 ['@babel/preset-react'],
48 ],
49 },
50 },
51 },
52
53 {
54 test: /\.(png|jpe?g|gif|svg|webp)$/i,
55 type: 'asset',
56 parser: {
57 dataUrlCondition: {
58 maxSize: 25 * 1024, // 25kb
59 },
60 },
61 generator: {
62 filename: 'assets/imgs/[name].[hash:8][ext]',
63 },
64 },
65
66 {
67 test: /\.(eot|ttf|woff|woff2)$/i,
68 type: 'asset',
69 parser: {
70 dataUrlCondition: {
71 maxSize: 25 * 1024, // 25kb
72 },
73 },
74 generator: {
75 filename: 'assets/fonts/[name].[hash:8][ext]',
76 },
San3yuan2534d422025-04-08 21:43:18 +080077 },
78 {
79 test: /\.module\.css$/,
80 use: [
81 isDev ? 'style-loader' : MiniCssExtractPlugin.loader,
82 {
83 loader: 'css-loader',
84 options: {
85 modules: {
86 namedExport: false,
87 localIdentName: isDev
88 ? '[name]__[local]__[hash:base64:5]'
89 : '[hash:base64:8]'
90 },
91 importLoaders: 1
92 },
93 },
94 {
95 loader: 'postcss-loader',
96 options: {
97 postcssOptions: {
98 plugins: ['postcss-preset-env'],
99 },
100 },
101 },
102 ],
103 },
104 {
San3yuan4d0e8032025-04-04 17:21:40 +0800105 test: /\.(css|less)$/,
San3yuan2534d422025-04-08 21:43:18 +0800106 exclude: /\.module\.css$/,
San3yuan4d0e8032025-04-04 17:21:40 +0800107 use: [
San3yuan2534d422025-04-08 21:43:18 +0800108 isDev?'style-loader':MiniCssExtractPlugin.loader, // 使用 MiniCssExtractPlugin.loader 代替 style-loader
San3yuan4d0e8032025-04-04 17:21:40 +0800109 'css-loader',
110 {
111 loader: 'postcss-loader',
112 options: {
113 // 它可以帮助我们将一些现代的 CSS 特性,转成大多数浏览器认识的 CSS,并且会根据目标浏览器或运行时环境添加所需的 polyfill;
114 // 也包括会自动帮助我们添加 autoprefixer
115 postcssOptions: {
116 plugins: [['postcss-preset-env', {}]],
117 },
118 },
119 },
120 'less-loader',
121 ],
San3yuan2534d422025-04-08 21:43:18 +0800122 },
San3yuan4d0e8032025-04-04 17:21:40 +0800123
124 ],
125 },
126 optimization: {
127 minimizer: [
128 // 在 webpack@5 中,你可以使用 `...` 语法来扩展现有的 minimizer(即 `terser-webpack-plugin`),将下一行取消注释
129 `...`,
130 new CssMinimizerPlugin({
131 // 默认开启
132 // parallel true: // 多进程并发执行,提升构建速度 。 运行时默认的并发数:os.cpus().length - 1
133 }),
134 ],
135 },
136
137 plugins:[
138 new HtmlWebpackPlugin({
139 template:path.resolve(__dirname, '../public/index.html')
140 }),
141 new MiniCssExtractPlugin({
San3yuan2534d422025-04-08 21:43:18 +0800142 filename: 'assets/css/[name].[contenthash:8].css',
143 chunkFilename: 'assets/css/[id].[contenthash:8].css',
San3yuan4d0e8032025-04-04 17:21:40 +0800144 }),
145 new CircularDependencyPlugin({
146 exclude: /node_modules/,
147 include: /src/,
阳菜,放晴!7e1e3a52025-06-05 23:00:51 +0800148 failOnError: true,
San3yuan4d0e8032025-04-04 17:21:40 +0800149 allowAsyncCycles: false,
150 cwd: process.cwd(),
阳菜,放晴!7e1e3a52025-06-05 23:00:51 +0800151 }),
152 new webpack.DefinePlugin({
153 'process.env': JSON.stringify({
154 NODE_ENV: process.env.NODE_ENV || 'production',
155 // 这里可以添加其他你需要的环境变量
156 }),
157 // 确保基础变量存在
158 'process.platform': JSON.stringify(platform()),
159 'process.browser': JSON.stringify(true)
San3yuan4d0e8032025-04-04 17:21:40 +0800160 })
161 ]
162}