How to watch certain node_modules changes with webpack-dev-server
Asked Answered
G

3

39

I'm currently experimenting with a monorepo architecture.

What I would like to do is in my web package where I run webpack dev server I'd like it to watch certain node_modules (symlinked local packages) for changes and trigger a "rebuild".

This way I'd be able to build dependencies separately and my browser would react to those changes.

My webpack config is the following:

var loaders = require('./../../../build/loaders-default');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var path = require('path');
var webpack = require('webpack');

module.exports = {
    entry: ['./src/index.ts'],
    output: {
        filename: 'build.js',
        path: path.join(__dirname, 'dist')
    },
    resolve: {
        extensions: ['.ts', '.js', '.json']
    },
    resolveLoader: {
        modules: ['node_modules']
    },
    devtool: 'inline-source-map',
    devServer: {
        proxy: [
            {
                context: ['/api-v1/**', '/api-v2/**'],
                target: 'https://other-server.example.com',
                secure: false
            }
        ]
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: './src/index.html',
            inject: 'body',
            hash: true
        }),
        new webpack.ProvidePlugin({
            $: 'jquery',
            jQuery: 'jquery',
            'window.jQuery': 'jquery',
            'window.jquery': 'jquery'
        })
    ],
    module:{
        loaders: loaders
    }
};

Loaders are just the usual stuff included.

Guardianship answered 7/1, 2017 at 14:51 Comment(0)
S
37

You can config in in webpack.config file or in WebpackDevServer option, to watch for changes also in node_modules (i think that by default webpack watching for changes in all files)

https://webpack.js.org/configuration/watch/#watchoptions-ignored

in the following example webpack ignored all changes in node_modules folder except specific module.

watchOptions: {
  ignored: [
    /node_modules([\\]+|\/)+(?!some_npm_module_name)/, 
    /\some_npm_module_name([\\]+|\/)node_modules/
  ]
}

ignored[0] = Regex to ignore all node_modules that not started with some_npm_module_name

ignored[1] = Regex to ignore all node_modules inside some_npm_module_name

You may also used this link npm linked modules don’t find their dependencies

Satisfactory answered 24/5, 2017 at 18:59 Comment(3)
this regex is not relevant anymore, for the following reasons: Since npm V5 all the dependencies saved in a flat hierarchy, and the issue of Webpack and linked modules is solved nowSatisfactory
watchOptions: { ignored: [ /node_modules([\\]+|\/)+(?!some_npm_module_name)/ ] }Satisfactory
if possible can you help me with my question #59134090Leandroleaning
P
11

UPDATE: I'm currently using Next.js 11, and it seems this is no longer necessary.

Granted this question is not regarding Next.js or any specific framework, I'd like to post an answer related to Next.js here since I arrived here from Google as others might also.

Here is what worked for me in my next.config.js:

module.exports = {
  // ...
  webpackDevMiddleware: config => {
    // Don't ignore all node modules.
    config.watchOptions.ignored = config.watchOptions.ignored.filter(
      ignore => !ignore.toString().includes('node_modules')
    );

    // Ignore all node modules except those here.
    config.watchOptions.ignored = [
      ...config.watchOptions.ignored,
      /node_modules\/(?!@orgname\/.+)/,
      /\@orgname\/.+\/node_modules/
    ];

    return config;
  },
  // ...
}

This targets a specific organization of packages. If you need to just target a specific package:

module.exports = {
  // ...
  webpackDevMiddleware: config => {
    // Don't ignore all node modules.
    config.watchOptions.ignored = config.watchOptions.ignored.filter(
      ignore => !ignore.toString().includes('node_modules')
    );

    // Ignore all node modules except those here.
    config.watchOptions.ignored = [
      ...config.watchOptions.ignored,
      /node_modules([\\]+|\/)+(?!my-node-module)/,
      /\my-node-module([\\]+|\/)node_modules/
    ];

    return config;
  },
  // ...
}

This builds on Elhay's answer.

Pointdevice answered 28/1, 2020 at 18:31 Comment(2)
You saved my day! Thanks!!Tramp
@Tramp Welcome! I just added to this answer with some improved regexes.Pointdevice
S
3

snapshot.managedPaths

A common use case for managedPaths would be to exclude some folders from node_modules, e.g. you want webpack to know that files in the node_modules/@azure/msal-browser folder are expected to change, which can be done with a regular expression like the one below:

module.exports = {
  snapshot: {
    managedPaths: [
      /^(.+?[\\/]node_modules[\\/](?!(@azure[\\/]msal-browser))(@.+?[\\/])?.+?)[\\/]/,
    ],
  },
};
Supranatural answered 21/2, 2023 at 10:36 Comment(1)
This answer would be even better if it explained how this interacts with watchOptions.ignored. And the purpose of (@.+?[\\/])?.+?)[\\/]/ is unclear.Luggage

© 2022 - 2024 — McMap. All rights reserved.