【挖坑每一天】webpack/electron/sqlite3/node-pre-pyg代码被打包进主线程js文件

2,661 阅读1分钟

描述

webpack在处理sqlite.js时会将计算node_sqlite3.node路径的表达式一并合并进入主线程代码中(如下所示的backgroun.js,以下皆称为background),导致background的大小超标。同时还会导致sqlite不能正确加载,因为路径计算会失败。

////////////////////////////////
///webpack.background.conf.ts///
////////////////////////////////
...
{
  mode: process.env.NODE_ENV === "development" ? "development" : "production",
  target: "electron-main",
  entry: path.join(__dirname, "..", "src/app/background.ts"),
  output: {
    filename: "background.js",
    path: path.resolve(__dirname, "..", "dist")
  },
  node: {
    __dirname: false
  },
  resolve: {
    extensions: [".js", ".jsx", ".ts", ".tsx", ".json"],
  },
  module: {
    rules: [
      {
        test: /\.tsx?$/,
        use: ["ts-loader"],
        exclude: /node_modules/
      },
      {
        test: /\.css/,
        use: [
          "style-loader",
          "css-loader"
        ]
      }
    ]
  }
}
...

//////////////////
///打包的输出///
//////////////////
Hash: eed471596c5c32070306
Version: webpack 4.42.1
Time: 19289ms
Built at: 2020-03-27 14:02:31
        Asset      Size  Chunks             Chunk Names
background.js  10.2 MiB    main  [emitted]  main
Entrypoint main = background.js
[./node_modules/node-gyp/lib sync recursive ^\.\/.*$] ./node_modules/node-gyp/lib sync ^\.\/.*$ 669 bytes {main} [built]
[./node_modules/node-pre-gyp/lib sync recursive] ./node_modules/node-pre-gyp/lib sync 160 bytes {main} [built]
[./node_modules/node-pre-gyp/lib sync recursive ^\.\/.*$] ./node_modules/node-pre-gyp/lib sync ^\.\/.*$ 1 KiB {main} [built]
[./node_modules/node-pre-gyp/lib/util sync recursive] ./node_modules/node-pre-gyp/lib/util sync 160 bytes {main} [built]
[./node_modules/sqlite3/lib sync recursive] ./node_modules/sqlite3/lib sync 160 bytes {main} [built]
[./src/app/background.ts] 2.48 KiB {main} [built]
[assert] external "assert" 42 bytes {main} [built]
[child_process] external "child_process" 42 bytes {main} [built]
[electron] external "electron" 42 bytes {main} [built]
[events] external "events" 42 bytes {main} [built]
[fs] external "fs" 42 bytes {main} [built]
[path] external "path" 42 bytes {main} [built]
[stream] external "stream" 42 bytes {main} [built]
[url] external "url" 42 bytes {main} [built]
[util] external "util" 42 bytes {main} [built]
    + 1263 hidden modules

WARNING in ./node_modules/sqlite3/lib/sqlite3.js 5:14-35
Critical dependency: the request of a dependency is an expression
 @ ./src/app/background.ts

WARNING in ./node_modules/node-pre-gyp/lib/pre-binding.js 20:22-48
Critical dependency: the request of a dependency is an expression
 @ ./node_modules/node-pre-gyp/lib/node-pre-gyp.js
 @ ./node_modules/sqlite3/lib/sqlite3.js
 @ ./src/app/background.ts

WARNING in ./node_modules/node-pre-gyp/lib/util/versioning.js 17:20-67
Critical dependency: the request of a dependency is an expression
 @ ./node_modules/node-pre-gyp/lib sync ^\.\/.*$
 @ ./node_modules/node-pre-gyp/lib/node-pre-gyp.js
 @ ./node_modules/sqlite3/lib/sqlite3.js
 @ ./src/app/background.ts

WARNING in ./node_modules/node-pre-gyp/lib/util/compile.js
Module not found: Error: Can't resolve 'npm' in 'E:\workspace\company\semic\node_modules\node-pre-gyp\lib\util'
 @ ./node_modules/node-pre-gyp/lib/util/compile.js
 @ ./node_modules/node-pre-gyp/lib sync ^\.\/.*$
 @ ./node_modules/node-pre-gyp/lib/node-pre-gyp.js
 @ ./node_modules/sqlite3/lib/sqlite3.js
 @ ./src/app/background.ts

WARNING in ./node_modules/node-pre-gyp/lib/util/nw-pre-gyp/index.html 1:0
Module parse failed: Unexpected token (1:0)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
> <!doctype html>
| <html>
| <head>
 @ ./node_modules/node-pre-gyp/lib sync ^\.\/.*$ ./util/nw-pre-gyp/index.html
 @ ./node_modules/node-pre-gyp/lib/node-pre-gyp.js
 @ ./node_modules/sqlite3/lib/sqlite3.js
 @ ./src/app/background.ts

WARNING in ./node_modules/node-gyp/lib/Find-VisualStudio.cs 9:6
Module parse failed: Unexpected token (9:6)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
| // This script needs to be compatible with PowerShell v2 to run on Windows 2008R2 and Windows 7.
|
> using System;
| using System.Text;
| using System.Runtime.InteropServices;
 @ ./node_modules/node-gyp/lib sync ^\.\/.*$ ./Find-VisualStudio.cs
 @ ./node_modules/node-gyp/lib/node-gyp.js
 @ ./node_modules/node-pre-gyp/lib/util/compile.js
 @ ./node_modules/node-pre-gyp/lib/node-pre-gyp.js
 @ ./node_modules/sqlite3/lib/sqlite3.js
 @ ./src/app/background.ts

分析

从输出中可以看到,很明显webpack进行了错误的打包,正确的过程应该是形似[path] external "path" 42 bytes {main} [built]这样的外部依赖描述,观察生成的background.js,其包含sqlite3.js的几乎全部代码。所以处理思路应该是配置webpack,阻止其处理node_modules中的内容。尝试使用babel-loader并且配置几种动态import插件,并没有什么效果。重新阅读webpack的配置文档,发现externals字段刚好可以满足需要,同时找到一个名为webpack-node-externals的插件,使用后问题解决。