代码之家  ›  专栏  ›  技术社区  ›  adviner

电子ES6模块导入

  •  5
  • adviner  · 技术社区  · 6 年前

    电子3.0.0-β.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>       
    

    但我一直有个错误:

    js/:1未能加载模块脚本:服务器以非javascript mime类型“”响应。对于每个html规范的模块脚本,强制执行严格的mime类型检查。

    我找遍了,但似乎找不到解决办法。有人能给我建议一个办法吗?

    谢谢

    4 回复  |  直到 6 年前
        1
  •  8
  •   Hans Koch    5 年前

    这是个棘手的问题,我将提及 Electron#12011 还有这个 GitHub Gist 对于更深入的解释,核心的学习是 HTML spec ,不允许通过 file:// (出于xss的原因)和协议必须定义mime类型。

    您使用的文件协议 client:// 提供文件时必须设置正确的mime类型。目前,我猜在您通过 protocol.registerBufferProtocol 所以你得到了 The server responded with a non-JavaScript MIME type of "" ,上面的要点有一个关于如何执行的代码示例。

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

        2
  •  6
  •   rob_james    5 年前

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

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

    改变 "target": "es2015" "target": "es5" 在tsconfig.json文件中

        3
  •  6
  •   InQβ    5 年前

    快速解决方案:

    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 } ) }
        )
      })
    })
    <script type="module" src="es6://main.js"></script>
        4
  •  2
  •   Isti115    5 年前

    基于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>
    

    抱歉,维齐奥林,没有足够的声誉来回答这个评论。

        5
  •  0
  •   marc_s    6 年前

    我现在这样做了:

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

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