blob: aeb4b79d64b89d501f78e4f57787372148a7d76b [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', // 打包的文件名
18 },
19 resolve: {
20 alias: {
21 '@': path.resolve(rootPath, 'src')
22 },
23 // 配置 extensions 来告诉 webpack 在没有书写后缀时,以什么样的顺序去寻找文件
24 extensions: ['.mjs','.js', '.json', '.jsx', '.ts', '.tsx'], // 如果项目中只有 tsx 或 ts 可以将其写在最前面
25 },
26 module: {
27 rules: [
28 {
29 test: /.(jsx?)|(tsx?)$/,
30 exclude: /node_modules/,
31 use: {
32 loader: 'babel-loader',
33 options: {
34 presets: [
35 [
36 '@babel/preset-env',
37 {
38 targets: 'iOS 9, Android 4.4, last 2 versions, > 0.2%, not dead', // 根据项目去配置
39 useBuiltIns: 'usage', // 会根据配置的目标环境找出需要的polyfill进行部分引入
40 corejs: 3, // 使用 core-js@3 版本
41 },
42 ],
43 ['@babel/preset-typescript'],
44 ['@babel/preset-react'],
45 ],
46 },
47 },
48 },
49
50 {
51 test: /\.(png|jpe?g|gif|svg|webp)$/i,
52 type: 'asset',
53 parser: {
54 dataUrlCondition: {
55 maxSize: 25 * 1024, // 25kb
56 },
57 },
58 generator: {
59 filename: 'assets/imgs/[name].[hash:8][ext]',
60 },
61 },
62
63 {
64 test: /\.(eot|ttf|woff|woff2)$/i,
65 type: 'asset',
66 parser: {
67 dataUrlCondition: {
68 maxSize: 25 * 1024, // 25kb
69 },
70 },
71 generator: {
72 filename: 'assets/fonts/[name].[hash:8][ext]',
73 },
San3yuan2534d422025-04-08 21:43:18 +080074 },
75 {
76 test: /\.module\.css$/,
77 use: [
78 isDev ? 'style-loader' : MiniCssExtractPlugin.loader,
79 {
80 loader: 'css-loader',
81 options: {
82 modules: {
83 namedExport: false,
84 localIdentName: isDev
85 ? '[name]__[local]__[hash:base64:5]'
86 : '[hash:base64:8]'
87 },
88 importLoaders: 1
89 },
90 },
91 {
92 loader: 'postcss-loader',
93 options: {
94 postcssOptions: {
95 plugins: ['postcss-preset-env'],
96 },
97 },
98 },
99 ],
100 },
101 {
San3yuan4d0e8032025-04-04 17:21:40 +0800102 test: /\.(css|less)$/,
San3yuan2534d422025-04-08 21:43:18 +0800103 exclude: /\.module\.css$/,
San3yuan4d0e8032025-04-04 17:21:40 +0800104 use: [
San3yuan2534d422025-04-08 21:43:18 +0800105 isDev?'style-loader':MiniCssExtractPlugin.loader, // 使用 MiniCssExtractPlugin.loader 代替 style-loader
San3yuan4d0e8032025-04-04 17:21:40 +0800106 'css-loader',
107 {
108 loader: 'postcss-loader',
109 options: {
110 // 它可以帮助我们将一些现代的 CSS 特性,转成大多数浏览器认识的 CSS,并且会根据目标浏览器或运行时环境添加所需的 polyfill;
111 // 也包括会自动帮助我们添加 autoprefixer
112 postcssOptions: {
113 plugins: [['postcss-preset-env', {}]],
114 },
115 },
116 },
117 'less-loader',
118 ],
San3yuan2534d422025-04-08 21:43:18 +0800119 },
San3yuan4d0e8032025-04-04 17:21:40 +0800120
121 ],
122 },
123 optimization: {
124 minimizer: [
125 // 在 webpack@5 中,你可以使用 `...` 语法来扩展现有的 minimizer(即 `terser-webpack-plugin`),将下一行取消注释
126 `...`,
127 new CssMinimizerPlugin({
128 // 默认开启
129 // parallel true: // 多进程并发执行,提升构建速度 。 运行时默认的并发数:os.cpus().length - 1
130 }),
131 ],
132 },
133
134 plugins:[
135 new HtmlWebpackPlugin({
136 template:path.resolve(__dirname, '../public/index.html')
137 }),
138 new MiniCssExtractPlugin({
San3yuan2534d422025-04-08 21:43:18 +0800139 filename: 'assets/css/[name].[contenthash:8].css',
140 chunkFilename: 'assets/css/[id].[contenthash:8].css',
San3yuan4d0e8032025-04-04 17:21:40 +0800141 }),
142 new CircularDependencyPlugin({
143 exclude: /node_modules/,
144 include: /src/,
145 failOnError: true,
146 allowAsyncCycles: false,
147 cwd: process.cwd(),
148 })
149 ]
150}