我正在使用Webpack 2和Electron在Mac上构建nodejs应用程序。
在根目录中的项目中,我有目录'数据'我将配置存储在json中的数据/配置/ files.json(实际上有不同的动态名称文件)
在我打电话给webpacka之后:fs.readdirSync(remote.app.getAppPath());
来获取根目录中的文件我只得到这些包装:[ "default_app.js", "icon.png", "index.html", "main.js", "package.json", "renderer.js" ]
path.join(remote.app.getAppPath(), 'data/tests/groups.json');
会导致问题Error: ENOENT, data/tests/groups.json not found in /Users/myuser/myproject/node_modules/electron/dist/Electron.app/Contents/Resources/default_app.asar
。所以似乎webpacker没有拿起整个数据文件夹。
Webpack配置正在使用json-loader
,我没有找到任何文档提及包含特定文件或jsons的任何特殊内容。或者我必须以不同方式引用代码中的json文件,因为它们可能包含在main.js下。
Electron / Webpack管理JSON配置文件的最佳做法是什么?在webpacking项目时我做错了吗?
我的项目基于https://github.com/SimulatedGREG/electron-vue使用webpack / electron / vue
答案 0 :(得分:14)
首先要了解的一点是,webpack
不会捆绑通过fs
或其他要求提供文件路径的模块所需的文件。这些类型的资产通常标记为静态资产,因为它们不以任何方式捆绑在一起。 webpack
只会捆绑require
d或import
ed(ES6)的文件。此外,根据您的webpack
配置,您的项目根目录可能并不总是与生产版本中的输出相匹配。
根据电子视频文档的项目结构/文件树,您会发现只有webpack
个包和static/
目录可用于生产建设。 electron-vue还有一个方便的__static
全局变量,可以在开发和生成中提供到static/
文件夹的路径。您可以使用此变量,类似于__dirname
和path.join
访问您的JSON文件或实际上任何文件的方式。
似乎electron-vue样板的当前版本已经为您解决了这个问题,但我将描述如何使用webpack
进行设置,因为它不仅适用于JSON文件及其如何应用于任何webpack
+ electron
设置。以下解决方案假设您的webpack
构建输出到单独的文件夹,在这种情况下我们将使用dist/
,假设您的webpack
配置位于您的项目中根目录,并假设process.env.NODE_ENV
在开发期间设置为development
。
static/
目录在开发过程中,我们需要一个存储静态资源的地方,所以我们将它们放在一个名为static/
的目录中。在这里,我们可以放置我们知道需要使用fs
或其他需要文件完整路径的模块的文件,例如JSON。
现在我们需要在生产版本中提供static/
资产目录。
但是
webpack
根本没有处理这个文件夹,我们能做什么?
让我们使用简单的copy-webpack-plugin
。在我们的webpack
配置文件中,我们可以在构建 for production 时添加此插件,并将其配置为将static/
文件夹复制到我们的dist/
文件夹中。
new CopyWebpackPlugin([
{
from: path.join(__dirname, '/static'),
to: path.join(__dirname, '/dist/static'),
ignore: ['.*']
}
])
好的,资产正在生产中,但如何在开发和生产中获得此文件夹的路径?
__static
变量制作此
__static
变量的重点是什么?
在__dirname
+ webpack
设置中使用electron
并不可靠。在开发期间,__dirname
可以引用src/
文件中存在的目录。在制作中,由于webpack
将我们的src/
文件捆绑到一个脚本中,因此您形成的static/
形成的路径不再存在。此外,您放在src/
内但未require
或import
的文件永远不会进入您的生产版本。
在处理项目结构与开发和生产的差异时,尝试获取static/
的路径会在开发期间非常烦人,必须始终检查您的process.env.NODE_ENV
。
使用webpack.DefinePlugin
我们只能在开发中设置__static
变量 ,以产生指向<projectRoot>/static/
的路径。如果您有多个webpack
配置,则可以将其应用于main
和renderer
流程配置。
new webpack.DefinePlugin({
'__static': `"${path.join(__dirname, '/static').replace(/\\/g, '\\\\')}"`
})
在制作中,我们需要在代码中手动设置__static
变量。这是我们能做的......
index.html (renderer
流程)
<!-- Set `__static` path to static files in production -->
<script>
if (process.env.NODE_ENV !== 'development') window.__static = require('path').join(__dirname, '/static').replace(/\\/g, '\\\\')
</script>
<!-- import webpack bundle -->
main.js (main
进程)
// Set `__static` path to static files in production
if (process.env.NODE_ENV !== 'development') {
global.__static = require('path').join(__dirname, '/static').replace(/\\/g, '\\\\')
}
// rest of application code below
__static
变量假设我们有一个简单的JSON文件,我们需要使用fs
阅读,这是我们现在可以完成的...
<强> static/someFile.json
强>
{"foo":"bar"}
someScript.js
(renderer
或main
流程)
import fs from 'fs'
import path from 'path'
const someFile = fs.readFileSync(path.join(__static, '/someFile.json'), 'utf8')
console.log(JSON.parse(someFile))
// => { foo: bar }
webpack
用于将require
或import
的资产捆绑在一起。使用fs
或其他需要文件路径的模块引用的资产被视为静态资产,而webpack
不会直接处理这些资产。使用copy-webpack-plugin
和webpack.DefinePlugin
,我们可以设置一个可靠的__static
变量,在开发和生产过程中生成static/
资产目录的路径。
最后,我个人还没有看到任何其他webpack
+ electron
样板处理这种情况,因为它不是很常见的情况,但我想我们都同意将一个事实来源提供给静态资产目录是缓解开发人员疲劳的一种很好的方法。
答案 1 :(得分:2)
我认为混淆(如果有的话)可能来自这样一个事实,即webpack不仅包装&#34;包装,内容,代码等......而且还可以通过其插件处理内容。
html插件就是一个很好的例子,因为它只是在构建时生成一个html文件。
这与配置文件问题有什么关系? 很好地取决于你是如何&#34;要求&#34; &#34; config&#34;文件,您用于处理该内容的插件。
您可以从文件系统或http中嵌入它,或者只是将其作为文本加载,否则......
对于配置文件,我想你希望它在运行时被解析,
否则它只是花哨的硬编码值,或许你可以更好地简单地在源代码中输入它作为简单的对象。
在这种情况下,我认为webpack对运行时需求几乎没有任何影响,因为在以后的使用中没有任何预先打包的内容,
所以我可能会改为或者&#34;要求&#34;它,我会从文件系统中读取它,例如:
// read it parse it relative to appPath/cwd,
const config = JSON.parse(
fs.readfileSync(
path.join( app.getAppPath(), "config.json" ),
"utf-8"
))
//note: look fs-extra, it does all that minus the app.path plus async
并且电子将从文件系统读取它,或者如果使用Electron.require将从asar | fileSystem读取它(如果我没记错的话,按顺序,我可能是错的),
答案 2 :(得分:1)
Webpack设计理念围绕着非常简单但强大的概念:
转换并捆绑应用实际使用的所有内容。
为了实现该webpack引入了一个强大的依赖图概念,它可以通过所谓的加载器来管理几乎任何类型的依赖(不仅仅是* .js模块)。
加载器的目的是以一种使语句import smth from 'your_dependency'
有意义的方式转换您的依赖项。例如,json-loader
在加载* .json文件期间调用JSON.parse(...)
并返回配置对象。因此,为了利用webpack依赖解析系统来管理JSON,请从安装json-loader
开始:
$ npm install --save-dev json-loader
然后按以下方式修改webpack.config.js
:
module.exports = {
...
module: {
rules: [
{test: /\.json$/, use: 'json-loader'}
]
}
...
};
此时webpack应该能够通过其绝对路径解析您的JSON依赖关系,因此以下内容应该可行(我假设您的根上下文目录的子目录config
包含文件{{1 }}):
sample.json
但是导入物理路径不会产生优雅,强大和可维护的代码(例如,考虑可测试性),因此将{@ 1}}中的别名添加为摘要物理被认为是一种很好的做法{导入语句中的{1}}文件夹
import sampleCfg from './config/sample.json';
然后你就可以像这样导入你的JSON配置:
webpack.config.js
最后,如果你使用.config/
Electron项目模板(正如你在帖子中提到的那样),那么你有三个webpack配置文件:
module.exports = {
...
resolve: {
alias: {
cfg: './config'
}
}
...
}
- 如果您仅将此模板用于普通Web开发(即不用于构建本机Electron项目),请使用此配置文件;
import sampleCfg from 'cfg/sample.json'
- 使用此文件配置将在Electron主要流程中运行的webpack模块;
SimulatedGREG/electron-vue
- 将此文件用于Electron的渲染器处理。
您可以在official Electron documentation中找到有关主要和渲染器进程的更多信息。