【问题标题】:Electron ES6 module importElectron ES6 模块导入
【发布时间】:2018-12-09 07:40:03
【问题描述】:

电子 3.0.0-beta.1 节点 10.2.0 铬 66.0.3359.181

我遇到的问题是导入模块。我创建了以下协议:

protocol.registerFileProtocol('client', (request, callback) => {
    var url = request.url.substr(8);
    callback({path: path.join(__dirname, url)});
});

协议的输出是正确的路径

"/Users/adviner/Projects/Client/src/ClientsApp/app.js"

我有以下模块 app.js 和以下代码:

export function square() {
    return 'hello';
}

在我的 index.html 中,我像这样导入模块:

    <script type="module" >
        import square from 'client://app.js';
        console.log(square());
    </script>       

但我不断收到错误消息:

app.js/:1 加载模块脚本失败:服务器以非 JavaScript MIME 类型“”响应。根据 HTML 规范对模块脚本强制执行严格的 MIME 类型检查。

我已完成搜索,但似乎找不到解决方案。任何人都可以建议一种方法来完成这项工作吗?

谢谢

【问题讨论】:

标签: electron


【解决方案1】:

这是一个棘手的问题,我将参考 Electron#12011GitHub Gist 进行更深入的解释,但核心学习是相应的 HTML spec,不允许通过 file:// 导入(出于 XSS 原因)和协议必须定义 MIME 类型。

您使用的文件协议client:// 必须在提供文件时设置正确的 mime 类型。目前我猜想当你通过protocol.registerBufferProtocol 定义协议时它们没有设置,因此你收到了The server responded with a non-JavaScript MIME type of "",上面的要点有一个关于如何做到这一点的代码示例。

编辑:我只想强调这里的其他答案只涵盖绝对最低限度的基础实现,不考虑异常、安全性或未来的变化。 我强烈建议您花时间阅读我链接的要点

【讨论】:

  • 非常感谢您提供的信息。它帮助我更多地了解 Electron 并解决了我的问题 :)
【解决方案2】:

确认:这是出于安全原因。

但是,如果您只是需要来部署它:

在您的 tsconfig.json 文件中将 "target": "es2015" 更改为 "target": "es5"

【讨论】:

  • 这是 TypeScript 特有的。
  • @amn 是的 - 可能确实对那些使用 TypeScript 的人有用
【解决方案3】:

快速解决方案:

const { protocol } = require( 'electron' )
const nfs = require( 'fs' )
const npjoin = require( 'path' ).join
const es6Path = npjoin( __dirname, 'www' )

// <= v4.x
// protocol.registerStandardSchemes( [ 'es6' ] )

// >= v5.x
protocol.registerSchemesAsPrivileged([
  { scheme: 'es6', privileges: { standard: true } }
])

app.on( 'ready', () => {
  protocol.registerBufferProtocol( 'es6', ( req, cb ) => {
    nfs.readFile(
      npjoin( es6Path, req.url.replace( 'es6://', '' ) ),
      (e, b) => { cb( { mimeType: 'text/javascript', data: b } ) }
    )
  })
})
&lt;script type="module" src="es6://main.js"&gt;&lt;/script&gt;

【讨论】:

  • 我需要删除“www”加入并添加.replace(/\/$/, ''),但它似乎工作正常,只要记得在导入中包含es6://...
  • 你能更新它以在 5.0 之后工作吗? github.com/electron/electron/blob/master/docs/api/…
  • 有人可以通过registerSchemesAsPrivileged 注册file 来解决这个问题吗?
【解决方案4】:

基于旧 Electron 版本的 flcoder 解决方案。

电子 5.0

const { protocol } = require('electron')
const nfs = require('fs')
const npjoin = require('path').join
const es6Path = npjoin(__dirname, 'www')

protocol.registerSchemesAsPrivileged([{ scheme: 'es6', privileges: { standard: true, secure: true } }])

app.on('ready', async () => {
  protocol.registerBufferProtocol('es6', (req, cb) => {
    nfs.readFile(
      npjoin(es6Path, req.url.replace('es6://', '')),
      (e, b) => { cb({ mimeType: 'text/javascript', data: b }) }
    )
  })
  await createWindow()
})

注意!路径似乎总是转换为小写

<script type="module" src="es6://path/main.js"></script>

抱歉,Viziionary,没有足够的声誉来回答评论。

【讨论】:

    【解决方案5】:

    我现在已经这样做了:

    https://gist.github.com/jogibear9988/3349784b875c7d487bf4f43e3e071612

    我的问题是,我还想支持通过非相对路径导入的模块,所以我不需要转译我的代码。

    【讨论】:

    • 不要在帖子或答案中链接,除非相关代码也在帖子本身中。一旦您的链接失效,答案仍然应该是答案。另外:在您的帖子中解释您的代码。如果没有,这不是一个答案,而是一个评论,应该作为评论发布。
    猜你喜欢
    • 2017-01-04
    • 2022-12-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-24
    • 1970-01-01
    • 2015-08-13
    • 2014-02-06
    相关资源
    最近更新 更多