【发布时间】:2018-02-12 06:40:43
【问题描述】:
我正在尝试使用 Webpack,因为我想在我的 Electron 应用程序中使用 ES 模块,但遇到了一些障碍。我只想在我的main 和renderer 进程中使用import。
我的应用结构如下-
- src/ // contains basic html, css & js
- index.html // <h1>Hello World</h1>
- style.css // is empty
- app.js // console.log('it works ????')
- app/ // contains electron code
- main_window.js
- custom_tray.js
- index.js // entry point for electron application
- dist/ // output bundle generated from webpack
- bundle.js
我的index.js 文件看起来像 -
import path from "path";
import { app } from "electron";
import MainWindow from "./app/main_window";
import CustomTray from "./app/custom_tray";
let win = null,
tray = null;
app.on("ready", () => {
// app.dock.hide();
win = new MainWindow(path.join("file://", __dirname, "/src/index.html"));
win.on("closed", () => {
win = null;
});
tray = new CustomTray(win);
});
我的main_window.js 文件看起来像 -
import { BrowserWindow } from "electron";
const config = {
width: 250,
height: 350,
show: false,
frame: false,
radii: [500, 500, 500, 500],
resizable: false,
fullscreenable: false
};
class MainWindow extends BrowserWindow {
constructor(url) {
super(config);
this.loadURL(url);
this.on("blur", this.onBlur);
this.show();
}
onBlur = () => {
this.hide();
};
}
export default MainWindow;
我的custom_tray.js 看起来像 -
import path from "path";
import { app, Tray, Menu } from "electron";
const iconPath = path.join(__dirname, "../src/assets/iconTemplate.png");
class CustomTray extends Tray {
constructor(mainWindow) {
super(iconPath);
this.mainWindow = mainWindow;
this.setToolTip("Thirsty");
this.on("click", this.onClick);
this.on("right-click", this.onRightClick);
}
onClick = (event, bounds) => {
const { x, y } = bounds;
const { width, height } = this.mainWindow.getBounds();
const isMac = process.platform === "darwin";
if (this.mainWindow.isVisible()) {
this.mainWindow.hide();
} else {
this.mainWindow.setBounds({
x: x - width / 2,
y: isMac ? y : y - height,
width,
height
});
this.mainWindow.show();
}
};
onRightClick = () => {
const menuConfig = Menu.buildFromTemplate([
{
label: "Quit",
click: () => app.quit()
}
]);
this.popUpContextMenu(menuConfig);
};
}
export default CustomTray;
而我的webpack.main.config.js 看起来像 -
const path = require("path");
const config = {
entry: "./index.js",
output: {
path: path.resolve(__dirname, "dist"),
filename: "bundle.js"
},
module: {
rules: [{ test: /\.js$/, exclude: /node_modules/, use: "babel-loader" }]
},
stats: {
colors: true
},
target: "electron-main",
devtool: "source-map"
};
module.exports = config;
我的webpack.renderer.config.js 看起来像 -
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const CopyWebpackPlugin = require("copy-webpack-plugin");
const config = {
entry: "./src/app.js",
output: {
path: path.resolve(__dirname, "dist/renderer"),
filename: "app.js"
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: "babel-loader"
},
{
test: /\.css$/,
use: {
loader: "css-loader",
options: {
minimize: true
}
}
},
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
use: {
loader: "url-loader",
query: {
limit: 10000,
name: "imgs/[name].[ext]"
}
}
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
use: {
loader: "url-loader",
query: {
limit: 10000,
name: "fonts/[name].[ext]"
}
}
}
]
},
stats: {
colors: true
},
target: "electron-renderer",
devtool: "source-map",
plugins: [
new CopyWebpackPlugin([
{ from: "src/app.css" },
{ from: "src/assets", to: "assets/" }
]),
new HtmlWebpackPlugin({
filename: "index.html",
template: path.resolve(__dirname, "./src/index.html"),
minify: {
collapseWhitespace: true,
removeAttributeQuotes: true,
removeComments: true
}
})
]
};
module.exports = config;
我在 package.json 中的 scripts 看起来像
"scripts": {
"dev:main": "webpack --mode development --config webpack.main.config.js",
"dev:renderer": "webpack --mode development --config webpack.renderer.config.js",
"dev:all": "npm run dev:main && npm run dev:renderer",
"build:main": "webpack --mode production --config webpack.main.config.js",
"build:renderer": "webpack --mode production --config webpack.renderer.config.js",
"build:all": "npm run build:main && npm run build:renderer",
"prestart": "npm run build:all",
"electron": "electron dist/index.js",
"start": "npm run electron",
}
目前我的应用程序创建了一个 dist/bundle.js,但是当我运行 electron dist/bundle.js 时它不起作用。我明白了,可能是因为它不包含 src 文件夹,但是当我将 src 文件夹复制到 dist 时,它仍然不起作用。
首先,我运行npm run dev:main 来生成dist/bundle.js,然后我运行npm run dev:renderer 来生成dist/renderer/bundle.js,然后我运行npm run start 来启动我的电子应用程序。
它给了我错误“未捕获的异常:错误:需要在新的 MainWindow 处调用构造函数”,它位于 index.js 中,我在其中调用构造函数 new MainWindow()
我只想在我所有的 JS 文件中使用 ES6。是否有任何样板文件,因为我发现的样板文件有大量额外的东西,比如 React JS 以及大量的优化?
【问题讨论】:
-
我实际上从未见过有人像你这样设置他们的 webpack.config 文件,尤其是模块部分。您是否尝试过使您的配置像 es6 docs 中的配置一样,特别是让模块对象包含一组加载器。另外,如果这不起作用,您能否发布正在输出的任何错误?
-
我也从未使用过 Electron,但是当我将 es6 与 knockout.js 框架一起使用时,我有必要将淘汰赛排除在解析之外。你可以看看我是如何制作我的 webpack.config here 的,也许会有所帮助。
-
您能解释一下您实际收到的错误是什么吗?你期望什么行为?你只是说“它不起作用”。另外,请注意手动复制
src -> dist永远不会起作用,因为 Webpack 必须捆绑您的代码才能执行它。 Webpack 不是一个模块加载器,它是一个模块捆绑器。 -
@stephenagwu 我正在使用 Webpack 4,所以它就是这样使用的。构建 Webpack 时没有错误。当我运行提供
new MainWindow is not a constructor的 Electron 应用程序时出现错误。问题实际上是 Electron 和 Webpack 的结合。我分别知道 Electron 和 Webpack,但结合起来我在过去 2 天里找不到任何东西。首先我运行npm run dev以生成dist/bundle.js然后我运行npm start但随后它在Electron 应用程序中引发错误。它给出了上述错误。 -
@AluanHaddad 我刚刚编辑了这个问题。目前,我正在尝试各种方法,为主要和渲染器进程制作 2 个捆绑文件并将其应用到我的
src/目录中。另外,我将尝试使用CopyWebpackPlugin将html 文件从src/目录复制到dist/目录。我将继续编辑问题。我从过去 2 天开始尝试这个,但没有运气。它只适用于require(),但最终我很想使用这个设置
标签: javascript webpack electron webpack-2