rspack.base.config.ts 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. // @ts-nocheck
  2. import { type RspackPluginFunction, rspack } from '@rspack/core';
  3. import { VueLoaderPlugin } from 'vue-loader';
  4. import path from 'path';
  5. import { isProd } from '../plugin/getEnv';
  6. import sassEmbedded from 'sass-embedded';
  7. import ESLintPlugin from 'eslint-rspack-plugin';
  8. import Components from 'unplugin-vue-components/rspack';
  9. import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
  10. import AutoImportPlugin from 'unplugin-auto-import/rspack';
  11. import packageJson from '../package.json';
  12. // 目标浏览器配置
  13. const targets = ['last 2 versions', '> 0.2%', 'not dead', 'Firefox ESR'];
  14. // 基础配置
  15. export const baseConfig = {
  16. entry: {
  17. main: './src/main.ts',
  18. },
  19. resolve: {
  20. extensions: ['...', '.ts', '.vue'],
  21. alias: {
  22. '@': path.resolve(__dirname, '../src'),
  23. },
  24. },
  25. module: {
  26. rules: [
  27. {
  28. test: /\.vue$/,
  29. loader: 'vue-loader',
  30. options: {
  31. experimentalInlineMatchResource: true,
  32. },
  33. },
  34. {
  35. test: /\.(js|ts)$/,
  36. use: [
  37. {
  38. loader: 'builtin:swc-loader',
  39. options: {
  40. jsc: {
  41. parser: {
  42. syntax: 'typescript',
  43. },
  44. },
  45. env: { targets },
  46. },
  47. },
  48. ],
  49. },
  50. {
  51. test: /\.jsx$/,
  52. use: {
  53. loader: 'builtin:swc-loader',
  54. options: {
  55. jsc: {
  56. parser: {
  57. syntax: 'ecmascript',
  58. jsx: true,
  59. },
  60. },
  61. },
  62. },
  63. type: 'javascript/auto',
  64. },
  65. {
  66. test: /\.tsx$/,
  67. use: {
  68. loader: 'builtin:swc-loader',
  69. options: {
  70. jsc: {
  71. parser: {
  72. syntax: 'typescript',
  73. tsx: true,
  74. },
  75. },
  76. },
  77. },
  78. type: 'javascript/auto',
  79. },
  80. {
  81. test: /\.d\.ts$/,
  82. loader: 'ignore-loader',
  83. },
  84. // SVG处理规则
  85. {
  86. test: /\.svg$/,
  87. exclude: [path.resolve(__dirname, '../src/assets/icons')],
  88. type: 'asset/resource',
  89. },
  90. {
  91. test: /\.svg$/,
  92. include: [path.resolve(__dirname, '../src/assets/icons')],
  93. use: [
  94. {
  95. loader: 'svg-sprite-loader',
  96. options: {
  97. symbolId: 'icon-[name]',
  98. },
  99. },
  100. ],
  101. },
  102. {
  103. test: /\.(png|jpe?g|gif)$/i,
  104. type: 'asset/resource',
  105. },
  106. // 处理CSS文件
  107. {
  108. test: /\.css$/i,
  109. use: [
  110. isProd() ? rspack.CssExtractRspackPlugin.loader : 'style-loader',
  111. 'css-loader',
  112. 'postcss-loader',
  113. ],
  114. },
  115. // 处理SCSS/SASS文件
  116. {
  117. test: /\.(scss|sass)$/i,
  118. use: [
  119. isProd() ? rspack.CssExtractRspackPlugin.loader : 'style-loader',
  120. 'css-loader',
  121. {
  122. loader: 'sass-loader',
  123. options: {
  124. api: 'modern-compiler',
  125. implementation: sassEmbedded,
  126. sassOptions: {
  127. includePaths: [path.resolve(__dirname, '../src/styles')],
  128. },
  129. additionalData: '@use "@/styles/variables.scss" as *;',
  130. },
  131. },
  132. ],
  133. type: 'javascript/auto',
  134. },
  135. ],
  136. },
  137. plugins: [
  138. new rspack.CssExtractRspackPlugin({
  139. filename: '[name].[contenthash].css',
  140. }),
  141. new rspack.HtmlRspackPlugin({
  142. template: './index.html',
  143. title: packageJson.name || '声音AI平台',
  144. // favicon: path.resolve(__dirname, '../public/favicon.ico'),
  145. meta: {
  146. description: '声音AI平台 - 专业的声音处理与分析工具',
  147. keywords: '声音AI,音频处理,AI平台,语音识别',
  148. author: 'Sound AI Team',
  149. },
  150. minify: isProd()
  151. ? {
  152. removeComments: true,
  153. collapseWhitespace: true,
  154. removeRedundantAttributes: true,
  155. useShortDoctype: true,
  156. removeEmptyAttributes: true,
  157. removeStyleLinkTypeAttributes: true,
  158. keepClosingSlash: true,
  159. minifyJS: true,
  160. minifyCSS: true,
  161. minifyURLs: true,
  162. }
  163. : false,
  164. }),
  165. AutoImportPlugin({
  166. include: [
  167. /\.[tj]sx?$/, // .ts, .tsx, .js, .jsx
  168. /\.vue$/,
  169. /\.vue\?vue/, // .vue
  170. /\.md$/, // .md
  171. ],
  172. imports: [
  173. 'vue',
  174. 'vue-router',
  175. // 可额外添加需要 autoImport 的组件
  176. {
  177. // '@/hooks/web/useI18n': ['useI18n'],
  178. axios: [
  179. // default imports
  180. ['default', 'axios'], // import { default as axios } from 'axios',
  181. ],
  182. },
  183. ],
  184. dts: 'src/types/auto-imports.d.ts',
  185. resolvers: [ElementPlusResolver()],
  186. eslintrc: {
  187. enabled: false, // Default `false`
  188. filepath: './.eslintrc-auto-import.json', // Default `./.eslintrc-auto-import.json`
  189. globalsPropValue: true, // Default `true`, (true | false | 'readonly' | 'readable' | 'writable' | 'writeable')
  190. },
  191. }),
  192. new rspack.DefinePlugin({
  193. __VUE_OPTIONS_API__: 'true',
  194. __VUE_PROD_DEVTOOLS__: 'false',
  195. __VUE_PROD_HYDRATION_MISMATCH_DETAILS__: 'false',
  196. API_BASE_URL: JSON.stringify(process.env.API_BASE_URL),
  197. 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
  198. }),
  199. new VueLoaderPlugin() as RspackPluginFunction,
  200. // 添加ESLint插件
  201. new ESLintPlugin({
  202. configType: 'flat',
  203. extensions: ['js', 'jsx', 'ts', 'tsx', 'vue'],
  204. exclude: ['node_modules', 'dist'],
  205. emitWarning: true,
  206. emitError: true,
  207. failOnError: false,
  208. failOnWarning: false,
  209. cache: true,
  210. cacheLocation: path.resolve(
  211. __dirname,
  212. '../node_modules/.cache/.eslintcache',
  213. ),
  214. }),
  215. // 添加组件自动导入插件
  216. Components({
  217. // 配置组件目录,默认为 src/components
  218. dirs: ['src/components'],
  219. // 组件的有效文件扩展名
  220. extensions: ['vue'],
  221. // 搜索子目录
  222. deep: true,
  223. // 自定义组件的解析器
  224. resolvers: [ElementPlusResolver()],
  225. // 生成 TypeScript 声明文件
  226. dts: 'src/types/components.d.ts',
  227. // 允许子目录作为组件的命名空间前缀
  228. directoryAsNamespace: true,
  229. // 自动导入指令
  230. directives: true,
  231. }),
  232. ],
  233. optimization: {
  234. minimizer: [
  235. new rspack.SwcJsMinimizerRspackPlugin(),
  236. new rspack.LightningCssMinimizerRspackPlugin({
  237. minimizerOptions: { targets },
  238. }),
  239. ],
  240. },
  241. experiments: {
  242. futureDefaults: true,
  243. css: false,
  244. },
  245. };
  246. export default baseConfig;