| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165 |
- 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.245',
- changeOrigin: true, // 允许跨域
- // pathRewrite: {
- // '^/dr/api': '' // 可选,用于重写路径
- // }
- },
- '/mqtt': {
- // target: 'ws://192.168.110.13:8083', // MQTT WebSocket 服务地址
- target: 'ws://192.168.110.245: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'>;
|