UNPKG

infly-libs

Version:

工具组件库

227 lines (207 loc) 5.41 kB
"use strict"; const path = require("path"); const InlineRuntimePlugin = require("./inline-runtime-plugin"); // 环境变量与常量配置 const ENV = { IS_PROD: ["production", "staging"].includes(process.env.NODE_ENV) }; /** * 解析项目路径(兼容monorepo) * @param {string} dir 相对路径 * @returns {string} 绝对路径 */ function resolve(dir) { return path.join(process.cwd(), dir); } /** * Node.js polyfill */ function createNodePolyfills() { return { path: require.resolve("path-browserify") // 需要时可添加更多 polyfill // fs: false, // stream: require.resolve('stream-browserify'), // crypto: require.resolve('crypto-browserify') }; } /** * CSS/SCSS配置 */ function cssModule({ additionalData }) { return { loaderOptions: { sass: { implementation: require("sass"), sassOptions: { api: "modern", quietDeps: true, silenceDeprecations: ["legacy-js-api", "function-units"] }, additionalData }, css: { esModule: true, modules: { auto: true, localIdentName: "[name]_[local]_[hash:base64:5]" } } }, extract: ENV.IS_PROD ? { ignoreOrder: true } : false }; } /** * 基础 configureWebpack 配置 */ function configureWebpack({ name }) { return { name, resolve: { alias: { vue$: "vue/dist/vue.esm.js", "@": resolve("src") }, fallback: createNodePolyfills() }, target: ["web", "es5"], output: { environment: { arrowFunction: false, bigIntLiteral: false, const: false, destructuring: false, dynamicImport: false, forOf: false, module: false } }, performance: { hints: false }, ignoreWarnings: [{ module: /sass-loader/ }] }; } /** * chainWebpack配置 */ function chainWebpack(config) { config.plugins.delete("preload"); config.plugins.delete("prefetch"); // 注册 runtime 内联插件 config.plugin("inline-runtime").use(InlineRuntimePlugin) // SVG图标 config.module.rule("svg").exclude.add(resolve("src/icons")).end(); config.module .rule("icons") .test(/\.svg$/) .include.add(resolve("src/icons")) .end() .use("svg-sprite-loader") .loader("svg-sprite-loader") .options({ symbolId: "icon-[name]" }) .end(); // Vue Loader config.module .rule("vue") .use("vue-loader") .loader("vue-loader") .tap((options) => ({ ...options, compilerOptions: { ...(options.compilerOptions || {}), preserveWhitespace: true, whitespace: "preserve" } })) .end(); // 图片资源 config.module .rule("images") .test(/\.(png|jpe?g|gif|webp)$/i) .set("type", "asset") .set("parser", { dataUrlCondition: { maxSize: 4 * 1024 } }); // SVG资源(非图标) config.module .rule("svg-assets") .test(/\.(svg)$/i) .exclude.add(resolve("src/icons")) .end() .set("type", "asset/resource"); // 媒体资源 config.module .rule("media") .test(/\.(mp4|webm|ogg|mp3|wav|flac|aac)$/i) .set("type", "asset") .set("parser", { dataUrlCondition: { maxSize: 4 * 1024 } }); // 字体资源 config.module .rule("fonts") .test(/\.(woff2?|eot|ttf|otf)$/i) .set("type", "asset/resource"); // 生产环境优化 if (ENV.IS_PROD) { config.plugin("html").tap((args) => { const options = args[0] || {}; const now = new Date(); return [ { ...options, scriptLoading: "blocking", inject: true, buildTimestamp: now.toLocaleString(), buildVersion: process.env.npm_package_version || "1.0.0", buildEnv: process.env.NODE_ENV } ]; }); config.optimization.splitChunks({ chunks: "all", minSize: 20000, minChunks: 1, maxAsyncRequests: 30, maxInitialRequests: 30, enforceSizeThreshold: 50000, cacheGroups: { libs: { name: "chunk-libs", test: /[\\/]node_modules[\\/]/, priority: 10, chunks: "initial" }, elementUI: { name: "chunk-elementUI", priority: 20, test: /[\\/]node_modules[\\/]_?element-ui(.*)/ }, commons: { name: "chunk-commons", test: resolve("src/components"), minChunks: 3, priority: 5, reuseExistingChunk: true } } }); config.optimization.runtimeChunk("single"); config.optimization.minimizer("terser").tap((args) => { const options = args[0] || {}; const terserOptions = options.terserOptions || {}; options.terserOptions = { ...terserOptions, compress: { ...(terserOptions.compress || {}), drop_console: true, drop_debugger: true, pure_funcs: ["console.log"] } }; return [options]; }); } else { config.devtool("eval-cheap-module-source-map"); } } module.exports = { cssModule, configureWebpack, chainWebpack };