4
votes

Webpack - Comment avez-vous besoin d'une dépendance facultative dans le bundle (saslprep)

J'utilise webpack pour regrouper un certain nombre de scripts back-end dans un seul fichier pendant mon processus de déploiement.

Lors de la connexion à la base de données MongoDB, il existe une dépendance facultative, qui émet un avertissement si elle n'est pas incluse.

const path = require('path');
const webpack = require('webpack');

module.exports = {
    entry: './src/api/index.ts',
    target: 'node',
    mode: 'production',
    module: {
        rules: [
            {
                test: /\.tsx?$/,
                loader: 'ts-loader',
                exclude: /node_modules/
            }
        ]
    },
    resolve: {
        extensions: ['.js', '.tsx', '.ts', '.json']
    },
    output: {
    filename: 'api.js',
        path: path.resolve(__dirname, 'dist'),
    },
    plugins: [
        new webpack.IgnorePlugin(/fsevents/),
        new webpack.IgnorePlugin(/blessed/),
        new webpack.ProvidePlugin({
            saslprep: path.resolve(__dirname, "node_modules/saslprep/index.js")
        })
    ],
};

Dans mon environnement de développement, cette erreur est facilement résolue en installant la dépendance facultative.

let saslprep;
try {
  saslprep = require('saslprep');
} catch (e) {
  // don't do anything;
}

Cependant, lors du regroupement avec webpack, la dépendance facultative n'est pas incluse et l'avertissement persiste dans le déploiement de production. Je peux trouver la cause de cela assez facilement, la bibliothèque mongodb l'exige comme dépendance facultative:

npm install saslprep --save

J'ai essayé de suivre la documentation du webpack en utilisant le shimming, les externes, les plugins et je suis franchement perdu quant à la bonne approche pour résoudre ce problème. Voici mon fichier webpack.config actuel (en essayant de l'exiger en tant que plugin).

Warning: no saslprep library specified. Passwords will not be sanitized

Merci d'avance.


0 commentaires

3 Réponses :


1
votes

webpack devrait «voir» qui require('saslprep') code require('saslprep') et le regroupement de saslprep. Vous pouvez le confirmer en regardant le (s) fichier (s) créé (s) par webpack et en recherchant quelque chose de distinctif dans le code source de la bibliothèque. Je regarderais le code MongoDB qui vérifie cette dépendance - il se peut que la façon dont ils vérifient qu'elle existe ne fonctionne pas avec la façon dont le webpack regroupe et définit la dépendance. (La plupart des auteurs de bibliothèques de nœuds ne réfléchissent probablement pas à la façon dont le code fonctionnera une fois groupé - webpack peut être utilisé pour Node, mais c'est rarement le cas.) Si tel est le cas, vous pourrez peut-être procéder à une rétro-ingénierie du code. vérifier et mettre en place via un alias, etc.


3 commentaires

Merci pour les commentaires Brendan. Il semble en effet que webpack voit require('saslprep') et l'inclut dans le bundle. Lorsque vous dites via un alias, vous voulez dire quelque chose du genre de ce qui est décrit ici ?


C'est ce à quoi je faisais référence, oui. Mais je ne suis pas sûr que cela finisse par aider - vous voudrez regarder le code source du module lié à mongo qui vérifie l'existence de saslprep . Comment fait-il ce chèque, que cherche-t-il? Vous allez vouloir lui donner ce qu'il recherche, donc tout dépend de la façon dont ce chèque est rédigé. N'hésitez pas à partager la mise en œuvre de ce chèque ici pour obtenir de l'aide sur un `` correctif ''


Salut Brendan - ne ressentez pas le besoin de regarder cela car j'ai trouvé une solution en utilisant Externals Above. Mais pour la postérité, les vérifications effectuées par le code source peuvent être vues ici: raw.githubusercontent.com/mongodb/node-mongodb-native/master‌ /…



2
votes

Merci à Brendan de m'avoir guidé dans la bonne direction. En fin de compte, la réponse a été trouvée ici: http://www.matthiassommer.it/software-architecture/webpack-node-modules/

L'information clé étant:

Le compilateur de Webpack convertit l'appel require () en son propre webpack_require (). Au moment de l'exécution, il examine son registre de module interne.

En suivant les étapes qui y sont décrites, la résolution devient:

const path = require('path');
const webpack = require('webpack');

module.exports = {
    entry: './src/api/index.ts',
    target: 'node',
    mode: 'production',
    module: {
        rules: [
            {
                test: /\.tsx?$/,
                loader: 'ts-loader',
                exclude: /node_modules/
            }
        ]
    },
    resolve: {
        extensions: ['.js', '.tsx', '.ts', '.json'],
    },
    output: {
        filename: 'api.js',
        path: path.resolve(__dirname, 'dist'),
    },
    plugins: [
        new webpack.IgnorePlugin(/fsevents/),
        new webpack.IgnorePlugin(/blessed/),
    ],
    externals: {
        "saslprep": "require('saslprep')"
    }
};

Veuillez noter que dans mes tests, les guillemets autour de "saslprep" semblent être nécessaires lors de l'importation d'externes.


0 commentaires

0
votes

Si vous utilisez le package webpack-node-externals, vous pouvez également le faire:

const nodeExternals = require("webpack-node-externals")

...

const webpackConfig = {
  ...
  externals: [nodeExternals({
    allowlist: ['saslprep']
  })],
  ...
}


0 commentaires