Knex: 将 knex 与 webpack 一起使用时出现“未找到模块”错误

创建于 2016-01-06  ·  23评论  ·  资料来源: knex/knex

我正在尝试在我正在进行的项目中使用 knex。 我遇到的问题是,当我尝试运行 webpack 时,它正在跟踪需求并尝试引入我未使用且未安装的驱动程序/方言。

关于如何解决这个问题的任何想法?

``````日志
./~/mariasql/lib/Client.js 中的错误
找不到模块:错误:无法解析 ~/project/node_modules/mariasql/lib 中的“文件”或“目录”../build/Debug/sqlclient
@ ./~/mariasql/lib/Client.js 17:10-45

./~/knex/lib/dialects/sqlite3/index.js 中的错误
未找到模块:错误:无法解析 ~/project/node_modules/knex/lib/dialects/sqlite3 中的模块“sqlite3”
@ ./~/knex/lib/dialects/sqlite3/index.js 33:11-29

./~/knex/lib/dialects/mysql2/index.js 中的错误
找不到模块:错误:无法解析 ~/project/node_modules/knex/lib/dialects/mysql2 中的模块“mysql2”
@ ./~/knex/lib/dialects/mysql2/index.js 33:11-28

./~/knex/lib/dialects/mysql/index.js 中的错误
找不到模块:错误:无法解析 ~/project/node_modules/knex/lib/dialects/mysql 中的模块“mysql”
@ ./~/knex/lib/dialects/mysql/index.js 35:11-27

./~/knex/lib/dialects/oracle/index.js 中的错误
找不到模块:错误:无法解析 ~/project/node_modules/knex/lib/dialects/oracle 中的模块“oracle”
@ ./~/knex/lib/dialects/oracle/index.js 40:11-28

./~/knex/lib/dialects/postgres/index.js 中的错误
找不到模块:错误:无法解析 ~/project/node_modules/knex/lib/dialects/postgres 中的模块“pg”
@ ./~/knex/lib/dialects/postgres/index.js 46:11-24

./~/knex/lib/dialects/postgres/index.js 中的错误
找不到模块:错误:无法在 ~/project/node_modules/knex/lib/dialects/postgres 中解析模块 'pg-query-stream'
@ ./~/knex/lib/dialects/postgres/index.js 132:50-76

./~/knex/lib/dialects/strong-oracle/index.js 中的错误
找不到模块:错误:无法解析 ~/project/node_modules/knex/lib/dialects/strong-oracle 中的模块“strong-oracle”
@ ./~/knex/lib/dialects/strong-oracle/index.js 15:9-33```
``````

最有用的评论

也遇到了这个。 什么对我有用;

externals: {
  knex: 'commonjs knex'
}

所有23条评论

我遇到了这个问题,但是在我的 webpack 配置中向我的外部添加一个正则表达式修复了它:

const commonLoaders = [
  { test: /\.js$/, loader: 'babel', exclude: [/node_modules/] },
  { test: /\.json$/, loader: 'json' },
];

module.exports = [
  {
    name: 'browser',
    entry: './js/entry.js',
    output: {
      path: './build',
      filename: 'bundle.js',
    },
    module: {
      loaders: commonLoaders.concat([
        { test: /\.styl$/, loader: 'style!css!stylus' },
      ]),
    },
  },
  {
    name: 'server',
    entry: './server.js',
    target: 'node',
    output: {
      path: './build',
      filename: 'server.js',
      libraryTarget: 'commonjs2',
    },
    externals: [
      {
        'socket.io': 'socket.io',
      },
      /^[a-z\-0-9]+$/,
    ],
    module: {
      loaders: commonLoaders.concat([
        { test: /\.styl$/, loader: 'css!stylus' },
      ]),
    },
  },
];

+1

@joeketchi忽略 node_modules 目录并不能真正解决问题,我们只是在解决这个问题。 如果代码能够以更智能的方式完成这些要求,并且不会引发错误,那就太棒了。

也碰到了这个。 不太清楚为什么忽略 node_modules 不起作用。

也遇到了这个。 什么对我有用;

externals: {
  knex: 'commonjs knex'
}

我无法具体评论 mariasql 问题,但解决我的问题的方法是将所有我不使用的驱动程序定义为外部驱动程序。 例如,我为我的项目使用 mysql2 驱动程序,所以我在外部有这个:

  externals: {
    // Possible drivers for knex - we'll ignore them
    'sqlite3': 'sqlite3',
    'mariasql': 'mariasql',
    'mssql': 'mssql',
    'mysql': 'mysql',
    'oracle': 'oracle',
    'strong-oracle': 'strong-oracle',
    'oracledb': 'oracledb',
    'pg': 'pg',
    'pg-query-stream': 'pg-query-stream'
  }

结果是 knex 被捆绑,没有错误或警告

这个问题似乎只是包含 knex 时如何设置 webpack 配置的问题......如果 knex 需要更改以更好地支持 webpack,请重新打开。

实际上,我认为这个问题还没有结束,webpack 仍然存在未解决的问题,包括迁移和种子:

WARNING in ./node_modules/knex/lib/migrate/index.js
342:20-81 Critical dependency: the request of a dependency is an expression

WARNING in ./node_modules/knex/lib/migrate/index.js
447:18-49 Critical dependency: the request of a dependency is an expression

WARNING in ./node_modules/knex/lib/seed/index.js
113:13-74 Critical dependency: the request of a dependency is an expression

WARNING in ./node_modules/knex/lib/seed/index.js
150:11-24 Critical dependency: the request of a dependency is an expression

我无法修复这些

@ifullgaz这似乎不是一个错误,而只是一个警告 require() 没有与字符串文字一起使用? https://github.com/webpack/webpack/issues/196

@ifullgaz ,我已经尝试过您的解决方案,但出现以下错误。 你遇到过类似的问题吗?

  Error --------------------------------------------------
  Command failed: npm install
gyp ERR! UNCAUGHT EXCEPTION
gyp ERR! stack Error: spawn EACCES
gyp ERR! stack     at exports._errnoException (util.js:1018:11)
gyp ERR! stack     at ChildProcess.spawn (internal/child_process.js:319:11)
gyp ERR! stack     at exports.spawn (child_process.js:378:9)
gyp ERR! stack     at exports.execFile (child_process.js:143:15)

@brianhuangyl您对 node_modules 目录和所有 ist 内容的所有权等是否正确(您在任何时候都没有以 root 身份运行 npm install )?

     [EACCES]       Permission bits of the file mode do not permit the
            requested access, or search permission is denied on a
            component of the path prefix.

@ifullgaz我发现https://www.laurivan.com/make-electron-work-with-knex-js/的建议修复了这些错误:

WARNING in ./node_modules/knex/lib/migrate/index.js
342:20-81 Critical dependency: the request of a dependency is an expression

WARNING in ./node_modules/knex/lib/migrate/index.js
447:18-49 Critical dependency: the request of a dependency is an expression

WARNING in ./node_modules/knex/lib/seed/index.js
113:13-74 Critical dependency: the request of a dependency is an expression

WARNING in ./node_modules/knex/lib/seed/index.js
150:11-24 Critical dependency: the request of a dependency is an expression

具体来说,这部分对我有用:

config.plugins = [
  // ...
  new NormalModuleReplacementPlugin(/\.\.\/migrate/, '../util/noop.js'),
  new NormalModuleReplacementPlugin(/\.\.\/seed/, '../util/noop.js'),
];

这是给我的票libraryTarget: 'commonjs2',

我看了一个稍微不同的方法,它允许 webpack 处理 knex 文件中的大多数require语句,但将单独留下非文字require s,以便用户提供的迁移和种子文件可以找到图书馆的。 这是我采取的方法:

config.module.rules = [
  {
    include: [
      /knex\/lib\/migrate\/index/,
      /knex\/lib\/seed\/index/
    ],
    loader: 'string-replace-loader',
    options: {
      search: 'require(\\([^\'"])',
      replace: '__non_webpack_require__$1',
      flags: 'g'
    }
  }
];

大家好,我正在努力解决使用 knex 为服务创建完整的 webpack 包的问题,​​并在尝试从该包以编程方式运行迁移时遇到了这个问题。 @mdlavin的建议确实让它运行了 require 但是,它导致 webpack 没有转换源文件。 这也意味着我需要将该目录与 webpack 捆绑包中的捆绑包一起包含在内。

我发现您可以使用 webpack 的ContextReplacementPlugin来解决迁移和种子问题。 以下是我的配置示例(用打字稿编写):

plugins: [
  //...
  fs.existsSync(path.join(params.targetPackageFilePath, 'migrations')) && new webpack.ContextReplacementPlugin(
    /knex\/lib\/migrate/,
    '.',
    fs.readdirSync(path.join(params.targetPackageFilePath, 'migrations'))
      .reduce((result, file) => {
        return Object.assign(result, {
          [path.join(params.targetPackageFilePath, 'migrations', file)]: path.relative(
            path.dirname(require.resolve('knex/lib/migrate')),
            path.join(params.targetPackageFilePath, 'migrations', file)
          )
        });
      }, {})),

  fs.existsSync(path.join(params.targetPackageFilePath, 'seeds')) && new webpack.ContextReplacementPlugin(
    /knex\/lib\/seed/,
    '.',
    fs.readdirSync(path.join(params.targetPackageFilePath, 'seeds'))
      .reduce((result, file) => {
        return Object.assign(result, {
          [path.join(params.targetPackageFilePath, 'seeds', file)]: path.relative(
            path.dirname(require.resolve('knex/lib/seed')),
            path.join(params.targetPackageFilePath, 'seeds', file)
          )
        });
      }, {}))
  //...
]

在我的配置中params.targetPackageFiletPath是正在编译的包的解析路径,例如/Users/yourusername/yourproject 。 因此,如果该路径上的项目具有migrationsseeds目录,则生成的插件配置将如下所示:

  fs.existsSync(path.join(params.targetPackageFilePath, 'migrations')) && new webpack.ContextReplacementPlugin(
    /knex\/lib\/migrate/,
    '.',
    {
      '/Users/yourusername/yourproject/201706261234_migration.ts': '../../../migrations/201706261234_migration.ts'
    }),

  fs.existsSync(path.join(params.targetPackageFilePath, 'seeds')) && new webpack.ContextReplacementPlugin(
    /knex\/lib\/seed/,
    '.',
    {
      '/Users/yourusername/yourproject/seeds/201706261234_first-seed.ts': '../../../seeds/201706261234_first-seed.ts'
    }),

稍微分解一下,问题是 knex 的迁移和种子代码调用require来加载您的迁移和种子,就像它在这里一样https://github.com/tgriesser/knex/blob/master/ src/migrate/index.js#L54。 它将函数/表达式的结果传递给 require 没有硬编码的字符串前缀或后缀,因此,当 webpack 尝试找出可能实际加载的文件时,它没有足够的信息来确定这一点。 这些插件为 webpack 提供所需的信息。

我不确定在与 webpack 捆绑时是否可以更改 Knex 以使这些变得不必要。 也许通过在用户领域做要求?

无论如何,我想我会分享一个对我有用的解决方案。

在 Angular 中对这个问题有什么建议吗?
我尝试使用 express 项目,这是正常的(没有显示任何错误)。 但是当我在 Angular 项目中使用它时,它会显示错误:

ERROR in ./node_modules/knex/lib/dialects/oracle/utils.js Module not found: Error: Can't resolve 'crypto' in '/Users/marudits/Documents/CODE/PROJECT/MOJOMARET/app-member/node_modules/knex/lib/dialects/oracle' ERROR in ./node_modules/knex/lib/dialects/mssql/index.js Module not found: Error: Can't resolve 'mssql/package.json' in '/Users/marudits/Documents/CODE/PROJECT/MOJOMARET/app-member/node_modules/knex/lib/dialects/mssql' ERROR in ./node_modules/knex/lib/runner.js Module not found: Error: Can't resolve 'stream' in '/Users/marudits/Documents/CODE/PROJECT/MOJOMARET/app-member/node_modules/knex/lib' ERROR in ./node_modules/knex/lib/dialects/oracledb/index.js Module not found: Error: Can't resolve 'stream' in '/Users/marudits/Documents/CODE/PROJECT/MOJOMARET/app-member/node_modules/knex/lib/dialects/oracledb'

我可以在哪里进行配置以消除此错误?
可以在angular.jsontsconfig.json文件上设置吗?

最有可能在 webpack 中。

这为我修复了它(归功于@ifullgaz )我不得不添加mysql2。

    externals: {
        // Possible drivers for knex - we'll ignore them
        sqlite3: 'sqlite3',
        mysql2: 'mysql2',
        mariasql: 'mariasql',
        mysql: 'mysql',
        oracle: 'oracle',
        'strong-oracle': 'strong-oracle',
        oracledb: 'oracledb',
        pg: 'pg',
        'pg-query-stream': 'pg-query-stream'
    }

然后只需从此列表中删除您正在使用的驱动程序,webpack 就会将其包含在构建中。

@ifullgaz我发现https://www.laurivan.com/make-electron-work-with-knex-js/的建议修复了这些错误:

WARNING in ./node_modules/knex/lib/migrate/index.js
342:20-81 Critical dependency: the request of a dependency is an expression

WARNING in ./node_modules/knex/lib/migrate/index.js
447:18-49 Critical dependency: the request of a dependency is an expression

WARNING in ./node_modules/knex/lib/seed/index.js
113:13-74 Critical dependency: the request of a dependency is an expression

WARNING in ./node_modules/knex/lib/seed/index.js
150:11-24 Critical dependency: the request of a dependency is an expression

具体来说,这部分对我有用:

config.plugins = [
  // ...
  new NormalModuleReplacementPlugin(/\.\.\/migrate/, '../util/noop.js'),
  new NormalModuleReplacementPlugin(/\.\.\/seed/, '../util/noop.js'),
];

这对我很有用。 我这样做了:

plugins: [
    new webpack.NormalModuleReplacementPlugin(/m[sy]sql2?|oracle(db)?|sqlite3/, "node-noop"),
    new webpack.NormalModuleReplacementPlugin(/\.\.\/migrate/, "node-noop"),
    new webpack.NormalModuleReplacementPlugin(/\.\.\/seed/, "node-noop")
  ]

1) 我无法让noop.js的相对导入工作,因为它试图将它导入到 knex 的深处。 我刚刚安装了这个简单的node-noop库,效果很好。
2) 我们使用 Postgres,因此第一行中的正则表达式与它查找的所有其他正则表达式匹配。 随心所欲地修改。

2019/10 我设法让它工作,在另一个问题中查看我的答案https://github.com/tgriesser/knex/issues/1446#issuecomment -537715431

我将 pg 依赖项设置为“外部”,非常感谢它解决了这个问题,这是否意味着 webpack 解析了后端依赖项?

大家好,我正在努力解决使用 knex 为服务创建完整的 webpack 包的问题,​​并在尝试从该包以编程方式运行迁移时遇到了这个问题。 @mdlavin的建议确实让它运行了 require 但是,它导致 webpack 没有转换源文件。 这也意味着我需要将该目录与 webpack 捆绑包中的捆绑包一起包含在内。

我发现您可以使用 webpack 的ContextReplacementPlugin来解决迁移和种子问题。 以下是我的配置示例(用打字稿编写):

plugins: [
  //...
  fs.existsSync(path.join(params.targetPackageFilePath, 'migrations')) && new webpack.ContextReplacementPlugin(
    /knex\/lib\/migrate/,
    '.',
    fs.readdirSync(path.join(params.targetPackageFilePath, 'migrations'))
      .reduce((result, file) => {
        return Object.assign(result, {
          [path.join(params.targetPackageFilePath, 'migrations', file)]: path.relative(
            path.dirname(require.resolve('knex/lib/migrate')),
            path.join(params.targetPackageFilePath, 'migrations', file)
          )
        });
      }, {})),

  fs.existsSync(path.join(params.targetPackageFilePath, 'seeds')) && new webpack.ContextReplacementPlugin(
    /knex\/lib\/seed/,
    '.',
    fs.readdirSync(path.join(params.targetPackageFilePath, 'seeds'))
      .reduce((result, file) => {
        return Object.assign(result, {
          [path.join(params.targetPackageFilePath, 'seeds', file)]: path.relative(
            path.dirname(require.resolve('knex/lib/seed')),
            path.join(params.targetPackageFilePath, 'seeds', file)
          )
        });
      }, {}))
  //...
]

在我的配置中params.targetPackageFiletPath是正在编译的包的解析路径,例如/Users/yourusername/yourproject 。 因此,如果该路径上的项目具有migrationsseeds目录,则生成的插件配置将如下所示:

  fs.existsSync(path.join(params.targetPackageFilePath, 'migrations')) && new webpack.ContextReplacementPlugin(
    /knex\/lib\/migrate/,
    '.',
    {
      '/Users/yourusername/yourproject/201706261234_migration.ts': '../../../migrations/201706261234_migration.ts'
    }),

  fs.existsSync(path.join(params.targetPackageFilePath, 'seeds')) && new webpack.ContextReplacementPlugin(
    /knex\/lib\/seed/,
    '.',
    {
      '/Users/yourusername/yourproject/seeds/201706261234_first-seed.ts': '../../../seeds/201706261234_first-seed.ts'
    }),

稍微分解一下,问题是 knex 的迁移和种子代码调用require来加载您的迁移和种子,就像它在这里一样https://github.com/tgriesser/knex/blob/master/ src/migrate/index.js#L54。 它将函数/表达式的结果传递给 require 没有硬编码的字符串前缀或后缀,因此,当 webpack 尝试找出可能实际加载的文件时,它没有足够的信息来确定这一点。 这些插件为 webpack 提供所需的信息。

我不确定在与 webpack 捆绑时是否可以更改 Knex 以使这些变得不必要。 也许通过在用户领域做要求?

无论如何,我想我会分享一个对我有用的解决方案。

节省我的时间,非常感谢。

对于那些正在寻找解决方案的人,这个使用 knex@^0.21.1 对我有用,我希望保留mysql2驱动程序。 我采用了 2 个现有的解决方案,它们共同为我工作。

在 webpack 配置中合并https://github.com/knex/knex/issues/1128#issuecomment -515573845 的修改版本

externals: [
      {
        // Possible drivers for knex - we'll ignore them
       // comment the one YOU WANT to use
        sqlite3: 'sqlite3',
        // mysql2: 'mysql2', // << using this one
        mariasql: 'mariasql',
        mysql: 'mysql',
        mssql: 'mssql',
        oracle: 'oracle',
        'strong-oracle': 'strong-oracle',
        oracledb: 'oracledb',
        pg: 'pg',
        'pg-query-stream': 'pg-query-stream',
      }

还添加一个 webpack 插件,它将排除有问题的包
参考https://github.com/knex/knex/issues/3130#issuecomment -573293311

我修改了原始文件以在我的用例中正确排除,包括正确的mssql子目录集,还允许 Knex 工作所需的一些pg

    new webpack.IgnorePlugin(
        new RegExp('^(mssql*|mariasql|.oracle.|sqlite3|mssql/.*|tedious|node-pre-gyp)$')
      ),
此页面是否有帮助?
0 / 5 - 0 等级

相关问题

mattgrande picture mattgrande  ·  3评论

rarkins picture rarkins  ·  3评论

marianomerlo picture marianomerlo  ·  3评论

zettam picture zettam  ·  3评论

hyperh picture hyperh  ·  3评论