电子ES6模块导入

adv*_*ner 10 electron

电子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)});
});
Run Code Online (Sandbox Code Playgroud)

协议的输出是正确的路径

"/Users/adviner/Projects/Client/src/ClientsApp/app.js"
Run Code Online (Sandbox Code Playgroud)

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

export function square() {
    return 'hello';
}
Run Code Online (Sandbox Code Playgroud)

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

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

但我不断收到错误:

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

我已经完成搜索,但似乎找不到解决方案。谁能建议我可以做这项工作的方法?

谢谢

Han*_*och 8

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

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

编辑:我只想强调其他答案,这里只涉及绝对最低限度的基本实现,不考虑异常,安全性或将来的更改。我强烈建议您花时间阅读我所链接的要点


rob*_*mes 7

确认:出于安全原因,此处存在。

但是,如果您只需要进行部署:

更改"target": "es2015""target": "es5"tsconfig.json文件

  • 这是 TypeScript 特有的。 (2认同)

flc*_*der 6

快速解决方案:

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 } ) }
    )
  })
})
Run Code Online (Sandbox Code Playgroud)
<script type="module" src="es6://main.js"></script>
Run Code Online (Sandbox Code Playgroud)