Giter Club home page Giter Club logo

npm-pipeline-rails's Introduction

End-of-life

July 2020: Rails 6 now recommends using Webpacker to manage frontend dependencies. Thank you to all the contributors who have made npm-pipeline-rails a successful experiment.


npm-pipeline-rails

Use npm as part of your Rails asset pipeline

npm-pipeline-rails allows you to use any toolchain to build your asset files in Rails 4.2+. This allows you to:


See § How it Works for an explanation of the diagram above.


⚠️ Notice ⚠️

Rails 5.1 will be adding official support for Webpack via webpacker. In contrast, npm-pipeline-rails is far less opinionated and more flexible than webpacker, but expect better support from using Rails's official integration.

Usage

Add this line below to your Gemfile. After that, proceed with an automated or manual setup.

gem 'npm-pipeline-rails'

Automated setup

Use the generators for your preferred build tool:

  • Brunch - ./bin/rails generate npm_pipeline:brunch
  • Gulp - ./bin/rails generate npm_pipeline:gulp
  • Webpack - ./bin/rails generate npm_pipeline:webpack

Manual setup

  • Put together a setup with Brunch, Broccoli, Gulp, Webpack or any other tool. It should:
    • Take source files from app/webpack/
    • Render CSS to vendor/assets/stylesheets/webpack/
    • Render JS to vendor/assets/javascripts/webpack/
    • (Replace webpack with whatever build tool you use.)
  • Create a package.json with start and build scripts to point to this setup. (See example)
    • start - Configure this script to run a development file watcher.
    • build - Configure this script to run a production compiler.
  • Add your expected compiled assets to .gitignore.

Set up support for tests

If you're using continuous integration for your tests, configure it to run this before your tests:

npm run build

For tests running in your development machine, ensure that asset files are available when running your tests. This means starting your dev server at least once before running tests, or invoking npm run build manually.

Disable some gems

You may also want to disable some gems, depending on your set up:

  • Disable uglifyjs if you already do minification in your npm tool.
  • Disable autoprefixer-rails if you already do autoprefixing in your npm tool.
  • Disable sprockets-es6 if you already do ES6 compiling in your npm tool.
  • and so on...

Heroku

When deploying to Heroku, use Node.js and Ruby buildpacks together. See: Using Multiple Buildpacks for an App (devcenter.heroku.com)

$ heroku buildpacks:set heroku/ruby
$ heroku buildpacks:add --index 1 heroku/nodejs

Buildpack added. Next release on my-app-name will use:
  1. heroku/nodejs
  2. heroku/ruby

It's recommended to turn off config.npm.install_on_asset_precompile to make deployments faster; see § Configuration.


Configuration

npm-pipeline-rails provides these configuration options below. Put them inside config/application.rb (not in an initializer!).

# These are defaults; in most cases, you don't need to configure anything.

Rails.application.configure do
  # Enables npm_pipeline_rails's invocation of `watch` commands. (v1.5.0+)
  # If `true`, watch commands will be ran alongside Rails's server.
  # Defaults to true in development.
  config.npm.enable_watch = Rails.env.development?

  # Command to install dependencies
  config.npm.install = ['npm install']

  # Command to build production assets
  config.npm.build = ['npm run build']

  # Command to start a file watcher
  config.npm.watch = ['npm run start']

  # The commands are arrays; you may add more commands as needed:
  config.npm.watch = [
    'npm run webpack:start',
    'npm run brunch:start'
  ]

  # If 'true', runs 'npm install' on 'rake assets:precompile'. (v1.6.0+)
  # If you disable this, you'll need to run `npm install` yourself.
  # This is generally desired, but you may set this to false when
  # deploying to Heroku to speed things up.
  config.npm.install_on_asset_precompile = true

  # If 'true', runs 'npm install' on 'rails server'. (v1.7.0+)
  # If you disable this, you'll need to run `npm install` yourself.
  config.npm.install_on_rails_server = true
end

How it works

npm-pipeline-rails allows you to hook certain commands, usually npm scripts, during the Rails app lifecycle. It assumes that your tool will build plain JS and CSS files into vendor/assets, allowing it to be picked up by Rails's asset pipeline.

It does not replace the Rails asset pipeline, but rather it works with it. The files you build with your npm pipeline will be available as regular files in the Rails asset pipeline.

In development

When starting a Rails development server (bundle exec rails s), it runs the install command. After that, it starts a background process that runs your watch command.

In production

When running rake assets:precompile, it will first run the install command then the build command.

More info

Consult railtie.rb for the actual code that makes all these happen.


Yarn

To use Yarn instead of npm, change config.npm.install as seen below in config/application.rb. See § Configuration for more details.

Rails.application.configure do
  # ...

  config.npm.install = ['yarn']
end

Skipping Rails asset pipeline

The recommended setup renders files to vendor/assets/stylesheets/webpack/ and vendor/assets/javascripts/webpack/. (Replace webpack with whatever build tool you use.) You may opt to output to public/assets/stylesheets/ and public/assets/javascripts/ instead.

This is not recommended since you will miss out on automatic asset fingerprinting, among other nice integrations.

If you do this, you will need to run npm run build as part of your deploy script and CI test script.


Motivation

Rails's asset pipeline was a great step forward for Rails 3. For today's requirements however, it doesn't always come with all the tools you need. npm-pipeline-rails lets you outsource asset building complexities to Node.js-based tools.

Read more →


Also see

Thanks

npm-pipeline-rails © 2016+, Rico Sta. Cruz. Released under the MIT License.
Authored and maintained by Rico Sta. Cruz with help from contributors (list).

ricostacruz.com  ·  GitHub @rstacruz  ·  Twitter @rstacruz

npm-pipeline-rails's People

Contributors

aka-cronos avatar drusepth avatar jasontorres avatar mikker avatar rstacruz avatar victorsolis avatar weiland avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

npm-pipeline-rails's Issues

fork() is not implemented on Windows

Hi, is it possible to get this working on a windows machine?

C:/tools/ruby23/lib/ruby/gems/2.3.0/gems/npm-pipeline-rails-1.8.0/lib/npm-pipeline-rails/railtie.rb:24:in `fork': fork() function is unimplemented on this machine (NotImplementedError)
        from C:/tools/ruby23/lib/ruby/gems/2.3.0/gems/npm-pipeline-rails-1.8.0/lib/npm-pipeline-rails/railtie.rb:24:in `background'
        from C:/tools/ruby23/lib/ruby/gems/2.3.0/gems/npm-pipeline-rails-1.8.0/lib/npm-pipeline-rails/railtie.rb:67:in `block (2 levels) in <class:Railtie>'
        from C:/tools/ruby23/lib/ruby/gems/2.3.0/gems/npm-pipeline-rails-1.8.0/lib/npm-pipeline-rails/railtie.rb:66:in `each'
        from C:/tools/ruby23/lib/ruby/gems/2.3.0/gems/npm-pipeline-rails-1.8.0/lib/npm-pipeline-rails/railtie.rb:66:in `block in <class:Railtie>'
        from C:/tools/ruby23/lib/ruby/gems/2.3.0/gems/railties-5.0.3/lib/rails/initializable.rb:30:in `instance_exec'
        from C:/tools/ruby23/lib/ruby/gems/2.3.0/gems/railties-5.0.3/lib/rails/initializable.rb:30:in `run'
        from C:/tools/ruby23/lib/ruby/gems/2.3.0/gems/railties-5.0.3/lib/rails/initializable.rb:55:in `block in run_initializers'
        from C:/tools/ruby23/lib/ruby/2.3.0/tsort.rb:228:in `block in tsort_each'
        from C:/tools/ruby23/lib/ruby/2.3.0/tsort.rb:350:in `block (2 levels) in each_strongly_connected_component'
        from C:/tools/ruby23/lib/ruby/2.3.0/tsort.rb:431:in `each_strongly_connected_component_from'
        from C:/tools/ruby23/lib/ruby/2.3.0/tsort.rb:349:in `block in each_strongly_connected_component'
        from C:/tools/ruby23/lib/ruby/2.3.0/tsort.rb:347:in `each'
        from C:/tools/ruby23/lib/ruby/2.3.0/tsort.rb:347:in `call'
        from C:/tools/ruby23/lib/ruby/2.3.0/tsort.rb:347:in `each_strongly_connected_component'        from C:/tools/ruby23/lib/ruby/2.3.0/tsort.rb:226:in `tsort_each'
        from C:/tools/ruby23/lib/ruby/2.3.0/tsort.rb:205:in `tsort_each'
        from C:/tools/ruby23/lib/ruby/gems/2.3.0/gems/railties-5.0.3/lib/rails/initializable.rb:54:in `run_initializers'
        from C:/tools/ruby23/lib/ruby/gems/2.3.0/gems/railties-5.0.3/lib/rails/application.rb:352:in `initialize!'
        from C:/Users/Tom/Documents/jooktube/config/environment.rb:5:in `<top (required)>'
        from C:/Users/Tom/Documents/jooktube/config.ru:3:in `require_relative'
        from C:/Users/Tom/Documents/jooktube/config.ru:3:in `block in <main>'
        from C:/tools/ruby23/lib/ruby/gems/2.3.0/gems/rack-2.0.3/lib/rack/builder.rb:55:in `instance_eval'
        from C:/tools/ruby23/lib/ruby/gems/2.3.0/gems/rack-2.0.3/lib/rack/builder.rb:55:in `initialize'
        from C:/Users/Tom/Documents/jooktube/config.ru:in `new'
        from C:/Users/Tom/Documents/jooktube/config.ru:in `<main>'
        from C:/tools/ruby23/lib/ruby/gems/2.3.0/gems/rack-2.0.3/lib/rack/builder.rb:49:in `eval'
        from C:/tools/ruby23/lib/ruby/gems/2.3.0/gems/rack-2.0.3/lib/rack/builder.rb:49:in `new_from_string'
        from C:/tools/ruby23/lib/ruby/gems/2.3.0/gems/rack-2.0.3/lib/rack/builder.rb:40:in `parse_file'
        from C:/tools/ruby23/lib/ruby/gems/2.3.0/gems/rack-2.0.3/lib/rack/server.rb:319:in `build_app_and_options_from_config'
        from C:/tools/ruby23/lib/ruby/gems/2.3.0/gems/rack-2.0.3/lib/rack/server.rb:219:in `app'
        from C:/tools/ruby23/lib/ruby/gems/2.3.0/gems/railties-5.0.3/lib/rails/commands/server.rb:84:in `app'
        from C:/tools/ruby23/lib/ruby/gems/2.3.0/gems/rack-2.0.3/lib/rack/server.rb:354:in `wrapped_app'
        from C:/tools/ruby23/lib/ruby/gems/2.3.0/gems/railties-5.0.3/lib/rails/commands/server.rb:148:in `log_to_stdout'
        from C:/tools/ruby23/lib/ruby/gems/2.3.0/gems/railties-5.0.3/lib/rails/commands/server.rb:102:in `start'
        from C:/tools/ruby23/lib/ruby/gems/2.3.0/gems/railties-5.0.3/lib/rails/commands/commands_tasks.rb:90:in `block in server'
        from C:/tools/ruby23/lib/ruby/gems/2.3.0/gems/railties-5.0.3/lib/rails/commands/commands_tasks.rb:85:in `tap'
        from C:/tools/ruby23/lib/ruby/gems/2.3.0/gems/railties-5.0.3/lib/rails/commands/commands_tasks.rb:85:in `server'
        from C:/tools/ruby23/lib/ruby/gems/2.3.0/gems/railties-5.0.3/lib/rails/commands/commands_tasks.rb:49:in `run_command!'
        from C:/tools/ruby23/lib/ruby/gems/2.3.0/gems/railties-5.0.3/lib/rails/commands.rb:18:in `<top (required)>'
        from bin/rails:4:in `require'
        from bin/rails:4:in `<main>'

Sprockets 4 support

Currently npm-pipeline-rails requires sprockets (~>3.5). I know that 4 is in beta, any chances to make it work?

application.css

Hello,

I am using my application.scss file rather than my application.css file (I actually deleted my application.css file, because it is empty and it was conflicting with my Rails site (Rails started automatically using the application.css)) -

But - when I try and use the Brunch generator, it fails here:

/Users/vasilioskaloidis/Code/Rails/tidbits/vendor/ruby/2.3.0/gems/thor-0.19.1/lib/thor/actions/inject_into_file.rb:98:in `binread': No such file or directory @ rb_sysopen - /Users/vasilioskaloidis/Code/Rails/tidbits/app/assets/stylesheets/application.css (Errno::ENOENT)

tidbits master % rails generate npm_pipeline:brunch identical package.json identical brunch-config.js append app/assets/stylesheets/application.css /Users/vasilioskaloidis/Code/Rails/tidbits/vendor/ruby/2.3.0/gems/thor-0.19.1/lib/thor/actions/inject_into_file.rb:98:inbinread': No such file or directory @ rb_sysopen - /Users/vasilioskaloidis/Code/Rails/tidbits/app/assets/stylesheets/application.css (Errno::ENOENT)
from /Users/vasilioskaloidis/Code/Rails/tidbits/vendor/ruby/2.3.0/gems/thor-0.19.1/lib/thor/actions/inject_into_file.rb:98:in replace!' from /Users/vasilioskaloidis/Code/Rails/tidbits/vendor/ruby/2.3.0/gems/thor-0.19.1/lib/thor/actions/inject_into_file.rb:59:in invoke!'
from /Users/vasilioskaloidis/Code/Rails/tidbits/vendor/ruby/2.3.0/gems/thor-0.19.1/lib/thor/actions.rb:94:in action' from /Users/vasilioskaloidis/Code/Rails/tidbits/vendor/ruby/2.3.0/gems/thor-0.19.1/lib/thor/actions/inject_into_file.rb:30:in insert_into_file'
from /Users/vasilioskaloidis/Code/Rails/tidbits/vendor/ruby/2.3.0/gems/thor-0.19.1/lib/thor/actions/file_manipulation.rb:180:in append_to_file' from /Users/vasilioskaloidis/Code/Rails/tidbits/vendor/ruby/2.3.0/gems/npm-pipeline-rails-1.6.2/lib/generators/npm_pipeline/brunch_generator.rb:18:in update_assets'
from /Users/vasilioskaloidis/Code/Rails/tidbits/vendor/ruby/2.3.0/gems/thor-0.19.1/lib/thor/command.rb:27:in run' from /Users/vasilioskaloidis/Code/Rails/tidbits/vendor/ruby/2.3.0/gems/thor-0.19.1/lib/thor/invocation.rb:126:in invoke_command'
from /Users/vasilioskaloidis/Code/Rails/tidbits/vendor/ruby/2.3.0/gems/thor-0.19.1/lib/thor/invocation.rb:133:in block in invoke_all' from /Users/vasilioskaloidis/Code/Rails/tidbits/vendor/ruby/2.3.0/gems/thor-0.19.1/lib/thor/invocation.rb:133:in each'
from /Users/vasilioskaloidis/Code/Rails/tidbits/vendor/ruby/2.3.0/gems/thor-0.19.1/lib/thor/invocation.rb:133:in map' from /Users/vasilioskaloidis/Code/Rails/tidbits/vendor/ruby/2.3.0/gems/thor-0.19.1/lib/thor/invocation.rb:133:in invoke_all'
from /Users/vasilioskaloidis/Code/Rails/tidbits/vendor/ruby/2.3.0/gems/thor-0.19.1/lib/thor/group.rb:232:in dispatch' from /Users/vasilioskaloidis/Code/Rails/tidbits/vendor/ruby/2.3.0/gems/thor-0.19.1/lib/thor/base.rb:440:in start'
from /Users/vasilioskaloidis/Code/Rails/tidbits/vendor/ruby/2.3.0/gems/railties-5.0.0.1/lib/rails/generators.rb:180:in invoke' from /Users/vasilioskaloidis/Code/Rails/tidbits/vendor/ruby/2.3.0/gems/railties-5.0.0.1/lib/rails/commands/generate.rb:13:in <top (required)>'
from /Users/vasilioskaloidis/Code/Rails/tidbits/vendor/ruby/2.3.0/gems/activesupport-5.0.0.1/lib/active_support/dependencies.rb:293:in require' from /Users/vasilioskaloidis/Code/Rails/tidbits/vendor/ruby/2.3.0/gems/activesupport-5.0.0.1/lib/active_support/dependencies.rb:293:in block in require'
from /Users/vasilioskaloidis/Code/Rails/tidbits/vendor/ruby/2.3.0/gems/activesupport-5.0.0.1/lib/active_support/dependencies.rb:259:in load_dependency' from /Users/vasilioskaloidis/Code/Rails/tidbits/vendor/ruby/2.3.0/gems/activesupport-5.0.0.1/lib/active_support/dependencies.rb:293:in require'
from /Users/vasilioskaloidis/Code/Rails/tidbits/vendor/ruby/2.3.0/gems/railties-5.0.0.1/lib/rails/commands/commands_tasks.rb:138:in require_command!' from /Users/vasilioskaloidis/Code/Rails/tidbits/vendor/ruby/2.3.0/gems/railties-5.0.0.1/lib/rails/commands/commands_tasks.rb:145:in generate_or_destroy'
from /Users/vasilioskaloidis/Code/Rails/tidbits/vendor/ruby/2.3.0/gems/railties-5.0.0.1/lib/rails/commands/commands_tasks.rb:60:in generate' from /Users/vasilioskaloidis/Code/Rails/tidbits/vendor/ruby/2.3.0/gems/railties-5.0.0.1/lib/rails/commands/commands_tasks.rb:49:in run_command!'
from /Users/vasilioskaloidis/Code/Rails/tidbits/vendor/ruby/2.3.0/gems/railties-5.0.0.1/lib/rails/commands.rb:18:in <top (required)>' from /Users/vasilioskaloidis/Code/Rails/tidbits/vendor/ruby/2.3.0/gems/activesupport-5.0.0.1/lib/active_support/dependencies.rb:293:in require'
from /Users/vasilioskaloidis/Code/Rails/tidbits/vendor/ruby/2.3.0/gems/activesupport-5.0.0.1/lib/active_support/dependencies.rb:293:in block in require' from /Users/vasilioskaloidis/Code/Rails/tidbits/vendor/ruby/2.3.0/gems/activesupport-5.0.0.1/lib/active_support/dependencies.rb:259:in load_dependency'
from /Users/vasilioskaloidis/Code/Rails/tidbits/vendor/ruby/2.3.0/gems/activesupport-5.0.0.1/lib/active_support/dependencies.rb:293:in require' from bin/rails:4:in

'

`

Using other static assets

Thank you for building npm-pipeline-rails. I have been using it and it is a really good solution to easily integrate npm scripts (webpack in our case) with the rails asset pipeline. 👍

Processing CSS and JavaScript works perfectly!
At the moment I got stuck with image assets.
Theoretically, all static assets could be placed into the public folder. However, there are some images and svgs wich run through webpack to be optimised or concatenated.
And for caching-reasons, I do not want to inline images and svgs into the JavaScript bundle but rather use them as single files.
The problem with this approach is, that due to the asset pipeline's fingerprinting the files cannot be accessed without using a rails helper.

💡 My ideas so far:

  • moving all assets to the public directory
    • this works good for static assets that don't change or don't need to be processed
  • rake assets:precompile creates a .sprockets-manifest-*.json file which maps the filenames
    • There is no rails-helper available, so I don't know the filename in my JS and I actually don't want to load the manifest json
    • The fingerprint is good for dealing with the cache

Is there a good way to deal with assets, especially images and svgs? Can the fingerprint be obtained somehow in a good way?

I would like to know whether someone else did run into the same problem and whether there are some approaches to solve that problem. 🤔

Thanks!

Prevent kill errors

When pressing ^C, Process.kill sometimes happens with the process already exited (maybe cleanly) before it's able to kill it. It's a harmless error, but it can be suppressed to make things less confusing.

[npm-pipeline-rails] Terminating 'npm run start' [78253]
/.../gems/npm-pipeline-rails-1.1.3/lib/npm-pipeline-rails/railtie.rb:28:in `kill': No such process (Errno::ESRCH)
        from /.../gems/npm-pipeline-rails-1.1.3/lib/npm-pipeline-rails/railtie.rb:28:in `block in background'

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.