Search code examples
javascriptwebpackgulplernamonorepo

Watch for changes in an npm link package being built with webpack


I have the following directory structure:

application
          |
          |__ component-library
             |
             |__src
          |
          |__ app
             |
             |__src

I have used lerna to link component-library in app.

At the minute I am linking to the compiled output of the component-library.

I want to somehow listen for changes in the component library folder which will cause a recompilation.

Would I need to use gulp?


Solution

  • We use yarn workspaces instead of lerna, but its essentially the same thing (--hoist option from lerna by default).

    I'm going to assume that you are starting webpack from the root of application with the watch option set to true (or are using webpack-dev-server) during development, that you have a prepare script setup in component-library's package.json for publishing, and that app lists modules from component-library as dependencies in its package.json (i.e. does not use a relative path during import/require of modules from component-library).

    I want to somehow listen for changes in the component library folder which will cause a recompilation.

    Would I need to use gulp?

    You would need some utility to watch for file changes in component-library, not necessarily gulp, but you could. When a file from component-library changes you would want to rerun the prepare script so that it republishes the package, whereupon webpack would notice a module in its dependency graph changed and would rebuild the root application (possibly kicking of a browser reload depending on your development setup). Note, it is not sufficient to simply watch files in component-library without rebuilding/publishing because webpack has the build of component-library in its dependency graph, not the development source code.

    If you wanted to use gulp a watch task might look something like this:

    import gulp from 'gulp';
    import { spawn } from 'child_process';
    
    gulp.watch('path/to/component-library/src/*.js', () => {
        let prepare = spawn('yarn', ['run', 'prepare'], {
            cwd: 'path/to/component-library',
            stdio: 'inherit'
        });
    
        prepare.on('exit', (code) => {
            if (code !== 0) {
                prepare.emit('end');
            }
        });
    
        // gulp 4 allows returning a child process to signal async completion
        return prepare;
    });
    

    Due to the lerna symlinks webpack's watch option can see a module changed and will rebuild the root application.