/** * Admin Framework Webpack 配置 * * 文件命名规则说明: * * 1. 图片文件 (images/) * - SVG 图标: images/svg/[name].[hash:7].svg * - PNG 图片: images/png/[name].[hash:7].png * - JPG 图片: images/jpg/[name].[hash:7].jpg * - GIF 动图: images/gif/[name].[hash:7].gif * * 2. 字体文件 (fonts/) * - WOFF/WOFF2: fonts/woff/[name].[hash:7].woff(2) * - TTF: fonts/ttf/[name].[hash:7].ttf * - EOT: fonts/eot/[name].[hash:7].eot * - OTF: fonts/otf/[name].[hash:7].otf * * 3. 媒体文件 (media/) * - 视频: media/video/[name].[hash:7].mp4/webm/ogg * - 音频: media/audio/[name].[hash:7].mp3/wav/flac/aac * * 4. 数据文件 (data/) * - JSON: data/[name].[hash:7].json * * 5. 其他资源 (assets/) * - TXT/XML/MD: assets/[name].[hash:7].txt/xml/md * * 命名占位符说明: * - [name]: 原始文件名 * - [hash:7]: 7 位内容哈希(用于缓存控制) * - [ext]: 文件扩展名(包含点号) */ const path = require('path') 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' ] }, { // 图片文件:根据文件类型分类存放 test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, loader: 'url-loader', options: { limit: 10000, // 小于 10KB 转为 base64 name: (resourcePath, resourceQuery) => { // 根据文件扩展名分类 const ext = path.extname(resourcePath).toLowerCase() if (ext === '.svg') { return 'images/svg/[name].[hash:7][ext]' } else if (ext === '.png') { return 'images/png/[name].[hash:7][ext]' } else if (ext === '.jpg' || ext === '.jpeg') { return 'images/jpg/[name].[hash:7][ext]' } else if (ext === '.gif') { return 'images/gif/[name].[hash:7][ext]' } return 'images/[name].[hash:7][ext]' }, esModule: false } }, { // 字体文件:根据字体类型分类存放 test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, loader: 'url-loader', options: { limit: 10000, // 小于 10KB 转为 base64 name: (resourcePath, resourceQuery) => { // 根据文件扩展名分类 const ext = path.extname(resourcePath).toLowerCase() if (ext === '.woff' || ext === '.woff2') { return 'fonts/woff/[name].[hash:7][ext]' } else if (ext === '.ttf') { return 'fonts/ttf/[name].[hash:7][ext]' } else if (ext === '.eot') { return 'fonts/eot/[name].[hash:7][ext]' } else if (ext === '.otf') { return 'fonts/otf/[name].[hash:7][ext]' } return 'fonts/[name].[hash:7][ext]' }, esModule: false } }, { // 媒体文件:视频和音频 test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/, loader: 'url-loader', options: { limit: 10000, name: (resourcePath, resourceQuery) => { const ext = path.extname(resourcePath).toLowerCase() if (['.mp4', '.webm', '.ogg'].includes(ext)) { return 'media/video/[name].[hash:7][ext]' } else if (['.mp3', '.wav', '.flac', '.aac'].includes(ext)) { return 'media/audio/[name].[hash:7][ext]' } return 'media/[name].[hash:7][ext]' }, esModule: false } }, { // JSON 文件 test: /\.json$/, type: 'asset/resource', generator: { filename: 'data/[name].[hash:7][ext]' } }, { // 其他资源文件 test: /\.(txt|xml|md)$/, type: 'asset/resource', generator: { filename: 'assets/[name].[hash:7][ext]' } } ] }, plugins: [ new VueLoaderPlugin() ], 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 } }