webpack - Electron+Webpack = 找不到模块 : Error: Can't resolve fsevents/fs/etc in chokidar/etc

标签 webpack electron

我正在尝试创建一个 Electron 应用程序,但许多节点库导致 Module not found错误,即使是 electron-main目标。

webpack.config.js

const path = require('path')

module.exports = {
  mode: 'development',
  target: `electron-main`,
  entry: {main: `./src/main.js`},
  resolve: {
    extensions: ['.js'],
    modules: ['node_modules', path.join(__dirname, 'src')],
  },
  output: {
    path: path.resolve(__dirname, `dist`),
    filename: '[name].bundle.js',
  },
}

src/main.js
const watcher = require('chokidar').watch('./dist')

watcher.on('change', function() {
  console.log('change', arguments)
})

package.json
{
  "name": "test",
  "version": "1.0.0",
  "author": "I",
  "private": true,
  "main": "dist/main.bundle.js",
  "scripts": {
    "build": "webpack"
  },
  "devDependencies": {
    "@types/chokidar": "^1.7.5",
    "chokidar": "^2.0.4",
    "electron": "^2.0.8",
    "webpack": "^4.17.1",
    "webpack-cli": "^3.1.0"
  }
}

这会在 build 期间产生错误:
WARNING in ./node_modules/chokidar/lib/fsevents-handler.js
Module not found: Error: Can't resolve 'fsevents' in '.\node_modules\chokidar\lib'
 @ ./node_modules/chokidar/lib/fsevents-handler.js
 @ ./node_modules/chokidar/index.js
 @ ./src/main.js

我究竟做错了什么?

PS:添加node: { fsevents: 'empty' }没有帮助。

最佳答案

tl;博士
告诉 Webpack 忽略 require通过 IgnorePlugin :

const { IgnorePlugin } = require('webpack');

const optionalPlugins = [];
if (process.platform !== "darwin") { // don't ignore on OSX
  optionalPlugins.push(new IgnorePlugin({ resourceRegExp: /^fsevents$/ }));
}

module.exports = {
  // other webpack config options here...
  plugins: [
    ...optionalPlugins,
  ],
};
解释
问题来自 this line in lib/fsevents-handler.js :
try {
  fsevents = require('fsevents'); // this module doesn't exists on Linux
} catch (error) {
  if (process.env.CHOKIDAR_PRINT_FSEVENTS_REQUIRE_ERROR) console.error(error);
}
我的猜测是,因为它是 require ,Webpack 尝试解决它,即使在 Linux 上它也不存在。这就是为什么它在 try...catch 中的原因阻止,因为它在 Linux 上运行时会失败并且他们会以这种方式处理它。可悲的是,Webpack(偶尔?)在这方面有问题。
如果我们检查这整个fsevents-handler.js模块用于主 index.js 文件,我们可以看到他们check if they can use this module通过 FsEventsHandler.canUse() , save it to opts.useFsEvents ,然后每次他们想使用该模块 they check that option .canUse功能是 implemented this way :
const canUse = () => fsevents && FSEventsWatchers.size < 128;
因此,如果我们有一个模块返回假值,那么通过 fsevents变量整个事情将被禁用(因为它应该在 Linux 上默认)。
解决方案
在我创建了以下章节中描述的(现在是替代的)解决方案后,vinceau想出了一个更简单的解决方案:你可以告诉 Webpack 忽略 require s 基于正则表达式低谷 IgnorePlugin .这样你就不必模拟模块,所以 require在 lib 中将像作者最初预期的那样工作(失败)。所以只需添加插件:
module.exports = {
  plugins: [
    new IgnorePlugin({ resourceRegExp: /^fsevents$/ }),
  ],
};
这将忽略 require在每个操作系统上,但在 OSX 下不应该发生这种情况,因此最好检查平台并仅选择性地添加它:
const optionalPlugins = [];
if (process.platform !== "darwin") { // don't ignore on OSX
  optionalPlugins.push(new IgnorePlugin({ resourceRegExp: /^fsevents$/ }));
}

module.exports = {
  plugins: [ ...optionalPlugins ],
};
替代方案
我们可以创建一个模拟模块,它将返回一个虚假的默认值(还添加一些注释来解释这种情况):
// mock module to prevent Webpack from throwing an error when
// it tries to resolve the `fsevents` module under Linux that
// doesn't have this module.
// see: https://stackoverflow.com/a/67829712

module.exports = undefined
让我们将其保存到名为 fsevent.js 的项目根目录中(你可以随意调用/放置它),然后配置 Webpack,以便当它尝试解析 fsevents 时它将返回这个模拟模块。在 Webpack 5 中,这可以通过 resolve aliases 完成.我们还添加了一个条件,因此我们不在 OSX 上执行此操作,其中 fsevents可用:
const optionalAliases = {};
if (process.platform !== "darwin") {
  optionalAliases['fsevents$'] = path.resolve(__dirname, `fsevents.js`);
}

module.exports = {
  resolve: {
    alias: {
      ...optionalAliases,
    },
  },
};

关于webpack - Electron+Webpack = 找不到模块 : Error: Can't resolve fsevents/fs/etc in chokidar/etc,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52125641/

相关文章:

webpack - 如何使用新的 Webpack API 重写 compiler.plugin ('done' ...)?

javascript - webpack 和两个不同的来源网站

javascript - ElectronJS - 在窗口之间共享 redux 存储?

javascript - 如何在桌面应用程序中实现文本搜索?

Electron :初始化前无法访问对话框

javascript - 这些 Webpack v3 ModuleConcatenationPlugin 救助消息是什么意思?

node.js - 需要帮助了解 gulp 和 webpack-stream 的工作原理

node.js - create-react-app和npm install webpack错误:超出最大调用堆栈大小

node.js - 如何修复 Electron 中的 IPC 错误 "Error invoking remote method, an object could not be cloned"?

reactjs - 如何在JSX中的arrow函数内调用另一个函数?