npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

cycle-hmr

v0.3.1

Published

Cycle.js hot module replacement (HMR).

Downloads

3

Readme

cycle-hmr

:fire: Hot reloading of cycle.js dataflows without need of restarting your app.

Demo (editing cyclic component's DOM vtree)

ezgif com-resize 1

How does it work?

cycle-hmr utilizes "standard" HMR approach - replacing internals of existing instances with newly updated versions on the fly. It is achieved by proxying cycle components (like it is done for example in React Hot Reloader). In cycle.js application components are pure functions that output sink streams, that makes it quite straightforward to transparently and safely extend them. When updated version of module with cyclic functions arrives (using some hot reload technique) we replace components while their runtime keeping the rest application parts not touched (though of course injection of updated components potentially my cause some "unexpected" effects).

What do you need to use it?

  • Well first you need to use cycle.js. Always. If you still don't.
  • Have a great desire to be more efficient with your development workflow, HMR is about quick feedback loop while dev process, you should use it.
  • Use webpack or broserify for modules loading/bundling. Other loaders (e.g System.js) are not tested and not supported yet.
  • Use ES2015 compatible modules, only ES6's exports are currently suported. CJS modules will be ignored.
  • Use babel transpiler. If you do't use babel for ES2015 => ES5 transformation you can still use it, just for cycle-hmr plugin.
  • Understand that it is experimental feature and bugs are possible.

Supported stream libraries

cycle-hmr is stream library agnostic. So you can use it with any library supported by cyclejs (rx4, rx5, most, xstream) - it will detect and use needed stream adapter, but you should have it installed in your dependencies, if cycle-hmr will not find valid adapter it will just not proxy your streams.

Usage

1) Install from npm

npm install cycle-hmr --save-dev

Also my need to install adapters, but usually they are installed with your cycle run modules (like @cycle/xstream-run)

npm install @cycle/rxjs-adapter @cycle/xstream-adapter --save

2) Configure babel plugin and point to dataflow files

cycle-hmr comes with babel plugin (as dependency).

You should include the babel plugin (for example in .babelrc) and point where files with cyclic dataflows are located (you may also exclude option to point files that should not be processed):

.babelrc:

{
  "env": {
    "development": {
      "plugins": [
        ["cycle-hmr", {
          "include": "**/cycles/**.js"      
        }]
      ]
    }
  }
}

You can also use only specific stream library plugin: "cycle-hmr/xstream"

"development": {
  "plugins": [
    ["cycle-hmr/xstream", {
      "include": "*"      
    }]
  ]
}

Note that include/exclude is a glob matchers - not relative paths, or regexps. If you don't use include/exclude options, no modules will be processed by default. But you can mark files individually with comment on the top:

/* @cycle-hmr */

For each processed module cycle-hmr babel plugin wraps all the exports with (safe) HMR proxy and adds also hot.accept() (webpack/browserify HMR API), so no dependants of the module will be reloaded when module changes.

Note: if it proxies something that it should not, well, unlikely that it will break anything - HMR proxy wrapper is transparent for non-cyclic exports.

NB! if you have non cycle exports in processed modules, and use them somewhere, changes to those exports will not have any effect - so it is recommended to have only cyclic exports in processed modules .

Also you may filter exports names which will be proxied with babel plugin parameter testExportName, for example such config:

{
  "plugins": [
    ["cycle-hmr", {
      "testExportName": "^[A-Z]"
      "include": "*"      
    }]
  ]
}

will process all the files, but will proxy only named exports starting with capital letter (not it will not include default exports in this case, to include them you would use ^([A-Z]|default) regExp expression).

3) Configure bundler/loader for hot-reloading

It is easy to use cycle-hmr with webpack or browserify.

Webpack

Setup you hot reloading workflow with webpack-dev-server and babel-loader using this need parts of config:

  ...
  entry: [
    'webpack-dev-server/client?http://localhost:' + process.env.PORT,
    'webpack/hot/only-dev-server',
    './app.js' // your app's entry
  ]
  module: {
    loaders: [{
      test: /\.js$/,
      loader: 'babel' // .babelrc should plug in `cycle-hmr`
    }]
  },
  plugins: [
    new webpack.NoErrorsPlugin(), // use it
    new webpack.HotModuleReplacementPlugin(),
    new webpack.IgnorePlugin(/most-adapter/) // for adaperts not installed
  ],
  devServer: {
    hot: true,
  ...

NB! To have less problems when dealing with compile and runtime errors, because of existing issues with webpack-dev-server recommendation is to run it using node API, instead of cli (especially avoid --hot and --inline options).

var webpack = require('webpack');
var WebpackDevServer = require('webpack-dev-server');
var config = require('./webpack.config');
new WebpackDevServer(webpack(config), config.devServer)
  .listen(process.env.PORT);

Browserify

Use browserify-hmr plugin and babelify. Use --ingnore-missing option to ignore missing dependencies. For example launch with budo server:

budo entry.js -- -t babelify --ignore-missing -p browserify-hmr

4) Turn on debug output if needed

If there is something wrong and you don't understand what (for example HMR does not work), you may want to turn on the debug output: It will show what happens to components that are proxied.

Fo this add proxy.debug option to cycle-hmr babel plugin:

"plugins": [
  ["cycle-hmr", {
    "include": "**/cycles/**.js",
    "proxy": {
      "debug": "info"
    }
  }]
]

This will turn on debug output for all modules, but you can turn on it individually using the comment on the top of the module:

 /* @cycle-hmr-debug */

Licence

MIT.