背景
昨天写得一篇Electron-vue asar 局部打包优化处理方案——绕开每次npm run build 超级慢的打包问题-CSDN博客文章浏览阅读754次,点赞19次,收藏11次。因为组员对于 Electron 打包过程存在比较迷糊的状态,且自己也没主动探索 Electron-vue 打包细节,导致每次打包过程都消耗 5-6 分钟的时间,在需要测试生产打包时,极其浪费时间,为此针对 Electron-vue 打包的几个环节进行拆解,来减少打包时间,提高开发效率。https://blog.csdn.net/wangsenling/article/details/142364579
打包超级慢的原因不是最终electron-builder环节的问题,而是webpack打包渲染进程的问题,今天经过与ChatGPT一起优化,终于把速度降了大概5倍左右,直接让文件打包速度快了很多。
具体配置
1. 主要是多进程处理,这里追加了4个worker,自己的cpu核心有几个可以配置几个,这个主要加速点
2. 去掉了原来的一个没有用的plugin
3. 增加了缓存机制
'use strict'
process.env.BABEL_ENV = 'renderer'
const path = require('path')
const {dependencies} = require('../package.json')
const webpack = require('webpack')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const {VueLoaderPlugin} = require('vue-loader')
const TerserPlugin = require('terser-webpack-plugin');
/**
* List of node_modules to include in webpack bundle
*
* Required for specific packages like Vue UI libraries
* that provide pure *.vue files that need compiling
* https://simulatedgreg.gitbooks.io/electron-vue/content/en/webpack-configurations.html#white-listing-externals
*/
let whiteListedModules = ['vue', 'element-ui']
let rendererConfig = {
// 添加以下一行,设置 mode
mode: process.env.NODE_ENV === 'production' ? 'production' : 'development',
devtool: process.env.NODE_ENV === 'production' ? false : '#cheap-module-eval-source-map',
entry: {
renderer: path.join(__dirname, '../src/renderer/main.js'),
},
externals: [
...Object.keys(dependencies || {}).filter(
(d) => !whiteListedModules.includes(d)
),
],
module: {
rules: [
{
test: /\.scss$/,
use: ['vue-style-loader', 'css-loader', 'sass-loader'],
},
{
test: /\.sass$/,
use: ['vue-style-loader', 'css-loader', 'sass-loader?indentedSyntax'],
},
{
test: /\.less$/,
use: ['vue-style-loader', 'css-loader', 'less-loader'],
},
{
test: /\.css$/,
use: ['vue-style-loader', 'css-loader'],
},
{
test: /\.html$/,
use: 'vue-html-loader',
},
{
test: /\.js$/,
use: [
{
loader: 'thread-loader',
options: {
workers: 4, // 设置 worker 数量
},
}, {
loader: 'babel-loader',
options: {
cacheDirectory: true
}
}
],
exclude: /node_modules/,
},
{
test: /\.node$/,
use: 'node-loader',
},
{
test: /\.vue$/,
use: {
loader: 'vue-loader',
options: {
extractCSS: process.env.NODE_ENV === 'production',
loaders: {
sass: 'vue-style-loader!css-loader!sass-loader?indentedSyntax=1',
scss: 'vue-style-loader!css-loader!sass-loader',
less: 'vue-style-loader!css-loader!less-loader',
},
},
},
},
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
use: {
loader: 'url-loader',
query: {
limit: 10000,
name: 'imgs/[name]--[folder].[ext]',
},
},
},
{
test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: 'media/[name]--[folder].[ext]',
},
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
use: {
loader: 'url-loader',
query: {
limit: 10000,
name: 'fonts/[name]--[folder].[ext]',
},
},
},
],
},
node: {
__dirname: process.env.NODE_ENV !== 'production',
__filename: process.env.NODE_ENV !== 'production',
},
plugins: [
new VueLoaderPlugin(),
new MiniCssExtractPlugin({filename: 'styles.css'}),
new HtmlWebpackPlugin({
filename: 'index.html',
template: path.resolve(__dirname, '../src/index.ejs'),
templateParameters(compilation, assets, options) {
return {
compilation: compilation,
webpack: compilation.getStats().toJson(),
webpackConfig: compilation.options,
htmlWebpackPlugin: {
files: assets,
options: options,
},
process,
}
},
minify: {
collapseWhitespace: true,
removeAttributeQuotes: true,
removeComments: true,
},
nodeModules:
process.env.NODE_ENV !== 'production'
? path.resolve(__dirname, '../node_modules')
: false,
}),
new webpack.NoEmitOnErrorsPlugin(),
],
output: {
filename: '[name].js',
chunkFilename: "cities/[name].js",
libraryTarget: 'commonjs2',
path: path.join(__dirname, '../dist/electron'),
},
resolve: {
alias: {
'@': path.join(__dirname, '../src/renderer'),
vue$: 'vue/dist/vue.esm.js',
},
extensions: ['.js', '.vue', '.json', '.css', '.node'],
},
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
parallel: true, // 开启多线程压缩
cache: true,
terserOptions: {
// 在这里添加 Terser 的配置选项
compress: {
drop_console: true, // 例如,移除 console.log
},
},
}),
],
},
target: 'electron-renderer',
}
/**
* Adjust rendererConfig for development settings
*/
if (process.env.NODE_ENV !== 'production') {
rendererConfig.plugins.push(
new webpack.HotModuleReplacementPlugin(),
new webpack.DefinePlugin({
__static: `"${path.join(__dirname, '../static').replace(/\\/g, '\\\\')}"`,
})
)
}
/**
* Adjust rendererConfig for production settings
*/
if (process.env.NODE_ENV === 'production') {
rendererConfig.devtool = ''
rendererConfig.plugins.push(
new CopyWebpackPlugin([
{
from: path.join(__dirname, '../static'),
to: path.join(__dirname, '../dist/electron/static'),
ignore: ['.*'],
},
]),
new webpack.DefinePlugin({
'process.env.NODE_ENV': '"production"',
})
)
}
module.exports = rendererConfig