在 Electron 应用程序中使用 require(lib) 与 <script>
Posted
技术标签:
【中文标题】在 Electron 应用程序中使用 require(lib) 与 <script>【英文标题】:Use of require(lib) versus <script> in Electron apps 【发布时间】:2016-10-10 17:57:51 【问题描述】:我不知道何时在 Electron 内容页面(例如 index.html)中使用 require('jslib')
和 <script src=""></script>
。使用jQuery,我发现需要按如下方式加载:
<script>window.$ = window.jQuery = require('./js/jquery-2.2.4.min.js');</script>
我需要开始使用其他一些库(例如 Handlebars、ds3.js、Bootstrap 等),我不确定是否应该使用 <script>
标记加载这些库,或者是否应该使用 require
它们。
【问题讨论】:
这完全取决于库。如果库可以通过 CommonJS (module.exports = ...
) 公开,那么您将不得不 require
它。否则,一个简单的<script src="..."></script>
就可以了。
@MikeC 即使 JS 脚本文件不使用 CommonJS,require
似乎也可以工作。这是否意味着我通常可以使用require
代替<script src="..."></script>
?尽管我问了这个问题,但我认为我应该查看 JS 文件以确定何时使用其中一个。
一般来说,你可以侥幸逃脱,是的。
@MikeCluck 为什么你说你必须要求它如果它是通过CommonJS公开的? <script src="..."></script>
不应该仍然有效吗?那么require
怎么能正常工作呢?这个问题值得回答……
【参考方案1】:
一些库仅通过 CommonJS 接口公开其变量。其他的,比如 jQuery,也会将它们暴露为全局变量。
您不能只为仅通过 CommonJS 公开的库执行 <script src="..."></script>
的原因是它不会绑定到全局空间。
与 CommonJS 绑定
module.exports = myLibrary;
绑定到全局范围
window.myLibrary = myLibrary;
如果一个库只做前者,那么您将无法在不使用require
的情况下访问该值。如果图书馆只做后者,那么您将不能够在const myLibrary = require('my-library')
的意义上使用require
访问它
一般来说,在全局变量上使用 CommonJS 是一个更好的主意。将变量添加到全局范围可能会导致名称冲突,并且直接加载依赖项可以让下一个人更容易判断该依赖项的来源。更不用说,CommonJS 允许静态分析工具更好地工作,因此您更有可能获得相关的代码完成和类型定义。
使用jQuery的例子,这样使用会更好。
// main.js
const $ = require('./js/jquery-2.2.4.min.js');
// could also be done like this if you install it as a Node dependency
// const $ = require('jquery');
$(document).ready(...);
<!-- index.html -->
...
<script src="main.js"></script>
TL;DR
尽可能使用require('my-library')
,如果不是,则将它们作为全局变量加载。
【讨论】:
这是一篇很棒的帖子,但我认为它没有解决房间里的大象问题,这就是为什么require
在 Electron 应用程序中完全可用?在任何普通的 Web 应用程序中,require
不存在,必须使用模块加载器/捆绑器来填充。在 Electron 应用程序中,您可以轻松使用本机 require
。
@customcommander 我不认为这是一头大象,因为所有 Electron 文档都表明它可以让您以与 Node 相同的方式访问模块,即通过 CommonJS 格式。
好吧,你可能是对的。我只是认为值得一提,因为这个问题特别提到了电子上下文。谢谢你的澄清。【参考方案2】:
在模块捆绑器之前,库必须通过<script>
标签或模块加载器(例如RequireJS)导入。
现在更容易假设 CommonJS 环境并通过模块捆绑器获取所有内容,该模块捆绑器将在浏览器上下文中为您公开 require
函数。
在 Electron 应用程序的上下文中,所有这些都不是必需的:
在普通浏览器中,网页通常在沙盒环境中运行,并且不允许访问本机资源。但是,Electron 用户可以在网页中使用 Node.js API,从而实现较低级别的操作系统交互。
参见。 renderer process
这意味着原生 Node.js require
函数(除其他外)在您的渲染器进程中可用!
这是一个简单的 Electron 应用程序来证明这一点:
我的package.json
:
"name": "foobar",
"version": "1.0.0",
"main": "main.js",
"scripts":
"start": "electron ."
,
"devDependencies":
"electron": "^3.0.7"
,
"dependencies":
"the-answer": "^1.0.0"
我的main.js
:(主进程)
const app, BrowserWindow = require('electron');
let mainWindow;
function createWindow ()
mainWindow = new BrowserWindow(width: 800, height: 600)
mainWindow.loadFile('index.html');
app.on('ready', createWindow);
我的index.html
:(渲染器进程)
<!DOCTYPE html>
<html>
<body>
<script>
const os = require('os'); // Standard Node.js module
const answer= require('the-answer'); // An NPM package that returns the answer to everything.
</script>
<button onclick="alert(os.platform())">YOUR PLATFORM</button>
<button onclick="alert(answer)">THE ANSWER</button>
</body>
</html>
那么你应该使用哪种方法呢?
Electron 公开了原生 Node.js require
函数。不利用这一点将是一种耻辱:您可以按名称要求包,并将您的代码拆分为可重用的模块,就像在任何 Node.js 应用程序中所做的那样。
【讨论】:
这并不能解释为什么他们会在脚本标签上使用require
,反之亦然。
公平。我提供了一些额外的信息。但是考虑到 OP 提到了 Electron,实际上很重要的是要提到本机 require
函数可用,并且某些模块加载器或捆绑器没有提供它。
进一步编辑此内容以阐明我对使用哪些方法的立场。以上是关于在 Electron 应用程序中使用 require(lib) 与 <script>的主要内容,如果未能解决你的问题,请参考以下文章
将 node require 与 Electron 和 Webpack 一起使用
electron 中renderer.js中使用require('electron') 报错require is not defined
来自 Electron 渲染器进程的 require() 节点模块,通过 HTTP 提供服务
require 没有在带有 ipcRenderer.on 的 Electron-React-Webpack-Typescript 应用程序中定义