Electron-vue 框架升级 Babel7 并支持electron-preload webapck 4 打包过程记录
前言
我这边一直用的electron-vue框架是基于electron 21版本的,electron 29版本追加了很多新功能,但是这些新功能对开发者不友好,对electron构建出来的软件,使用者更安全,所以,我暂时不想研究electron 29版本,可发挥的地方又收窄了,electron这种东西越用越喜欢,嵌入进来的网页,可以自己想怎么搞就怎么搞,比起浏览器开发,真是专门为开发者独家打造的。
背景
electron-vue 老代码是不支持 data?.这种新式 ES 语法不支持打包,如若支持的话,又发现新版的 babel 插件又依赖于 babel7,导致出现 babel 版本冲突,最后的解决方案,则是全面升级 babel 至 babel7,并且适配好 webpack4(目前 electron-vue 框架正在用的),现将整个升级过程记录,同时也完善下.babelrc 配置文件在代码中如何生效的。
注意事项
electron 打包preload.js时如果是webview或者renderer.src="chrome-extesion://xxxxx" 这样开头的,是不支持module.exports 开头的,这种开头是node.js环境下的commonjs模块化支持,chrome-extension://xxxx 这个环境应该更特殊,更像target:"web"环境,但却支持require("electron"),目前我还没完全掌握规律,所以基于chrome-extension://xxxx 环境,还是老老实实自己写代码。
PS: chrome-extension://xxxxx 是个什么鬼?这是谷歌插件提供的option.html页面的访问协议,不懂得可以去谷歌一下,后续会出谷歌插件开发高级课程。
升级过程
卸载已安装的 babel 版本
npm uninstall babel-core babel-preset-env babel-plugin-transform-runtime babel-register babel-minify-webpack-plugin babel-loader
安装 Babel7 和其他相关依赖
-- babel7 核心库
npm install --save-dev @babel/core@7 @babel/cli@7 @babel/preset-env@7 babel-loader@8
-- 安装可选链、?? 判断插件
npm install --save-dev @babel/plugin-proposal-optional-chaining@7 @babel/plugin-proposal-nullish-coalescing-operator@7
-- 安装 Babel 的 runtime 插件(如果您的代码使用了 async/await 或者 generator 函数等)
npm install --save-dev @babel/plugin-transform-runtime@7 @babel/runtime@7
适配 webpack 的 terser
npm install terser-webpack-plugin@4.2.3 --save-dev
安装一些其他 babel 插件
npm install @babel/plugin-proposal-optional-chaining @babel/plugin-proposal-nullish-coalescing-operator @babel/plugin-proposal-class-properties @babel/plugin-proposal-private-methods @babel/plugin-transform-runtime --save-dev
babel 关键插件解释:
这些插件分别用于以下功能:
-
@babel/plugin-proposal-optional-chaining
: 允许在代码中使用可选链操作符(?.
)。 -
@babel/plugin-proposal-nullish-coalescing-operator
: 允许在代码中使用空值合并操作符(??
)。 -
@babel/plugin-proposal-class-properties
: 允许使用类属性语法。 -
@babel/plugin-proposal-private-methods
: 允许使用私有方法语法(例如:#privateMethod
)。 -
@babel/plugin-transform-runtime
: 用于将一些 ES6+ 的功能(如 Generator 函数)转化为兼容性更好的代码,同时避免重复的代码冗余。
.babelrc 配置怎么用
.babelrc 集中配置了几种 babel env 环境的配置,在具体的 webpack 打包配置时,可以通过设置环境变量来使用具体的配置
.babelrc preload 环境截图
为什么配置在 plugins
下统一?
-
plugins
是针对所有环境(main
,renderer
,preload
,web
)统一的。因为这些插件的功能通常是跨环境的(即无论是在浏览器端、Node.js 环境,还是 Electron 渲染进程中,使用这些插件的代码行为应该一致)。所以将它们放到plugins
配置中统一管理,可以减少冗余的配置。
附带 preload 的 webpack 打包配置代码
完全精简版的 preload 配置代码
'use strict'
process.env.BABEL_ENV = 'preload'
const path = require('path')
const {dependencies} = require('../../package.json')
const webpack = require('webpack')
const TerserPlugin = require('terser-webpack-plugin');
// 获取当前配置文件的名称 (不包含扩展名)
const configFileName = path.basename(__filename, '.js');
// 提取文件名中的第二个单词并将其转换为 kebab-case
const secondWord = configFileName.split('.')[1]; // 提取文件名中的第二个单词
const caseFileName = secondWord.split('-')[1]
/**
* 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']
console.log(path.join(__dirname, `../../src/renderer/preload/${caseFileName}/main.js`))
let preloadLineConfig = {
// 添加以下一行,设置 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/preload/${caseFileName}/main.js`),
},
externals: [
...Object.keys(dependencies || {}).filter(
(d) => !whiteListedModules.includes(d)
),
],
module: {
rules: [
{
test: /\.js$/,
use: [
{
loader: 'babel-loader',
options: {
cacheDirectory: true
}
},
],
exclude: /node_modules/,
},
{
test: /\.node$/,
use: 'node-loader',
},
],
},
node: {
__dirname: process.env.NODE_ENV !== 'production',
__filename: process.env.NODE_ENV !== 'production',
},
plugins: [
new webpack.NoEmitOnErrorsPlugin(),
],
output: {
filename: '[name].js',
libraryTarget: 'commonjs2',
path: path.join(__dirname, `../../dist/electron/preload`),
},
resolve: {
extensions: ['.js', '.node'],
},
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
parallel: true, // 开启多线程压缩
cache: true,
terserOptions: {
// 在这里添加 Terser 的配置选项
compress: {
drop_console: true, // 例如,移除 console.log
},
},
}),
],
},
target: 'electron-preload',
}
/**
* Adjust preloadLineConfig for development settings
*/
if (process.env.NODE_ENV !== 'production') {
preloadLineConfig.plugins.push(
new webpack.DefinePlugin({
__static: `"${path.join(__dirname, '../../static').replace(/\\/g, '\\\\')}"`,
})
)
}
/**
* Adjust preloadLineConfig for production settings
*/
module.exports = preloadLineConfig
延伸技术
使用 webstorm 的开发者,只要将 node_modules 目录标记为源码,或者从排除中剔除,webstorm 就会自动扫描 node_modules 下的所有源代码,并且提供最好的提示效果
原来没有提示性的代码有了提示性,windows 快捷键 Ctrl+鼠标左键,可以点击这个 Plugin 看源码
可以看到很多 webpack 插件,这些插件用 AI 来解释下:
webpack 插件说明
这些东西虽然不需要记忆,但是的确在以后的打包过程中动态地处理一些东西时非常有用,包括引用路径,引用的资源,甚至定义的不同变量都是能用到的
-
AutomaticPrefetchPlugin: 自动预加载资源,提升加载性能。
-
BannerPlugin: 为打包的文件添加横幅注释。
-
CachePlugin: 控制构建缓存,优化构建速度。
-
ContextExclusionPlugin: 排除不需要的上下文模块,减少打包体积。
-
ContextReplacementPlugin: 替换模块上下文,优化构建和运行时行为。
-
DefinePlugin: 定义全局常量,替换代码中的指定值。
-
Dependency: 处理模块依赖关系。
-
DllPlugin: 提前构建并生成 DLL(动态链接库)文件,提升构建速度。
-
DllReferencePlugin: 引用其他 DLL 文件,优化构建性能。
-
EnvironmentPlugin: 设置环境变量,常用于配置和优化。
-
EvalDevToolModulePlugin: 提供源映射,用于开发模式下调试。
-
EvalSourceMapDevToolPlugin: 提供 eval-based 源映射,优化开发调试。
-
ExtendedAPIPlugin: 扩展 Webpack 的 API 功能。
-
ExternalsPlugin: 将外部库(如 CDN)排除在打包之外,减少打包文件大小。
-
HashedModuleIdsPlugin: 使用模块的哈希值来生成唯一 ID,提升长期缓存效果。
-
HotModuleReplacementPlugin: 支持热模块替换,实时更新应用而无需重新加载页面。
-
IgnorePlugin: 忽略不需要的模块或文件,优化打包。
-
LibraryTemplatePlugin: 用于库的打包,生成适合库的模板。
-
LoaderOptionsPlugin: 为加载器提供选项配置。
-
LoaderTargetPlugin: 设置加载器的目标环境,指定如何处理模块。
-
MemoryOutputFileSystem: 使用内存文件系统,在内存中存储构建文件,提升速度。
-
Module: 处理和加载模块的基本单元。
-
ModuleFilenameHelpers: 帮助工具类,生成模块的文件名。
-
NamedChunksPlugin: 使用模块名称生成输出的 chunk 名称。
-
NamedModulesPlugin: 为模块分配更易于理解的名称,方便调试。
-
NoEmitOnErrorsPlugin: 构建失败时不生成输出文件,避免错误文件的生成。
-
NormalModuleReplacementPlugin: 替换模块的正常流程,允许条件性加载不同模块。
-
PrefetchPlugin: 提前加载指定的模块,提升页面加载性能。
-
ProgressPlugin: 打包过程中显示进度信息。
-
ProvidePlugin: 自动加载某些模块或变量,避免在每个文件中显式引入。
-
SetVarMainTemplatePlugin: 设置入口模板,通常用于自定义构建模板。
-
SingleEntryPlugin: 为单一入口提供插件支持。
-
SourceMapDevToolPlugin: 生成源映射文件,帮助开发调试。
-
Stats: 输出 Webpack 构建过程的统计信息。
-
Template: 模板引擎,用于构建输出内容。
-
UmdMainTemplatePlugin: 生成 UMD(通用模块定义)格式的模板,支持多平台。
-
WatchIgnorePlugin: 在开发过程中,忽略某些文件或目录,避免不必要的重新构建。
补充
目前探索electron-vue这个环境直接升级webpack 5打包,没有成功,后续我将借助AI来从新构建基于node.js 18版本下的webpack5的各种依赖
另外关于electron-vue框架的详细精讲也会录个视频发到B站去