Quasar electron typescript 模式下自动编译ts为js到 __dirname
背景
在写electron代码时,希望点击按钮通过如下代码打开新的窗口:
import {enable} from '@electron/remote/main';
let childWindow: Window | undefined;
childWindow= new BrowserWindow({
icon: path.resolve(__dirname, 'icons/icon.png'), // tray icon
width: 1000,
height: 600,
useContentSize: true,
frame: false, // <-- no bar on electron
webPreferences: {
sandbox: false, // <-- to be able to import @electron/remote in preload script
contextIsolation: true,
// More info: https://v2.quasar.dev/quasar-cli-vite/developing-electron-apps/electron-preload-script
preload: path.resolve(path.resolve(__dirname,'preload.js')),
},
});
enable(childWindow.webContents) // <-- no bar on electron
childWindow.loadURL(url);
childWindow.webContents.openDevTools();
childWindow.on('closed', () => {
childWindow = undefined;
});
问题是@electron/remote/main 的 enable 操作不能在主窗口执行,不生效,因此需要在preload.js内执行
然而__dirname指向的是根目录下的.quasar/electron,显而易见这里面的代码都是项目启动时自动build出来的
那么我想做的是:
在项目启动时自动编译我各个窗口下的preload.ts为js到.quasar/electron下
编译preload.ts为js到.quasar/electron下
好在查看源码很方便,咱们首先看下quasar是如何做到的:
1 我们在项目启动时可以看到这么一句话:
App • WAIT • Compiling of Electron Main with Esbuild in progress...
2 全局搜索可以看到这样一段代码(app-tool.js):
const done = progress(
'Compiling of ___ with Esbuild in progress...',
threadName
)
const result = await esBuild(cfg)
done('___ compiled with success')
return result
这里便是构建的入口,在debugger模式下可以看到(main.js):
if (outfile)
flags.push(`--outfile=${outfile}`);
if (outdir)
flags.push(`--outdir=${outdir}`);
if (outbase)
flags.push(`--outbase=${outbase}`);
if (tsconfig)
flags.push(`--tsconfig=${tsconfig}`);
其实相当于调用esBuild的命令行将ts转成了js到指定目录
3 于是乎我们只需要模仿着写就ok啦
在quasar.config.js下的electron开启以下钩子函数的回调:
electron: {
...
async extendElectronPreloadConf(esbuildConf) { // 这个方法
console.log(esbuildConf) // 更改这个参数的文件就行了
// 以下仅供参考
const windowData = fs.readdirSync(path.join(__dirname, 'src', 'pages'))
.map((filename) => [
kebabCase(filename),
path.join(__dirname, 'src', 'pages', filename),
])
const preloadEntries = windowData
.filter(([, filepath]) => fs.existsSync(path.join(filepath, 'preload.ts')))
.map(([name, filepath]) => [
`${name}-preload`,
path.join(filepath, 'preload.ts'),
])
const res = preloadEntries.map(([name, filepath]) => [
name,
// 这里可以将相对路径扩展为绝对路径,例如
// src/nested/foo 会变成 /project/src/nested/foo.js
filepath
]
)
res.forEach(([name, filepath]) => {
const buildData = {
...esbuildConf,
entryPoints:[filepath],
outfile: path.join(__dirname, '.quasar', 'electron', name,'preload.js'),
}
esBuild(buildData)
})
const result = await esBuild(buildData) // 执行编译
console.log(result)
}
...
}
运行看下结果
真提莫完美