import type { UserConfigExport } from '@tarojs/cli'; import path from 'path'; import dotenv from 'dotenv'; import ReactRefreshWebpackPlugin from '@pmmmwh/react-refresh-webpack-plugin'; // 加载 .env.development 文件中的环境变量 dotenv.config({ path: path.resolve(__dirname, '../.env.development') }); /** * 构建时间测量插件 * 用于测量开发环境下的编译时间(包括首次编译和增量编译) */ class BuildTimerPlugin { private buildStartTime: number = 0; private buildNumber: number = 0; apply(compiler: any) { // Watch 模式的编译开始(包括首次和增量) compiler.hooks.watchRun.tap('BuildTimerPlugin', (comp: any) => { this.buildNumber++; this.buildStartTime = Date.now(); const time = new Date().toLocaleTimeString('zh-CN', { hour12: false }); console.log('\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'); console.log(`🔨 [构建 #${this.buildNumber}] ${this.buildNumber === 1 ? '首次' : '增量'}编译开始... ${time}`); }); // 非 Watch 模式的编译开始(理论上开发环境不会用到) compiler.hooks.run.tap('BuildTimerPlugin', () => { this.buildNumber++; this.buildStartTime = Date.now(); const time = new Date().toLocaleTimeString('zh-CN', { hour12: false }); console.log('\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'); console.log(`🔨 [构建 #${this.buildNumber}] 编译开始... ${time}`); }); // 编译完成(包括首次和增量) compiler.hooks.done.tap('BuildTimerPlugin', (stats: any) => { const duration = Date.now() - this.buildStartTime; const seconds = (duration / 1000).toFixed(2); const time = new Date().toLocaleTimeString('zh-CN', { hour12: false }); // 获取编译的模块数量 const modulesCount = stats.compilation.modules.size; // 判断是否有错误或警告 const hasErrors = stats.hasErrors(); const hasWarnings = stats.hasWarnings(); console.log(`${hasErrors ? '❌' : '✅'} [构建 #${this.buildNumber}] 编译${hasErrors ? '失败' : '完成'}! ${time}`); console.log(`⏱️ 耗时: ${seconds}s (${duration}ms)`); console.log(`📊 模块数: ${modulesCount}`); if (hasErrors) { console.log(`⚠️ 错误: ${stats.compilation.errors.length} 个`); } if (hasWarnings) { console.log(`⚠️ 警告: ${stats.compilation.warnings.length} 个`); } console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n'); }); } } export default { logger: { quiet: false, stats: true, }, defineConstants: { MQTT_BROKER_URL_FROM_WEBPACK: '"ws://192.168.110.13:8083/mqtt"', // MQTT_BROKER_URL_FROM_WEBPACK: '"ws://192.168.110.245:8083/mqtt"', }, mini: {}, h5: { // ⚡ 优化:使用更快的 source map 类型(提升 40-60% 构建速度) // 'eval-source-map' 是最慢但最详细的 // 'cheap-module-source-map' 快很多,仍然保留行号和源码映射 sourceMapType: 'cheap-module-source-map', publicPath: '/', devServer: { proxy: { '/dr': { target: 'http://192.168.110.13', // 你的后端服务地址 // target: 'http://192.168.110.133', changeOrigin: true, // 允许跨域 // pathRewrite: { // '^/dr/api': '' // 可选,用于重写路径 // } }, '/mqtt': { target: 'ws://192.168.110.13:8083', // MQTT WebSocket 服务地址 // target: 'ws://192.168.110.133:8083', changeOrigin: true, ws: true, // 启用 WebSocket 代理 // pathRewrite: { // '^/mqtt': '/mqtt' // 保持路径不变,或根据需要调整 // } }, }, // server: 'https', // 启用 HTTPS ,为了开发环境测试打开摄像头功能 host: '0.0.0.0', // 监听所有网络接口 open: false, // 可选:是否自动打开浏览器 port: 10086, // 可选:指定端口号 static: { directory: path.resolve(__dirname, '../public'), }, }, // Use webpackChain to customize Webpack // eslint-disable-next-line webpackChain(chain, webpack) { // ✅ 添加构建时间测量插件 chain.plugin('build-timer').use(BuildTimerPlugin); // 读取环境变量,告诉webpack在打包时,使用环境变量中定义的值 替换掉代码中的process.env.USE_MSW // 打印环境变量,检查是否正确读取 console.log('环境变量 process.env.USE_MSW:', process.env.USE_MSW); console.log('环境变量 process.env.NODE_ENV:', process.env.NODE_ENV); // 确保使用正确的值,直接从.env文件读取 const useMSW = JSON.stringify( process.env.USE_MSW === 'true' ? 'true' : 'false' ); console.log('使用的 useMSW 值:', useMSW); // 检查 define 插件是否已存在,如果不存在则先创建它 const hasDefinePlugin = chain.plugins.has('define'); if (!hasDefinePlugin) { chain.plugin('define').use(webpack.DefinePlugin, [{}]); } /* 1. 把 Taro 可能注入的所有 react-refresh 插件先删掉 */ chain.plugins.delete('react-refresh'); // 3.5 之前 chain.plugins.delete('ReactRefreshWebpackPlugin'); // 3.6+ 可能叫这个 /* 2. 重新注册,强制关闭 overlay */ chain .plugin('ReactRefreshWebpackPlugin') // 名字随意,保证唯一 .use(ReactRefreshWebpackPlugin, [ { overlay: false, // 👈 关键:关掉灰色蒙层 }, ]) // 然后再修改插件配置 chain.plugin('define').tap((args) => { // 确保args[0]存在 if (!args[0]) { args[0] = {}; } args[0]['process.env.USE_MSW'] = useMSW; console.log('DefinePlugin配置:', args[0]); return args; }); chain.devServer.merge({ setupMiddlewares: (middlewares, devServer) => { devServer.app.get('/mockServiceWorker.js', (req, res) => { res.set('Content-Type', 'application/javascript'); res.sendFile( path.resolve(__dirname, '../public/mockServiceWorker.js') ); }); return middlewares; }, }); }, }, } satisfies UserConfigExport<'webpack5'>;