Knex: Errores de "Módulo no encontrado" al usar knex con webpack

Creado en 6 ene. 2016  ·  23Comentarios  ·  Fuente: knex/knex

Estoy tratando de usar knex en un proyecto en el que estoy trabajando. El problema que tengo es que cuando trato de ejecutar el paquete web, está rastreando los requisitos e intentando obtener controladores/dialectos que no estoy usando y que no tengo instalados.

¿Alguna idea sobre cómo se puede resolver esto?

registro ``````
ERROR en ./~/mariasql/lib/Client.js
Módulo no encontrado: Error: No se puede resolver 'archivo' o 'directorio' ../build/Debug/sqlclient en ~/project/node_modules/mariasql/lib
@ ./~/mariasql/lib/Client.js 17:10-45

ERROR en ./~/knex/lib/dialects/sqlite3/index.js
Módulo no encontrado: Error: No se puede resolver el módulo 'sqlite3' en ~/project/node_modules/knex/lib/dialects/sqlite3
@ ./~/knex/lib/dialects/sqlite3/index.js 33:11-29

ERROR en ./~/knex/lib/dialects/mysql2/index.js
Módulo no encontrado: Error: No se puede resolver el módulo 'mysql2' en ~/project/node_modules/knex/lib/dialects/mysql2
@ ./~/knex/lib/dialects/mysql2/index.js 33:11-28

ERROR en ./~/knex/lib/dialects/mysql/index.js
Módulo no encontrado: Error: No se puede resolver el módulo 'mysql' en ~/project/node_modules/knex/lib/dialects/mysql
@ ./~/knex/lib/dialects/mysql/index.js 35:11-27

ERROR en ./~/knex/lib/dialects/oracle/index.js
Módulo no encontrado: Error: No se puede resolver el módulo 'oracle' en ~/project/node_modules/knex/lib/dialects/oracle
@ ./~/knex/lib/dialects/oracle/index.js 40:11-28

ERROR en ./~/knex/lib/dialects/postgres/index.js
Módulo no encontrado: Error: No se puede resolver el módulo 'pg' en ~/project/node_modules/knex/lib/dialects/postgres
@ ./~/knex/lib/dialects/postgres/index.js 46:11-24

ERROR en ./~/knex/lib/dialects/postgres/index.js
Módulo no encontrado: Error: No se puede resolver el módulo 'pg-query-stream' en ~/project/node_modules/knex/lib/dialects/postgres
@ ./~/knex/lib/dialects/postgres/index.js 132:50-76

ERROR en ./~/knex/lib/dialects/strong-oracle/index.js
Módulo no encontrado: Error: No se puede resolver el módulo 'strong-oracle' en ~/project/node_modules/knex/lib/dialects/strong-oracle
@ ./~/knex/lib/dialects/strong-oracle/index.js 15:9-33```
``````

Comentario más útil

también me encontré con esto. lo que funciona para mí;

externals: {
  knex: 'commonjs knex'
}

Todos 23 comentarios

Tuve este problema, pero al agregar un Regex a mis elementos externos en la configuración de mi paquete web se solucionó:

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 Ignorar el directorio node_modules realmente no resuelve el problema, solo estamos solucionando el problema. Sería increíble si el código hiciera estos requisitos de una manera más inteligente que no arroje errores.

También me encontré con esto. No estoy muy seguro de por qué ignorar node_modules no funciona.

también me encontré con esto. lo que funciona para mí;

externals: {
  knex: 'commonjs knex'
}

No puedo comentar específicamente sobre el problema de mariasql, pero lo que resolvió mi problema es definir todos los controladores que no uso como externos. Por ejemplo, utilizo el controlador mysql2 para mi proyecto, así que tengo esto en los elementos externos:

  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'
  }

El resultado es que knex se empaqueta sin errores ni advertencias.

Este problema parece ser solo un problema de cómo configurar la configuración del paquete web cuando se incluye knex ... volvamos a abrir si se requieren cambios en knex para admitir mejor el paquete web.

En realidad, no creo que el problema deba cerrarse todavía, todavía hay problemas sin resolver con el paquete web, con la migración y la semilla:

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

No pude arreglar estos

@ifullgaz eso no parece ser un error, sino solo una advertencia de que require () no se usó con cadena literal. https://github.com/webpack/webpack/issues/196

@ifullgaz , probé su solución, pero obtuve los siguientes errores. ¿Te encontraste con un problema similar?

  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 , ¿tiene la propiedad correcta, etc. del directorio node_modules y todo el contenido (no ha ejecutado npm install como root en ningún momento)?

     [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 Encontré la sugerencia de https://www.laurivan.com/make-electron-work-with-knex-js/ solucionó estos errores:

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

Específicamente, esta parte funcionó para mí:

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

este fue el boleto para mi libraryTarget: 'commonjs2',

Miré un enfoque ligeramente diferente que permite que webpack procese la mayoría de las declaraciones require en los archivos knex, pero dejaré los require no literales solos para que los archivos de migración y semilla proporcionados por el usuario de la biblioteca se encuentra. Aquí está el enfoque que tomé:

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'
    }
  }
];

Hola amigos, estaba trabajando para resolver el problema de crear un paquete web completo para un servicio usando knex y me encontré con este problema al intentar ejecutar migraciones mediante programación desde ese paquete. La sugerencia de @mdlavin hizo que ejecutara el requisito, pero resultó en que el paquete web no transformara el archivo fuente. También significaba que tendría que incluir ese directorio con el paquete fuera de banda del paquete webpack.

Descubrí que puedes usar el paquete web ContextReplacementPlugin para resolver el problema con las migraciones y las semillas. A continuación se muestra una muestra de mi configuración (escrito en mecanografiado):

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)
          )
        });
      }, {}))
  //...
]

En mi configuración params.targetPackageFiletPath es la ruta resuelta al paquete que se está compilando, por ejemplo /Users/yourusername/yourproject . Entonces, si un proyecto en esa ruta tiene directorios migrations y seeds , las configuraciones de complemento resultantes se verían así:

  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'
    }),

Para desglosar esto un poco, el problema es que el código de migración y semilla de knex llama a require para cargar sus migraciones y semillas, como lo hace aquí https://github.com/tgriesser/knex/blob/master/ src/migrar/index.js#L54. Pasa el resultado de una función/expresión a require sin prefijo o sufijo de cadena codificado de forma rígida, por lo que, cuando el paquete web intenta averiguar qué archivos podrían cargarse, no tiene suficiente información para determinarlo. Estos complementos proporcionan la información necesaria para webpack.

No estoy seguro de si se podría cambiar Knex para que no sea necesario cuando se empaqueta con un paquete web. ¿Tal vez haciendo los requisitos en la tierra del usuario?

De todos modos, pensé en compartir una solución que funcionó para mí.

¿Alguna sugerencia para este problema en Angular?
Intento usar el proyecto express, es normal (no muestra ningún error). Pero cuando lo uso en el proyecto Angular, muestra el error:

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'

¿Dónde puedo hacer la configuración para eliminar este error?
¿podría configurarse en el archivo angular.json o tsconfig.json ?

En webpack lo más probable.

Esto me lo arregló (crédito a @ifullgaz ) Tuve que agregar 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'
    }

Luego, simplemente elimine el controlador que está utilizando de esta lista y el paquete web lo incluirá en la compilación.

@ifullgaz Encontré la sugerencia de https://www.laurivan.com/make-electron-work-with-knex-js/ solucionó estos errores:

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

Específicamente, esta parte funcionó para mí:

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

Esto funciono muy bien para mi. Hice esto:

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) No pude hacer funcionar la importación relativa de noop.js porque estaba tratando de importarlo en lo profundo de knex. Acabo de instalar esta simple node-noop lib y funcionó bien.
2) Usamos Postgres, por lo que la expresión regular en la primera línea coincide con todas las demás que busca. Modifique al contenido de su corazón.

2019/10 Logré hacerlo funcionar, vea mi respuesta en otro número https://github.com/tgriesser/knex/issues/1446#issuecomment -537715431

Puse la dependencia de pg como "externa" y resolvió el problema muchas gracias, ¿significa que el paquete web analiza las dependencias de back-end?

Hola amigos, estaba trabajando para resolver el problema de crear un paquete web completo para un servicio usando knex y me encontré con este problema al intentar ejecutar migraciones mediante programación desde ese paquete. La sugerencia de @mdlavin hizo que ejecutara el requisito, pero resultó en que el paquete web no transformara el archivo fuente. También significaba que tendría que incluir ese directorio con el paquete fuera de banda del paquete webpack.

Descubrí que puedes usar el paquete web ContextReplacementPlugin para resolver el problema con las migraciones y las semillas. A continuación se muestra una muestra de mi configuración (escrito en mecanografiado):

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)
          )
        });
      }, {}))
  //...
]

En mi configuración params.targetPackageFiletPath es la ruta resuelta al paquete que se está compilando, por ejemplo /Users/yourusername/yourproject . Entonces, si un proyecto en esa ruta tiene directorios migrations y seeds , las configuraciones de complemento resultantes se verían así:

  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'
    }),

Para desglosar esto un poco, el problema es que el código de migración y semilla de knex llama a require para cargar sus migraciones y semillas, como lo hace aquí https://github.com/tgriesser/knex/blob/master/ src/migrar/index.js#L54. Pasa el resultado de una función/expresión a require sin prefijo o sufijo de cadena codificado de forma rígida, por lo que, cuando el paquete web intenta averiguar qué archivos podrían cargarse, no tiene suficiente información para determinarlo. Estos complementos proporcionan la información necesaria para webpack.

No estoy seguro de si se podría cambiar Knex para que no sea necesario cuando se empaqueta con un paquete web. ¿Tal vez haciendo los requisitos en la tierra del usuario?

De todos modos, pensé en compartir una solución que funcionó para mí.

Salva mis días, muchas gracias.

Para aquellos que buscan una solución, esta funcionó para mí usando knex@^0.21.1, quería que se mantuviera el controlador mysql2 . Tomé 2 soluciones existentes, que funcionaron juntas para mí.

En la combinación de configuración del paquete web en una versión modificada de 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',
      }

También agregue un complemento de paquete web, que excluirá los paquetes ofensivos
referencia https://github.com/knex/knex/issues/3130#issuecomment -573293311

Modifiqué el original para excluirlo correctamente en mi caso de uso, incluido el conjunto correcto de subdirectorios mssql y también para permitir algunos paquetes pg que se requieren para que Knex funcione

    new webpack.IgnorePlugin(
        new RegExp('^(mssql*|mariasql|.oracle.|sqlite3|mssql/.*|tedious|node-pre-gyp)$')
      ),
¿Fue útil esta página
0 / 5 - 0 calificaciones

Temas relacionados

zettam picture zettam  ·  3Comentarios

rarkins picture rarkins  ·  3Comentarios

ghost picture ghost  ·  3Comentarios

fsebbah picture fsebbah  ·  3Comentarios

mishitpatel picture mishitpatel  ·  3Comentarios