6

I’m creating a Javascript library. Inside my project there’s a folder that contains examples of how to use the library. Inside each of the examples is a webpack config file with the entire purpose of bundling that example and serving it over webpack-dev-server with hot reloading. Each of these examples also has the library (at the root of the project) listed as a local NPM dependency. I have hot reloading working for each example and I have babel compiling the library at the root on a watch command.

  • Primary question: Is there a way that I can have the hot reloader of webpack-dev-server respond to changes in that local NPM dependency?
  • Secondary question: Is this intended to be the default behavior of webpack? If so, what is could be wrong with my machine/config file?
  • General/vague question: Am I doing this wrong? I feel like it should be a lot easier to serve local examples (I’m not interested in using Storybook either as the examples I’m writing aren’t in React, Vue, Angular, etc... it's all straight-up vanilla Javascript).

Here's my webpack.config.js file:

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = (env, argv) => ({
  mode: argv.mode,
  entry: './index.js',
  output: {
    path: path.join(__dirname, '/dist'),
    filename: 'index.bundle.js'
  },
  devtool: argv.mode === 'development' ? '#eval-source-map' : 'source-map',
  devServer: {
    port: 8080,
    hot: true,
    open: true,
    stats: {
      children: false, // Hide children information
      maxModules: 0 // Set the maximum number of modules to be shown
    }
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader'
        }
      }
    ]
  },
  plugins: [new HtmlWebpackPlugin({ template: './index.html' })]
});

And my package.json file (note that syft.js is the local dependency I want to watch for changes):

{
  "name": "with-grid",
  "version": "1.0.0",
  "private": true,
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "webpack-dev-server --mode development",
    "build": "rm -rf dist && webpack --mode production",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "",
  "devDependencies": {
    "babel-loader": "^8.0.6",
    "html-webpack-plugin": "^3.2.0",
    "path": "^0.12.7",
    "webpack": "^4.39.1",
    "webpack-cli": "^3.3.7",
    "webpack-dev-server": "^3.7.2"
  },
  "dependencies": {
    "syft.js": "file:../.."
  }
}

Folder structure is like such:

  • dist
    • index.js (Babel-generated file, what package.json points to, and the file that I want to be watched)
  • examples
    • with-grid
      • webpack.config.js (referenced above)
      • package.json (referenced above)
  • src
    • index.js (main src file)

  • Operating System: MacOS 10.14.6
  • Browser: Chrome 76
  • Node: 12.8.0
  • NPM: 6.10.3
  • Yarn: 1.17.3
cereallarceny
  • 4,913
  • 4
  • 39
  • 74
  • can you please clarify the problem you want to solve? From reading your question a few times it sounds like you have a working solution. – Peter Aug 19 '19 at 17:51
  • Sure, I have a working solution for hot-reloading files that are within the `with-grid` folder. However, I want to also watch for files within `node_modules`, specifically the `syft.js` library. Whenever I make a change to a file two directories up, it should also trigger a re-build and reload of that dependency within the `with-grid` folder. – cereallarceny Aug 19 '19 at 17:54
  • 1
    default behaviour of `webapack` should be to watch all files for changes, even `node_modules`. But can try this out: `watch` flag need to be true in main config `watch: true` and then with `watchOptions` [link](https://stackoverflow.com/a/44166532/6082280) – ambianBeing Aug 19 '19 at 18:08

2 Answers2

1

I opted for a different strategy that now seems very obvious in retrospect. Rather than treating my library like a local node dependency that needs to be resolved, I can just simply import it locally.

When importing from my example folder, I do:

import syft from '../../src'; // Like a relative file

Instead of:

import syft from 'syft.js'; // Like an NPM package

After this small change, everything reloads as expected.

cereallarceny
  • 4,913
  • 4
  • 39
  • 74
-2

You can use npm link to create symbolic links between your React app and your local dependencies. Just make sure you build your local dependency to trigger reload in your React app.

  1. Your local dependency should have a "main" and a "name" attributes in the package.json. webpack-dev-server will reload based on changes in your "main"
{
  "name": "my-dep",
  "main": "lib/index.js",
}
  1. Run npm link next to the dependency package.json.
  2. Run npm link my-dep in your React project - it will create a symbolic link between the two projects.
  3. import myDep from 'my-dep in your React project. Reload will be triggered when you change lib/index.js

You can read more here https://medium.com/dailyjs/how-to-use-npm-link-7375b6219557 npm link: https://docs.npmjs.com/cli/link

Barak
  • 97
  • 1
  • 6