Estou tentando usar o knex em um projeto em que estou trabalhando. O problema que estou tendo é que, quando tento executar o webpack, ele está rastreando os requisitos e tentando extrair drivers/dialetos que não estou usando e não tenho instalados.
Alguma ideia de como isso pode ser resolvido?
`````` log
ERRO em ./~/mariasql/lib/Client.js
Módulo não encontrado: Erro: Não é possível resolver 'arquivo' ou 'diretório' ../build/Debug/sqlclient em ~/project/node_modules/mariasql/lib
@ ./~/mariasql/lib/Client.js 17:10-45
ERRO em ./~/knex/lib/dialects/sqlite3/index.js
Módulo não encontrado: Erro: Não é possível resolver o módulo 'sqlite3' em ~/project/node_modules/knex/lib/dialects/sqlite3
@ ./~/knex/lib/dialects/sqlite3/index.js 33:11-29
ERRO em ./~/knex/lib/dialects/mysql2/index.js
Módulo não encontrado: Erro: Não é possível resolver o módulo 'mysql2' em ~/project/node_modules/knex/lib/dialects/mysql2
@ ./~/knex/lib/dialects/mysql2/index.js 33:11-28
ERRO em ./~/knex/lib/dialects/mysql/index.js
Módulo não encontrado: Erro: Não é possível resolver o módulo 'mysql' em ~/project/node_modules/knex/lib/dialects/mysql
@ ./~/knex/lib/dialects/mysql/index.js 35:11-27
ERRO em ./~/knex/lib/dialects/oracle/index.js
Módulo não encontrado: Erro: Não é possível resolver o módulo 'oracle' em ~/project/node_modules/knex/lib/dialects/oracle
@ ./~/knex/lib/dialects/oracle/index.js 40:11-28
ERRO em ./~/knex/lib/dialects/postgres/index.js
Módulo não encontrado: Erro: Não é possível resolver o módulo 'pg' em ~/project/node_modules/knex/lib/dialects/postgres
@ ./~/knex/lib/dialects/postgres/index.js 46:11-24
ERRO em ./~/knex/lib/dialects/postgres/index.js
Módulo não encontrado: Erro: Não é possível resolver o módulo 'pg-query-stream' em ~/project/node_modules/knex/lib/dialects/postgres
@ ./~/knex/lib/dialects/postgres/index.js 132:50-76
ERRO em ./~/knex/lib/dialects/strong-oracle/index.js
Módulo não encontrado: Erro: Não é possível resolver o módulo 'strong-oracle' em ~/project/node_modules/knex/lib/dialects/strong-oracle
@ ./~/knex/lib/dialects/strong-oracle/index.js 15:9-33```
``````
Eu tive esse problema, mas adicionar um Regex aos meus externos na configuração do meu webpack corrigiu:
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 o diretório node_modules realmente não resolve o problema, estamos apenas resolvendo o problema. Seria incrível se o código fizesse esses requisitos de uma maneira mais inteligente que não gerasse erros.
Também correu para isso. Não tenho certeza por que ignorar node_modules não funciona.
também se deparou com isso. o que funciona para mim;
externals: {
knex: 'commonjs knex'
}
Não posso comentar especificamente sobre o problema do mariasql mas o que resolveu meu problema é definir todos os drivers que não uso como externos. Por exemplo, eu uso o driver mysql2 para o meu projeto, então tenho isso em 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'
}
O resultado é que o knex é empacotado sem erros ou avisos
Este problema parece ser apenas um problema de como configurar a configuração do webpack ao incluir o knex... vamos reabrir se houver alterações necessárias no knex para suportar melhor o webpack.
Na verdade, não acho que o assunto deva ser encerrado ainda, ainda existem problemas não resolvidos com o webpack, com migração e semente:
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
não consegui consertar isso
@ifullgaz isso não parece ser um erro, mas apenas um aviso de que require() não foi usado com literal de string? https://github.com/webpack/webpack/issues/196
@ifullgaz , tentei sua solução, mas recebi erros como abaixo. Você se deparou com um problema semelhante?
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 você corrigiu a propriedade etc. para o diretório node_modules e todo o conteúdo ist (você não executou o npm install como root em nenhum 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 encontrei a sugestão de https://www.laurivan.com/make-electron-work-with-knex-js/ corrigi esses erros:
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
Especificamente, esta parte funcionou para mim:
config.plugins = [
// ...
new NormalModuleReplacementPlugin(/\.\.\/migrate/, '../util/noop.js'),
new NormalModuleReplacementPlugin(/\.\.\/seed/, '../util/noop.js'),
];
este foi o bilhete para mim libraryTarget: 'commonjs2',
Eu procurei uma abordagem um pouco diferente que permite que o webpack processe a maioria das instruções require
nos arquivos knex, mas deixará os require
s não literais sozinhos para que os arquivos de migração e semente fornecidos pelo usuário da biblioteca seja encontrado. Aqui está a abordagem que fiz:
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'
}
}
];
Oi pessoal, eu estava trabalhando para resolver o problema de criar um pacote webpack completo para um serviço usando knex e me deparei com esse problema ao tentar executar migrações programaticamente desse pacote. A sugestão de @mdlavin fez com que ele executasse o require, mas resultou no webpack não transformando o arquivo de origem. Isso também significava que eu precisaria incluir esse diretório com o pacote fora de banda do pacote webpack.
Eu descobri que você pode usar ContextReplacementPlugin
do webpack para resolver o problema com migrações e sementes. Abaixo está uma amostra da minha configuração (escrito em texto datilografado):
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)
)
});
}, {}))
//...
]
Na minha configuração params.targetPackageFiletPath
é o caminho resolvido para o pacote que está sendo compilado, por exemplo /Users/yourusername/yourproject
. Portanto, se um projeto nesse caminho tiver os diretórios migrations
e seeds
, as configurações de plug-in resultantes seriam algo assim:
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 detalhar um pouco, o problema é que o código de migração e semente do knex chama require
para carregar suas migrações e sementes, como faz aqui https://github.com/tgriesser/knex/blob/master/ src/migrate/index.js#L54. Ele passa o resultado de uma função/expressão para exigir sem prefixo ou sufixo de string codificado, portanto, quando o webpack tenta descobrir quais arquivos podem realmente carregar, ele não tem informações suficientes para determinar isso. Esses plugins fornecem as informações necessárias ao webpack.
Não tenho certeza se o Knex pode ser alterado para torná-los desnecessários ao agrupar com o webpack. Talvez fazendo os requisitos na terra do usuário?
De qualquer forma, pensei em compartilhar uma solução que funcionou para mim.
Alguma sugestão para este problema em Angular?
Eu tento usar o projeto expresso, é normal (não mostra nenhum erro). Mas quando eu uso no projeto Angular, ele mostra o erro:
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'
onde posso fazer a configuração para remover esse erro?
poderia ser configurado no arquivo angular.json
ou tsconfig.json
?
Provavelmente no webpack.
Isso corrigiu para mim (crédito a @ifullgaz ) Eu tive que adicionar 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'
}
Em seguida, basta remover o driver que você está usando desta lista e o webpack o incluirá no arquivo build.
@ifullgaz encontrei a sugestão de https://www.laurivan.com/make-electron-work-with-knex-js/ corrigi esses erros:
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
Especificamente, esta parte funcionou para mim:
config.plugins = [ // ... new NormalModuleReplacementPlugin(/\.\.\/migrate/, '../util/noop.js'), new NormalModuleReplacementPlugin(/\.\.\/seed/, '../util/noop.js'), ];
Isso funcionou muito bem para mim. Eu fiz isso:
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) Não consegui fazer com que a importação relativa de noop.js
funcionasse porque estava tentando importá-la profundamente dentro do knex. Acabei de instalar esta simples node-noop
lib e funcionou bem.
2) Usamos o Postgres, então a regex na primeira linha corresponde a todas as outras que ela procura. Modifique para o conteúdo do seu coração.
2019/10 consegui fazer funcionar, veja minha resposta em outro problema https://github.com/tgriesser/knex/issues/1446#issuecomment -537715431
Eu coloquei a dependência pg como "externa" e resolveu o problema muito obrigado, isso significa que o webpack analisa as dependências de back-end?
Oi pessoal, eu estava trabalhando para resolver o problema de criar um pacote webpack completo para um serviço usando knex e me deparei com esse problema ao tentar executar migrações programaticamente desse pacote. A sugestão de @mdlavin fez com que ele executasse o require, mas resultou no webpack não transformando o arquivo de origem. Isso também significava que eu precisaria incluir esse diretório com o pacote fora de banda do pacote webpack.
Eu descobri que você pode usar
ContextReplacementPlugin
do webpack para resolver o problema com migrações e sementes. Abaixo está uma amostra da minha configuração (escrito em texto datilografado):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) ) }); }, {})) //... ]
Na minha configuração
params.targetPackageFiletPath
é o caminho resolvido para o pacote que está sendo compilado, por exemplo/Users/yourusername/yourproject
. Portanto, se um projeto nesse caminho tiver os diretóriosmigrations
eseeds
, as configurações de plug-in resultantes seriam algo assim: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 detalhar um pouco, o problema é que o código de migração e semente do knex chama
require
para carregar suas migrações e sementes, como faz aqui https://github.com/tgriesser/knex/blob/master/ src/migrate/index.js#L54. Ele passa o resultado de uma função/expressão para exigir sem prefixo ou sufixo de string codificado, portanto, quando o webpack tenta descobrir quais arquivos podem realmente carregar, ele não tem informações suficientes para determinar isso. Esses plugins fornecem as informações necessárias ao webpack.Não tenho certeza se o Knex pode ser alterado para torná-los desnecessários ao agrupar com o webpack. Talvez fazendo os requisitos na terra do usuário?
De qualquer forma, pensei em compartilhar uma solução que funcionou para mim.
Salve meus dias, muito obrigado.
Para aqueles que procuram uma solução, esta funcionou para mim usando knex@^0.21.1, eu queria o driver mysql2
retido. Peguei 2 soluções existentes, que funcionaram juntas para mim.
Na configuração do webpack, mesclar em uma versão 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',
}
Adicione também um plug-in do webpack, que excluirá os pacotes ofensivos
ref https://github.com/knex/knex/issues/3130#issuecomment -573293311
Modifiquei o original para excluir corretamente no meu caso de uso, incluindo o conjunto correto de subdiretórios mssql
e também para permitir alguns pacotes pg
que são necessários para o Knex funcionar
new webpack.IgnorePlugin(
new RegExp('^(mssql*|mariasql|.oracle.|sqlite3|mssql/.*|tedious|node-pre-gyp)$')
),
Comentários muito úteis
também se deparou com isso. o que funciona para mim;