infly-libs
Version:
工具组件库
227 lines (207 loc) • 5.41 kB
JavaScript
"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
};