const path = require('path') const webpack = require('webpack') const { VueLoaderPlugin } = require('vue-loader') module.exports = { mode: 'production', // 明确指定生产模式 entry: './src/index.js', output: { path: path.resolve(__dirname, 'dist'), filename: 'admin-framework.js', library: 'AdminFramework', libraryTarget: 'umd', libraryExport: 'default', globalObject: 'typeof self !== \'undefined\' ? self : this', clean: true // 构建前清理 dist 目录 }, externals: { vue: { commonjs: 'vue', commonjs2: 'vue', amd: 'vue', root: 'Vue' }, 'vue-router': { commonjs: 'vue-router', commonjs2: 'vue-router', amd: 'vue-router', root: 'VueRouter' }, vuex: { commonjs: 'vuex', commonjs2: 'vuex', amd: 'vuex', root: 'Vuex' }, 'view-design': { commonjs: 'view-design', commonjs2: 'view-design', amd: 'view-design', root: 'iview' }, axios: { commonjs: 'axios', commonjs2: 'axios', amd: 'axios', root: 'axios' } }, module: { rules: [ { test: /\.vue$/, loader: 'vue-loader' }, { test: /\.js$/, loader: 'babel-loader', exclude: /node_modules/ }, { test: /\.css$/, use: [ 'vue-style-loader', 'css-loader' ] }, { test: /\.less$/, use: [ 'vue-style-loader', 'css-loader', 'less-loader' ] }, { // 图片文件:全部转为 base64 内联到代码中 test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, loader: 'url-loader', options: { limit: 999999999, // 所有图片都转为 base64 内联(设置超大限制) esModule: false } }, { // 字体文件:全部转为 base64 内联到代码中 test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, loader: 'url-loader', options: { limit: 999999999, // 所有字体都转为 base64 内联 esModule: false } }, { // 媒体文件:全部转为 base64 内联到代码中 test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/, loader: 'url-loader', options: { limit: 999999999, // 所有媒体文件都转为 base64 内联 esModule: false } }, { // JSON 文件:内联到代码中 test: /\.json$/, type: 'asset/inline' }, { // 其他资源文件:内联到代码中 test: /\.(txt|xml|md)$/, type: 'asset/inline' } ] }, plugins: [ new VueLoaderPlugin(), new webpack.BannerPlugin({ banner: () => { const now = new Date() const updateTime = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')} ${String(now.getHours()).padStart(2, '0')}:${String(now.getMinutes()).padStart(2, '0')}:${String(now.getSeconds()).padStart(2, '0')}` return [ 'admin-framework v1.0.0', '通用后台管理系统框架 - 包含系统功能、登录、路由管理、布局等', '', '作者: light', '更新时间: ' + updateTime, '', 'Copyright (c) ' + now.getFullYear() ].join('\n') }, entryOnly: true // 只在入口文件顶部添加 }) ], resolve: { extensions: ['.js', '.vue', '.json'], alias: { '@': path.resolve(__dirname, 'src'), '@component': path.resolve(__dirname, 'src/components'), '@utils': path.resolve(__dirname, 'src/utils'), '@api': path.resolve(__dirname, 'src/api'), '@config': path.resolve(__dirname, 'src/config'), '@assets': path.resolve(__dirname, 'src/assets'), 'vue$': 'vue/dist/vue.esm.js' } }, optimization: { minimize: true, minimizer: [ new (require('terser-webpack-plugin'))({ terserOptions: { format: { comments: /^!|@preserve|@license|@cc_on|admin-framework|作者/i // 保留特殊注释 } }, extractComments: false // 不提取注释到单独文件 }) ] } }