Electron-vue 框架升级 Babel7 并支持electron-preload webapck 4 打包过程记录

发布于:2024-12-06 ⋅ 阅读:(21) ⋅ 点赞:(0)

前言

我这边一直用的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 是针对所有环境(mainrendererpreloadweb)统一的。因为这些插件的功能通常是跨环境的(即无论是在浏览器端、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站去


网站公告

今日签到

点亮在社区的每一天
去签到