web-dev-qa-db-ja.com

monorepoでwebpackを使用する方法(yarnpkgワークスペース)

私は yarn workspaces を使用しています。ここで、ルートディレクトリにはすべてのリポジトリを含むパッケージディレクトリがあります。各リポジトリには、依存関係を含む独自のnode_modulesディレクトリがあります。ルートnode_modulesディレクトリには、プロジェクト全体のすべてのdev依存関係と、webpack.configファイルなど、devに関連する他のすべてのものが含まれています。 Webpackは、エクスプレスサーバーパッケージのホットモジュールリロードを使用します。

私が持っている問題は、ルートだけでなくプロジェクト全体ですべてのnode_modulesディレクトリを除外するようにwebpack外部を設定する方法です?

webpack-node-externals は、このシナリオでは機能しないようです。

エラーメッセージ:

WARNING in ./packages/servers/express/node_modules/colors/lib/colors.js
127:29-43 Critical dependency: the request of a dependency is an expression

WARNING in ./packages/servers/express/node_modules/express/lib/view.js
79:29-41 Critical dependency: the request of a dependency is an expression

Webpackの構成:

const webpack = require('webpack');
const path = require('path');
const nodeExternals = require('webpack-node-externals');
const StartServerPlugin = require('start-server-webpack-plugin');

module.exports = {
  entry: [
    'babel-polyfill',
    'webpack/hot/poll?1000',
    path.join(__dirname, '../packages/servers/express/server/index.js')
  ],
  watch: true,
  target: 'node',
  externals: [
    nodeExternals({
      whitelist: ['webpack/hot/poll?1000']
    })
  ],
  resolve: {
    alias: {
      handlebars: 'handlebars/dist/handlebars.js'
    }
  },
  module: {
    rules: [
      {
        test: /\.js?$/,
        use: 'babel-loader',
        exclude: /node_modules/
      }
    ]
  },
  plugins: [
    new StartServerPlugin('server.js'),
    new webpack.NamedModulesPlugin(),
    new webpack.HotModuleReplacementPlugin(),
    new webpack.NoEmitOnErrorsPlugin(),
    new webpack.DefinePlugin({
      'process.env': { BUILD_TARGET: JSON.stringify('server') }
    })
  ],
  output: {
    path: path.join(__dirname, '../packages/servers/express/.build'),
    filename: 'server.js'
  }
};
19
otissv

webpack-node-externalsでyarnワークスペースを使用する場合、modulesFromFile: trueを設定するよりも良い解決策は、Webpack構成で次のexternals設定を使用することです。

externals: [
  nodeExternals(),
  nodeExternals({
    modulesDir: path.resolve(__dirname, 'path/to/root/node_modules'),
  }),
],

基本的に、nodeExternalsの2つのインスタンスを使用します。パッケージnode_modulesの場合は1、ルートnode_modulesの場合は1。

8
Max Parelius

@blackxoredのおかげで、プロジェクトで修正できました。

Webpack構成ファイルで次を実行します。

import nodeExternals from 'webpack-node-externals'

それから加えて

externals: [
  nodeExternals({
    modulesFromFile: true,
  }),
],

ワークスペースは、互換性のあるモジュールをルートnode_modulesディレクトリに格納し、互換性のない(異なるsemverなど)モジュールを依存ワークスペースのnode_modulesディレクトリに残します。パッケージが相対パスを使用せずに要求された場合、node_moduleのネイティブパッケージか、ワークスペースの1つからのシンボリックリンクパッケージのいずれかです。これらのパッケージはすべて外部にしたいでしょう。

ルートだけでなくプロジェクト全体ですべてのnode_modulesディレクトリを除外するようにwebpack外部を設定する方法は?

webpackの外部オプションで関数を使用 を試してみます。 requireのコンテキスト、要求されたモジュールの名前、およびこの特定のインポート(require)を外部と見なすべきかどうかを示すコールバックが渡されます。

externals: [
    (ctx, req, cb) => {
        if (!/node_modules/.test(ctx) && req[0] !== '.') {
            // Assumes you have defined an "entries" variable
            let notAnEntry = (path) => {
                return Object.keys(entries).every((entry) => {
                    return entries[entry] !== path
                });
            };

            if (notAnEntry(require.resolve(req))) {
                // This module is external in a commonjs context
                return cb(null, `commonjs ${req}`);
            }
        }

        cb();
    }
]
4
Morgan