Electron: webpacking main.js 后不允许加载本地资源:file://index.html/

创建于 2016-04-10  ·  31评论  ·  资料来源: electron/electron

我正在尝试将所有 main.js 脚本及其依赖项打包到一个文件中(我想为 UI 应用程序提供一个文件,为服务器应用程序提供一个文件)。

如果我使用正常的源, index.html 加载就好了。 但是,当 webpacking 时,我得到了标题中提到的错误。

这是我使用的 webpack 配置:

webpack({
    entry: [
        './main'
    ],
    output: {
        path: path.join(__dirname, 'asar'),
        filename: 'main.js',
        libraryTarget: 'commonjs2'
    },
    externals: ['electron'],
    target: 'node'
});

我像这样加载文件:
mainWindow.loadURL('file://' + __dirname + '/index.html');

我认为这可能是由于 webpack 调用/评估允许提供本地文件的电子上下文之外的东西。

有什么想法/建议吗? 谢谢!

  • 电子版:0.37.2
  • 操作系统:Windows 10 家庭版

最有用的评论

通过谷歌向这里的人提供信息:如果文件不存在,你会得到同样的错误。 我忘了告诉 electron-packager 将目标文件复制到应用程序中。 从我愚蠢的错误中学习:)

所有31条评论

您可以尝试在webPreferences of BrowserWindow中关闭webSecurity #$ 。 对于更多问题,我建议向社区寻求帮助。

@MihaiValentin嘿,您找到解决方案了吗?

@MihaiValentin @singhshashi我有同样的问题。 默认情况下,webpack 似乎会尝试“模拟” Node 全局变量,例如__dirname 。 我用node.__dirname选项禁用了这种行为,并且……它起作用了!

以防万一,我还将webpack-target-electron-renderer用于target选项。

这是我到目前为止的配置。 我希望它有帮助:

var webpack = require('webpack');
var path = require('path');
var webpackTargetElectronRenderer = require('webpack-target-electron-renderer');

var BUILD_DIR = path.resolve(__dirname, 'build');
var APP_DIR = path.resolve(__dirname, 'src');

var config = {
  entry: APP_DIR + '/index.js',
  output: {
    path: BUILD_DIR,
    filename: 'index.js'
  },
  node: {
    __dirname: false,
    __filename: false
  },
  module : {
    loaders : [
      {
        test : /\.jsx?/,
        include : APP_DIR,
        exclude: /node_modules/,
        loader : 'babel'
      }
    ]
  }
};

config.target = webpackTargetElectronRenderer(config);

module.exports = config;

@eiriarte感谢分享,但是没有用。 如果我使用 webpack 打包主进程的文件,即使使用您所说的节点配置,我仍然会收到相同的错误。

我正在分享一个解决方法,我用来解决这个问题的其他人登陆这个线程。

而不是使用需要 babel 转换它们以在主中正常工作的 es 功能。 js 文件,我将它们分成不同的文件。 在我的 main.js 中,我不使用任何需要 babel 转译的功能。 所以我使用require而不是import。 对于使用 es7 提案功能(例如异步)的代码,我将该代码移动到不同的文件中,位于名为 desktopServices 的文件夹中(您可以想出一个更好的名称)。 我现在运行 webpack 来为 desktopServices 创建一个包,并在 main.js 中引用这个包。

const myshell = require('./dist/desktopServices').myShell ;

我的 webpack.config.main.js 文件包含以下配置。

let config = {
  target:'electron',
  entry:'./desktopServices/desktopServices.js',
  output:{
    path:path.resolve(__dirname, 'dist'),
    filename: 'desktopServices.js',
    publicPath:'/dist/',
    libraryTarget:'commonjs2'
  },
  resolve: {
    extensions:["",".js",".json"]
  },
  module: {
    noParse: /node_modules\/json-schema\/lib\/validate\.js/,
    loaders:[{
      test: /\.js?$/,
      exclude: /node_modules/,
      loader: 'babel-loader'
    },
      {
        test: /\.json/,
        loader: 'json-loader',
      },
    ],
  },
}

module.exports = config;

不是最干净的方法,但我想这是我暂时要走的路线,直到我想使用的一些 es 功能被合并到节点中并且不需要 babel 转译。

对我来说,事实证明这是一个误导性错误。 我收到not allowed to load local resource错误是因为 webpack 在我尝试加载文件之前还没有完成写入文件,而不是因为它的权限错误。

我~固定~用setTimeout (javascript 的胶带)把它包起来,这样我就可以继续生活了:

setTimeout(() => {
  win.loadURL(`file:///${__dirname}/index.html`);
}, 2000); // 1 second wasn't enough lol

对我来说..原因是因为webpack输出包的路径..遥不可及...我通过返回几个目录并按照上面的建议应用节点配置来解决它..完美地工作:D

pathname: path.join(__dirname, '../../source/resources/views', 'index.html');

node: {
    __dirname: false,
    __filename: false
  },

通过谷歌向这里的人提供信息:如果文件不存在,你会得到同样的错误。 我忘了告诉 electron-packager 将目标文件复制到应用程序中。 从我愚蠢的错误中学习:)

供将来参考(因为我已经多次搜索此页面),以下是当前可能存在的问题:

  1. 该文件不存在,或者您的 Node 应用程序无法访问它。 确保electron-packager正在将目标文件复制到应用程序中!

  2. 创建BrowserWindow() webPreferences webSecurity #$ :

{
  webPreferences: {
    webSecurity: false
  }
}
  1. 默认情况下,Webpack 似乎尝试“模拟”像node.__dirname这样的节点全局变量,您可以通过在配置中添加以下内容来禁用它:
  node: {
    __dirname: false
  }
  1. 您可以使用setTimeout() (不推荐)或等待从应用程序发送的ready事件(更好)延迟加载 URL 的执行。
setTimeout(() => {
  win.loadURL(`file:///${__dirname}/index.html`);
}, 2000); // 1 second wasn't enough lol
app.on('ready', () => {
  win.loadURL(`file:///${__dirname}/index.html`);
})

对我来说,解决方案是

  1. 禁用网络安全。
  2. 当试图连接文件时,我在做 __dirname+"./FileName"。 所以它正在创建'C:/Folder./FileName'。 所以应该没有“./”而只有“/”。 这不是开发中的问题,直到我添加了 ASAR。
  3. 它遵循文件名的严格大小写。 我在添加 asar 后遇到了这个问题,直到那时它在开发和生产中都可以完美运行。

希望这可以帮助像我这样的人。

我正在为 webpack 开发服务器的主浏览器窗口加载http://localhost:8080/ (所以我可以重新加载热模块)。 问题是在 <iframe> 上使用<iframe> file://协议加载时,它不起作用。

正如@popey456963所指出的,我只是禁用了网络安全。

我有两种 webpack 配置,分别用于electron-mainelectron-renderer

const path = require('path');
const config_main = {
  target: 'electron-main',
  entry: path.resolve(__dirname, 'src/main/index.js'),
  output: {
    path    : path.resolve(__dirname, 'static'),
    filename: 'main.js'
  },
  externals: [{ 'electron-store': 'require("electron-store")' }],
  resolve: {
    alias: {
      main   : path.resolve(__dirname, 'src/main/'),
      common : path.resolve(__dirname, 'src/common/')
    }
  }
};

const config_renderer = {
  target: 'electron-renderer',
  entry: path.resolve(__dirname, 'src/renderer/index.js'),
  output: {
    path    : path.resolve(__dirname, 'static'),
    filename: 'renderer.js'
  },
  externals: [{ 'electron-store': 'require("electron-store")' }],
  resolve: {
    alias: {
      components : path.resolve(__dirname, 'src/renderer/components/'),
      core       : path.resolve(__dirname, 'src/renderer/core/'),
      states     : path.resolve(__dirname, 'src/renderer/states/'),
      ui         : path.resolve(__dirname, 'src/renderer/ui/'),
      common     : path.resolve(__dirname, 'src/common/'),
    }
  }
};

module.exports = [
  config_main,
  config_renderer
];

我试过申请

  node: {
    __dirname: false
  },

我已经在我的renderer.js__dirname中进行了控制台,在这两种情况下,如果我将 __dirname 设置为 false 或 true,它们都会打印出/

当然,如果我手动输入绝对网址,它可以工作,但不确定为什么__dirname拒绝提供正确的路径。

注意事项

webpackTargetElectronRenderer与目标相同: electron-main

我相信在某些时候electron-main被卷入 webpack 使得webpackTargetElectronRenderer过时了

在这里你可以看到electron-main做了什么
https://github.com/webpack/webpack/blob/master/lib/WebpackOptionsApply.js#L70 -L185

在这里你可以看到完全相同的代码。
https://github.com/chentsulin/webpack-target-electron-renderer/blob/master/index.js

原来我有

  node: {
    __dirname: false
  },

在我的渲染器配置而不是我的主配置中。 如果有人喜欢我的配置文件,我会保留我的评论。

如果我不使用 webpack 怎么办?

@hbgdPro尝试https://github.com/electron/electron/issues/5107#issuecomment -299971806 中的一些选项,1、2 和 4 都不需要 webpack。

@popey456963谢谢。 在我问之前我已经尝试过了。 我的问题实际上是我必须指定我需要在构建过程中包含哪些文件夹。 它与 webpack 无关。

我自己也遇到过这个,(嗨,我来自 webpack 团队)。 我们在 webpack 中有一个 electron-main 目标,我不知道__dirname__filename模拟破坏了默认的快速启动示例。

只是为了确保,电子团队。 这是禁用此功能的官方建议吗? 如果是这样,我将继续为我们拥有的电子主要目标 PR 我们的默认值,以便这些内置函数不会被模拟。

谢谢!

@TheLarkInn __dirname__filename对于大多数电子应用程序来说非常重要,因为它们用于查找要在渲染器进程中显示的 HTML 文件的路径。 嘲笑他们最/总是破坏事情。 不嘲笑他们会解决很多人的问题👍

对于那些不使用 Webpack 的人,我偶然发现了一个奇怪的解决方案,我希望有更多经验的人可以详细说明。 我正在使用以下内容并收到整个线程中提到的错误。

win.loadURL('file://${__dirname}/renderer/main.html')

将上述代码切换为以下代码后,错误消失了,html 将呈现。

win.loadURL('file://' + __dirname + '/renderer/main.html')

似乎由于某种原因,原始文件提供了不正确的 html 文件路径,有人知道为什么吗?

@s-lawrence 不正确的路径是由于:

win.loadURL('file://${__dirname}/renderer/main.html')

应该

win.loadURL(`file://${__dirname}/renderer/main.html`)

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals

啊,好吧,这是有道理的。 感谢@milewski 对此进行详细说明并提供参考。

我通常坚持使用连接,但现在我知道了正确的语法,我将开始更多地使用模板文字,它们看起来更清晰。

@milewski ,我看不出你的两个片段有什么不同。 第二个应该和第一个不同吗?

@jakehockey10第二个有反引号而不是单引号。 反引号表示它是一个模板文字,而不仅仅是一个字符串文字。 第一个示例是常规字符串文字,因此${__dirname}部分永远不会被__dirname值替换。 如果您的编辑器没有以不同的方式突出显示它们,有时很难注意到它们(不幸的是,GFM 语法突出显示不区分它们)。

啊,明白了。 在 GitHub 的 Markdown 中查看它时我没有注意到这种差异,但我使用 Visual Studio Code 并且肯定会注意到你提到的差异。 抱歉误报;-)

只是想补充一下,由于我自己的错误(上限敏感性),我也遇到了这个错误
当文件名全部为小写时,我正在调用pathname: path.join(__dirname, 'Views/settingsWindow.html')

这只在 webpacked 后才导致错误。

我尝试了一些解决方案,但无法让它工作(使用 [email protected][email protected])。
我在一个帖子中找到了最好的解决方案,只有 3 票 SO:原来不需要这个包!
https://stackoverflow.com/questions/45041364/angular-electron-webpack-live-reloading

零配置麻烦的解决方案:
-npm 卸载电子重新加载
- 在一个终端运行 ng serve
-in main.js 更改 win.loadURL( http://localhost:4200/index.html );
- 然后在另一个终端运行 npm run electron

它只是工作

我一整天都试图解决这个问题,最后这个家伙的解决方案奏效了
https://github.com/electron-userland/electron-builder/issues/2955#issuecomment -393524832

在 package.json 中定义“build”属性时,只需添加所需文件,如下所示:

    "files": [
      "./build/**/*",
      "./index.html",
      "./src/*.js"
    ],

然后电子生成器将正确打包它。

原来,'file://' 前缀是 loadUrl 方法所需要的。
有:
win.loadUrl(path.join(__dirname, "./index.html"))
替换为:
win.loadUrl(path.join("file://",__dirname, "./index.html"))

Webpack 让我在 html 条目的 URL 中混合正斜杠和反斜杠感到困惑,所以我使用节点的urlpath来使其工作:

const winURL = process.env.NODE_ENV === 'development'
  ? 'http://localhost:9080'
  : url.format({
    protocol: 'file',
    pathname: path.join(__dirname, 'index.html'),
  });

这是一场灾难,我卡在CRA +电子😂,在dev模式下运行还可以,但是打包成windows exe根本不起作用。

我得到了它。 🤣 如果你使用 CRA 和 react-router,你应该使用 HashRouter,而不是 BrowerRouter。 完毕!!! 😂参考https://github.com/electron-userland/electron-builder/issues/2167

此页面是否有帮助?
0 / 5 - 0 等级