pax_global_header00006660000000000000000000000064131452457230014520gustar00rootroot0000000000000052 comment=83a5d4c8af82e1f33116e3550d3bc3e8ecff977f webpack-rails-0.9.11/000077500000000000000000000000001314524572300143345ustar00rootroot00000000000000webpack-rails-0.9.11/.gitignore000066400000000000000000000000471314524572300163250ustar00rootroot00000000000000.bundle/ .ruby-version pkg/ log/ rdoc/ webpack-rails-0.9.11/.rubocop.yml000066400000000000000000000044501314524572300166110ustar00rootroot00000000000000# Reference: # https://github.com/bbatsov/rubocop/blob/v0.33.0/config/default.yml # https://github.com/bbatsov/rubocop/blob/v0.33.0/config/enabled.yml # https://github.com/bbatsov/rubocop/blob/v0.33.0/config/enabled.yml # Many of the variations are because rubocop prefers things to look like: # foo = foo(a, # b # ) # # where we prefer: # foo = foo(a, # b # ) AllCops: DisplayCopNames: true DisplayStyleGuide: true Exclude: - "*.gemspec" # Don't force end alignment to be versus the opening if/while - it should # be with the code flow, which isn't an option. Lint/EndAlignment: Enabled: false # Can't configure it to force last argument to be via code flow, so we ignore the rule Style/AlignHash: EnforcedLastArgumentHashStyle: always_ignore # indent call parameters against code flow, not method call opening Style/AlignParameters: EnforcedStyle: with_fixed_indentation # indent case statements against code flow, not assignment Style/CaseIndentation: IndentWhenRelativeTo: end # indents against opening paren, not code flow Style/ClosingParenthesisIndentation: Enabled: false # if branches should be indented against code flow, not if Style/ElseAlignment: Enabled: false # indent first param on next line against code flow, not opening statement Style/FirstParameterIndentation: EnforcedStyle: consistent # sprintf is much more common than format Style/FormatString: EnforcedStyle: format # hashes should be indented against code flow, not assignment Style/IndentHash: EnforcedStyle: consistent # indents against opening block, not code flow Style/IndentationWidth: Enabled: false # align with code flow Style/MultilineOperationIndentation: EnforcedStyle: indented # different methods calls that do exactly the same thing are a smell, regardless of semantics Style/SignalException: EnforcedStyle: only_raise # we don't care whether you use ' or " Style/StringLiterals: Enabled: false # "Refactor" severity - intended as warnings, not violations Metrics/LineLength: Severity: refactor Max: 180 Metrics/ClassLength: Severity: refactor Max: 300 Metrics/MethodLength: Max: 30 Severity: refactor Metrics/CyclomaticComplexity: Max: 10 Severity: refactor Metrics/PerceivedComplexity: Severity: refactor Metrics/AbcSize: Max: 30 Severity: refactor webpack-rails-0.9.11/.travis.yml000066400000000000000000000001241314524572300164420ustar00rootroot00000000000000language: ruby rvm: - "2.1.7" - "2.2.2" - "2.3.1" script: bundle exec rake spec webpack-rails-0.9.11/CHANGELOG.md000066400000000000000000000010531314524572300161440ustar00rootroot00000000000000# CHANGELOG ## v0.9.10 * Only error if manifest error was a module build failure (Juan-Carlos Medina and Naomi Jacobs ) * Change dependency to railties (Mike Auclair ) * Only enable dev server in development & test (Agis Anastasopoulos ) * Use existing NODE_ENV if available (Alex ) * Switched README & generators to use yarn over npm * Allow SSL certificate verification for localhost connections (Marek Hulan ) webpack-rails-0.9.11/Gemfile000066400000000000000000000001321314524572300156230ustar00rootroot00000000000000source 'https://rubygems.org' gem 'rspec' gem 'webmock' gem 'rubocop' gem 'rake' gemspec webpack-rails-0.9.11/Gemfile.lock000066400000000000000000000071171314524572300165640ustar00rootroot00000000000000PATH remote: . specs: webpack-rails (0.9.11) railties (>= 3.2.0) GEM remote: https://rubygems.org/ specs: actionmailer (4.2.6) actionpack (= 4.2.6) actionview (= 4.2.6) activejob (= 4.2.6) mail (~> 2.5, >= 2.5.4) rails-dom-testing (~> 1.0, >= 1.0.5) actionpack (4.2.6) actionview (= 4.2.6) activesupport (= 4.2.6) rack (~> 1.6) rack-test (~> 0.6.2) rails-dom-testing (~> 1.0, >= 1.0.5) rails-html-sanitizer (~> 1.0, >= 1.0.2) actionview (4.2.6) activesupport (= 4.2.6) builder (~> 3.1) erubis (~> 2.7.0) rails-dom-testing (~> 1.0, >= 1.0.5) rails-html-sanitizer (~> 1.0, >= 1.0.2) activejob (4.2.6) activesupport (= 4.2.6) globalid (>= 0.3.0) activemodel (4.2.6) activesupport (= 4.2.6) builder (~> 3.1) activerecord (4.2.6) activemodel (= 4.2.6) activesupport (= 4.2.6) arel (~> 6.0) activesupport (4.2.6) i18n (~> 0.7) json (~> 1.7, >= 1.7.7) minitest (~> 5.1) thread_safe (~> 0.3, >= 0.3.4) tzinfo (~> 1.1) addressable (2.3.8) arel (6.0.3) ast (2.1.0) astrolabe (1.3.1) parser (~> 2.2) builder (3.2.2) concurrent-ruby (1.0.2) crack (0.4.2) safe_yaml (~> 1.0.0) diff-lcs (1.2.5) erubis (2.7.0) globalid (0.3.6) activesupport (>= 4.1.0) i18n (0.7.0) json (1.8.3) loofah (2.0.3) nokogiri (>= 1.5.9) mail (2.6.4) mime-types (>= 1.16, < 4) mime-types (3.0) mime-types-data (~> 3.2015) mime-types-data (3.2016.0221) mini_portile2 (2.0.0) minitest (5.9.0) nokogiri (1.6.7.2) mini_portile2 (~> 2.0.0.rc2) parser (2.2.2.6) ast (>= 1.1, < 3.0) powerpack (0.1.1) rack (1.6.4) rack-test (0.6.3) rack (>= 1.0) rails (4.2.6) actionmailer (= 4.2.6) actionpack (= 4.2.6) actionview (= 4.2.6) activejob (= 4.2.6) activemodel (= 4.2.6) activerecord (= 4.2.6) activesupport (= 4.2.6) bundler (>= 1.3.0, < 2.0) railties (= 4.2.6) sprockets-rails rails-deprecated_sanitizer (1.0.3) activesupport (>= 4.2.0.alpha) rails-dom-testing (1.0.7) activesupport (>= 4.2.0.beta, < 5.0) nokogiri (~> 1.6.0) rails-deprecated_sanitizer (>= 1.0.1) rails-html-sanitizer (1.0.3) loofah (~> 2.0) railties (4.2.6) actionpack (= 4.2.6) activesupport (= 4.2.6) rake (>= 0.8.7) thor (>= 0.18.1, < 2.0) rainbow (2.0.0) rake (10.5.0) rspec (3.2.0) rspec-core (~> 3.2.0) rspec-expectations (~> 3.2.0) rspec-mocks (~> 3.2.0) rspec-core (3.2.2) rspec-support (~> 3.2.0) rspec-expectations (3.2.0) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.2.0) rspec-mocks (3.2.1) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.2.0) rspec-support (3.2.2) rubocop (0.33.0) astrolabe (~> 1.3) parser (>= 2.2.2.5, < 3.0) powerpack (~> 0.1) rainbow (>= 1.99.1, < 3.0) ruby-progressbar (~> 1.4) ruby-progressbar (1.7.5) safe_yaml (1.0.4) sprockets (3.6.0) concurrent-ruby (~> 1.0) rack (> 1, < 3) sprockets-rails (3.0.4) actionpack (>= 4.0) activesupport (>= 4.0) sprockets (>= 3.0.0) thor (0.19.1) thread_safe (0.3.5) tzinfo (1.2.2) thread_safe (~> 0.1) webmock (1.21.0) addressable (>= 2.3.6) crack (>= 0.3.2) PLATFORMS ruby DEPENDENCIES rails (>= 3.2.0) rake rspec rubocop webmock webpack-rails! BUNDLED WITH 1.15.3 webpack-rails-0.9.11/MIT-LICENSE000066400000000000000000000020371314524572300157720ustar00rootroot00000000000000Copyright 2015 Michael Pearson Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. webpack-rails-0.9.11/README.md000066400000000000000000000154621314524572300156230ustar00rootroot00000000000000# No Longer Maintained Hi! `webpack-rails` is no longer being maintained. Please see #90 for more info. [![Build Status](https://travis-ci.org/mipearson/webpack-rails.svg?branch=master)](https://travis-ci.org/mipearson/webpack-rails) [![Gem Version](https://badge.fury.io/rb/webpack-rails.svg)](http://badge.fury.io/rb/webpack-rails) # webpack-rails **webpack-rails** gives you tools to integrate Webpack in to an existing Ruby on Rails application. It will happily co-exist with sprockets but does not use it for production fingerprinting or asset serving. **webpack-rails** is designed with the assumption that if you're using Webpack you treat Javascript as a first-class citizen. This means that you control the webpack config, package.json, and use yarn to install Webpack & its plugins. In development mode [webpack-dev-server](http://webpack.github.io/docs/webpack-dev-server.html) is used to serve webpacked entry points and offer hot module reloading. In production entry points are built in to `public/webpack`. **webpack-rails** uses [stats-webpack-plugin](https://www.npmjs.com/package/stats-webpack-plugin) to translate entry points in to asset paths. It was designed for use at [Marketplacer](http://www.marketplacer.com) to assist us in migrating our Javascript (and possibly our SCSS) off of Sprockets. It first saw production use in June 2015. Our examples show **webpack-rails** co-existing with sprockets (as that's how environment works), but sprockets is not used or required for development or production use of this gem. This gem has been tested against Rails 4.2 and Ruby 2.2. Earlier versions of Rails (>= 3.2) and Ruby (>= 2.0) may work, but we haven't tested them. ## Using webpack-rails **We have a demo application: [webpack-rails-demo](https://github.com/mipearson/webpack-rails-demo)** ### Installation 1. Install [yarn](https://yarnpkg.com/en/docs/install) if you haven't already 1. Add `webpack-rails` to your gemfile 1. Run `bundle install` to install the gem 1. Run `bundle exec rails generate webpack_rails:install` to copy across example files 1. Run `foreman start` to start `webpack-dev-server` and `rails server` at the same time 1. Add the webpack entry point to your layout (see next section) 1. Edit `webpack/application.js` and write some code ### Adding the entry point to your Rails application To add your webpacked javascript in to your app, add the following to the `` section of your to your `layout.html.erb`: ```erb <%= javascript_include_tag *webpack_asset_paths("application") %> ``` Take note of the splat (`*`): `webpack_asset_paths` returns an array, as one entry point can map to multiple paths, especially if hot reloading is enabled in Webpack. If your webpack is configured to output both CSS and JS, you can use the `extension:` argument to filter which files are returned by the helper: ```erb <%= javascript_include_tag *webpack_asset_paths('application', extension: 'js') %> <%= stylesheet_link_tag *webpack_asset_paths('application', extension: 'css') %> ``` #### Use with webpack-dev-server live reload If you're using the webpack dev server's live reload feature (not the React hot reloader), you'll also need to include the following in your layout template: ``` html ``` ### How it works Have a look at the files in the `examples` directory. Of note: * We use [foreman](https://github.com/ddollar/foreman) and a `Procfile` to run our rails server & the webpack dev server in development at the same time * The webpack and gem configuration must be in sync - look at our railtie for configuration options * We require that **stats-webpack-plugin** is loaded to automatically generate a production manifest & resolve paths during development ### Configuration Defaults * Webpack configuration lives in `config/webpack.config.js` * Webpack & Webpack Dev Server binaries are in `node_modules/.bin/` * Webpack Dev Server will run on port 3808 on localhost via HTTP * Webpack Dev Server is enabled in development & test, but not in production * Webpacked assets will be compiled to `public/webpack` * The manifest file is named `manifest.json` #### Dynamic host To have the host evaluated at request-time, set `host` to a proc: ```ruby config.webpack.dev_server.host = proc { request.host } ``` This is useful when accessing your Rails app over the network (remember to bind both your Rails app and your WebPack server to `0.0.0.0`). #### Use with docker-compose If you're running `webpack-dev-server` as part of docker compose rather than `foreman`, you might find that the host and port that rails needs to use to retrieve the manifest isn't the same as the host and port that you'll be giving to the browser to retrieve the assets. If so, you can set the `manifest_host` and `manifest_port` away from their default of `localhost` and port 3808. ### Working with browser tests In development, we make sure that the `webpack-dev-server` is running when browser tests are running. #### Continuous Integration In CI, we manually run `webpack` to compile the assets to public and set `config.webpack.dev_server.enabled` to `false` in our `config/environments/test.rb`: ``` ruby config.webpack.dev_server.enabled = !ENV['CI'] ``` ### Production Deployment Add `rake webpack:compile` to your deployment. It serves a similar purpose as Sprockets' `assets:precompile` task. If you're using Webpack and Sprockets (as we are at Marketplacer) you'll need to run both tasks - but it doesn't matter which order they're run in. If you deploy to Heroku, you can add the special [webpack-rails-buildpack](https://github.com/febeling/webpack-rails-buildpack) in order to perform this rake task on each deployment. If you're using `[chunkhash]` in your build asset filenames (which you should be, if you want to cache them in production), you'll need to persist built assets between deployments. Consider in-flight requests at the time of deployment: they'll receive paths based on the old `manifest.json`, not the new one. ## TODO * Drive config via JSON, have webpack.config.js read same JSON? * Custom webpack-dev-server that exposes errors, stats, etc * [react-rails](https://github.com/reactjs/react-rails) fork for use with this workflow * Integration tests ## Contributing Pull requests & issues welcome. Advice & criticism regarding webpack config approach also welcome. Please ensure that pull requests pass both rubocop & rspec. New functionality should be discussed in an issue first. ## Acknowledgements * Len Garvey for his [webpack-rails](https://github.com/lengarvey/webpack-rails) gem which inspired this implementation * Sebastian Porto for [Rails with Webpack](https://reinteractive.net/posts/213-rails-with-webpack-why-and-how) * Clark Dave for [How to use Webpack with Rails](http://clarkdave.net/2015/01/how-to-use-webpack-with-rails/) webpack-rails-0.9.11/Rakefile000066400000000000000000000010411314524572300157750ustar00rootroot00000000000000begin require 'bundler/setup' rescue LoadError puts 'You must `gem install bundler` and `bundle install` to run rake tasks' end require 'rdoc/task' require 'rspec/core/rake_task' require 'rubocop/rake_task' RuboCop::RakeTask.new RSpec::Core::RakeTask.new(:spec) RDoc::Task.new(:rdoc) do |rdoc| rdoc.rdoc_dir = 'rdoc' rdoc.title = 'WebpackRails' rdoc.options << '--line-numbers' rdoc.rdoc_files.include('README.md') rdoc.rdoc_files.include('lib/**/*.rb') end Bundler::GemHelper.install_tasks task default: [:rubocop, :spec] webpack-rails-0.9.11/example/000077500000000000000000000000001314524572300157675ustar00rootroot00000000000000webpack-rails-0.9.11/example/Procfile000066400000000000000000000002731314524572300174570ustar00rootroot00000000000000# Run Rails & Webpack concurrently # Example file from webpack-rails gem rails: bundle exec rails server webpack: ./node_modules/.bin/webpack-dev-server --config config/webpack.config.js webpack-rails-0.9.11/example/dot_gitignore000066400000000000000000000003001314524572300205400ustar00rootroot00000000000000 # Ignore bundler config. /.bundle # Ignore all logfiles and tempfiles. /log/* !/log/.keep /tmp # Don't commit node_modules (vendored npm bits) or built assets /node_modules /public/webpack webpack-rails-0.9.11/example/package.json000066400000000000000000000003151314524572300202540ustar00rootroot00000000000000{ "name": "webpack-rails-example", "version": "0.0.1", "license": "MIT", "dependencies": { "stats-webpack-plugin": "^0.4.3", "webpack": "^1.14.0", "webpack-dev-server": "^1.16.2" } } webpack-rails-0.9.11/example/webpack.config.js000066400000000000000000000035271314524572300212140ustar00rootroot00000000000000// Example webpack configuration with asset fingerprinting in production. 'use strict'; var path = require('path'); var webpack = require('webpack'); var StatsPlugin = require('stats-webpack-plugin'); // must match config.webpack.dev_server.port var devServerPort = 3808; // set NODE_ENV=production on the environment to add asset fingerprints var production = process.env.NODE_ENV === 'production'; var config = { entry: { // Sources are expected to live in $app_root/webpack 'application': './webpack/application.js' }, output: { // Build assets directly in to public/webpack/, let webpack know // that all webpacked assets start with webpack/ // must match config.webpack.output_dir path: path.join(__dirname, '..', 'public', 'webpack'), publicPath: '/webpack/', filename: production ? '[name]-[chunkhash].js' : '[name].js' }, resolve: { root: path.join(__dirname, '..', 'webpack') }, plugins: [ // must match config.webpack.manifest_filename new StatsPlugin('manifest.json', { // We only need assetsByChunkName chunkModules: false, source: false, chunks: false, modules: false, assets: true })] }; if (production) { config.plugins.push( new webpack.NoErrorsPlugin(), new webpack.optimize.UglifyJsPlugin({ compressor: { warnings: false }, sourceMap: false }), new webpack.DefinePlugin({ 'process.env': { NODE_ENV: JSON.stringify('production') } }), new webpack.optimize.DedupePlugin(), new webpack.optimize.OccurenceOrderPlugin() ); } else { config.devServer = { port: devServerPort, headers: { 'Access-Control-Allow-Origin': '*' } }; config.output.publicPath = '//localhost:' + devServerPort + '/webpack/'; // Source maps config.devtool = 'cheap-module-eval-source-map'; } module.exports = config; webpack-rails-0.9.11/lib/000077500000000000000000000000001314524572300151025ustar00rootroot00000000000000webpack-rails-0.9.11/lib/generators/000077500000000000000000000000001314524572300172535ustar00rootroot00000000000000webpack-rails-0.9.11/lib/generators/webpack_rails/000077500000000000000000000000001314524572300220615ustar00rootroot00000000000000webpack-rails-0.9.11/lib/generators/webpack_rails/install_generator.rb000066400000000000000000000032471314524572300261300ustar00rootroot00000000000000module WebpackRails # :nodoc: class InstallGenerator < ::Rails::Generators::Base source_root File.expand_path("../../../../example", __FILE__) desc "Install everything you need for a basic webpack-rails integration" def add_foreman_to_gemfile gem 'foreman' end def copy_procfile copy_file "Procfile", "Procfile" end def copy_package_json copy_file "package.json", "package.json" end def copy_webpack_conf copy_file "webpack.config.js", "config/webpack.config.js" end def create_webpack_application_js empty_directory "webpack" create_file "webpack/application.js" do <<-EOF.strip_heredoc console.log("Hello world!"); EOF end end def add_to_gitignore append_to_file ".gitignore" do <<-EOF.strip_heredoc # Added by webpack-rails /node_modules /public/webpack EOF end end def run_yarn_install run "yarn install" if yes?("Would you like us to run 'yarn install' for you?") end def run_bundle_install run "bundle install" if yes?("Would you like us to run 'bundle install' for you?") end def whats_next puts <<-EOF.strip_heredoc We've set up the basics of webpack-rails for you, but you'll still need to: 1. Add the 'application' entry point in to your layout, and 2. Run 'foreman start' to run the webpack-dev-server and rails server See the README.md for this gem at https://github.com/mipearson/webpack-rails/blob/master/README.md for more info. Thanks for using webpack-rails! EOF end end end webpack-rails-0.9.11/lib/tasks/000077500000000000000000000000001314524572300162275ustar00rootroot00000000000000webpack-rails-0.9.11/lib/tasks/webpack.rake000066400000000000000000000012361314524572300205110ustar00rootroot00000000000000namespace :webpack do desc "Compile webpack bundles" task compile: :environment do ENV["TARGET"] = 'production' # TODO: Deprecated, use NODE_ENV instead ENV["NODE_ENV"] ||= 'production' webpack_bin = ::Rails.root.join(::Rails.configuration.webpack.binary) config_file = ::Rails.root.join(::Rails.configuration.webpack.config_file) unless File.exist?(webpack_bin) raise "Can't find our webpack executable at #{webpack_bin} - have you run `npm install`?" end unless File.exist?(config_file) raise "Can't find our webpack config file at #{config_file}" end sh "#{webpack_bin} --config #{config_file} --bail" end end webpack-rails-0.9.11/lib/webpack-rails.rb000066400000000000000000000000301314524572300201440ustar00rootroot00000000000000require 'webpack/rails' webpack-rails-0.9.11/lib/webpack/000077500000000000000000000000001314524572300165165ustar00rootroot00000000000000webpack-rails-0.9.11/lib/webpack/rails.rb000066400000000000000000000001271314524572300201550ustar00rootroot00000000000000require 'webpack/rails/version' require 'webpack/railtie' if defined? ::Rails::Railtie webpack-rails-0.9.11/lib/webpack/rails/000077500000000000000000000000001314524572300176305ustar00rootroot00000000000000webpack-rails-0.9.11/lib/webpack/rails/helper.rb000066400000000000000000000023021314524572300214310ustar00rootroot00000000000000require 'action_view' require 'webpack/rails/manifest' module Webpack module Rails # Asset path helpers for use with webpack module Helper # Return asset paths for a particular webpack entry point. # # Response may either be full URLs (eg http://localhost/...) if the dev server # is in use or a host-relative URl (eg /webpack/...) if assets are precompiled. # # Will raise an error if our manifest can't be found or the entry point does # not exist. def webpack_asset_paths(source, extension: nil) return "" unless source.present? paths = Webpack::Rails::Manifest.asset_paths(source) paths = paths.select { |p| p.ends_with? ".#{extension}" } if extension port = ::Rails.configuration.webpack.dev_server.port protocol = ::Rails.configuration.webpack.dev_server.https ? 'https' : 'http' host = ::Rails.configuration.webpack.dev_server.host host = instance_eval(&host) if host.respond_to?(:call) if ::Rails.configuration.webpack.dev_server.enabled paths.map! do |p| "#{protocol}://#{host}:#{port}#{p}" end end paths end end end end webpack-rails-0.9.11/lib/webpack/rails/manifest.rb000066400000000000000000000071211314524572300217640ustar00rootroot00000000000000require 'net/http' require 'uri' module Webpack module Rails # Webpack manifest loading, caching & entry point retrieval class Manifest # Raised if we can't read our webpack manifest for whatever reason class ManifestLoadError < StandardError def initialize(message, orig) super "#{message} (original error #{orig})" end end # Raised if webpack couldn't build one of your entry points class WebpackError < StandardError def initialize(errors) super "Error in webpack compile, details follow below:\n#{errors.join("\n\n")}" end end # Raised if a supplied entry point does not exist in the webpack manifest class EntryPointMissingError < StandardError end class << self # :nodoc: def asset_paths(source) raise WebpackError, manifest["errors"] unless manifest_bundled? paths = manifest["assetsByChunkName"][source] if paths # Can be either a string or an array of strings. # Do not include source maps as they are not javascript [paths].flatten.reject { |p| p =~ /.*\.map$/ }.map do |p| "/#{::Rails.configuration.webpack.public_path}/#{p}" end else raise EntryPointMissingError, "Can't find entry point '#{source}' in webpack manifest" end end private def manifest_bundled? !manifest["errors"].any? { |error| error.include? "Module build failed" } end def manifest if ::Rails.configuration.webpack.dev_server.enabled # Don't cache if we're in dev server mode, manifest may change ... load_manifest else # ... otherwise cache at class level, as JSON loading/parsing can be expensive @manifest ||= load_manifest end end def load_manifest data = if ::Rails.configuration.webpack.dev_server.enabled load_dev_server_manifest else load_static_manifest end JSON.parse(data) end def load_dev_server_manifest host = ::Rails.configuration.webpack.dev_server.manifest_host port = ::Rails.configuration.webpack.dev_server.manifest_port http = Net::HTTP.new(host, port) http.use_ssl = ::Rails.configuration.webpack.dev_server.https http.verify_mode = ::Rails.configuration.webpack.dev_server.https_verify_peer ? OpenSSL::SSL::VERIFY_PEER : OpenSSL::SSL::VERIFY_NONE http.get(dev_server_path).body rescue => e raise ManifestLoadError.new("Could not load manifest from webpack-dev-server at http://#{host}:#{port}#{dev_server_path} - is it running, and is stats-webpack-plugin loaded?", e) end def load_static_manifest File.read(static_manifest_path) rescue => e raise ManifestLoadError.new("Could not load compiled manifest from #{static_manifest_path} - have you run `rake webpack:compile`?", e) end def static_manifest_path ::Rails.root.join( ::Rails.configuration.webpack.output_dir, ::Rails.configuration.webpack.manifest_filename ) end def dev_server_path "/#{::Rails.configuration.webpack.public_path}/#{::Rails.configuration.webpack.manifest_filename}" end def dev_server_url "http://#{::Rails.configuration.webpack.dev_server.host}:#{::Rails.configuration.webpack.dev_server.port}#{dev_server_path}" end end end end end webpack-rails-0.9.11/lib/webpack/rails/version.rb000066400000000000000000000001131314524572300216350ustar00rootroot00000000000000module Webpack # :nodoc: module Rails VERSION = "0.9.11" end end webpack-rails-0.9.11/lib/webpack/railtie.rb000066400000000000000000000033201314524572300204720ustar00rootroot00000000000000require 'rails' require 'rails/railtie' require 'webpack/rails/helper' module Webpack # :nodoc: class Railtie < ::Rails::Railtie config.after_initialize do ActiveSupport.on_load(:action_view) do include Webpack::Rails::Helper end end config.webpack = ActiveSupport::OrderedOptions.new config.webpack.dev_server = ActiveSupport::OrderedOptions.new config.webpack.config_file = 'config/webpack.config.js' config.webpack.binary = 'node_modules/.bin/webpack' # Host & port to use when generating asset URLS in the manifest helpers in dev # server mode. Defaults to the requested host rather than localhost, so # that requests from remote hosts work. config.webpack.dev_server.host = proc { respond_to?(:request) ? request.host : 'localhost' } config.webpack.dev_server.port = 3808 # The host and port to use when fetching the manifest # This is helpful for e.g. docker containers, where the host and port you # use via the web browser is not the same as those that the containers use # to communicate among each other config.webpack.dev_server.manifest_host = 'localhost' config.webpack.dev_server.manifest_port = 3808 config.webpack.dev_server.https = false # Below will default to 'true' in 1.0 release config.webpack.dev_server.https_verify_peer = false config.webpack.dev_server.binary = 'node_modules/.bin/webpack-dev-server' config.webpack.dev_server.enabled = ::Rails.env.development? || ::Rails.env.test? config.webpack.output_dir = "public/webpack" config.webpack.public_path = "webpack" config.webpack.manifest_filename = "manifest.json" rake_tasks do load "tasks/webpack.rake" end end end webpack-rails-0.9.11/spec/000077500000000000000000000000001314524572300152665ustar00rootroot00000000000000webpack-rails-0.9.11/spec/helper_spec.rb000066400000000000000000000051261314524572300201100ustar00rootroot00000000000000require 'spec_helper' describe 'webpack_asset_paths' do let(:source) { 'entry_point' } let(:asset_paths) { %w(/a/a.js /b/b.css) } include Webpack::Rails::Helper before do allow(Webpack::Rails::Manifest).to receive(:asset_paths).with(source).and_return(asset_paths) end it "should return paths straight from te manifest if the dev server is disabled" do ::Rails.configuration.webpack.dev_server.enabled = false expect(webpack_asset_paths source).to eq(asset_paths) end it "should allow us to filter asset paths by extension" do ::Rails.configuration.webpack.dev_server.enabled = false expect(webpack_asset_paths(source, extension: 'js')).to eq(["/a/a.js"]) expect(webpack_asset_paths(source, extension: 'css')).to eq(["/b/b.css"]) expect(webpack_asset_paths(source, extension: 'html')).to eq([]) end it "should have the user talk to the dev server if it's enabled for each path returned from the manifest defaulting to localhost" do ::Rails.configuration.webpack.dev_server.enabled = true ::Rails.configuration.webpack.dev_server.host = 'webpack.host' ::Rails.configuration.webpack.dev_server.port = 4000 expect(webpack_asset_paths source).to eq([ "http://webpack.host:4000/a/a.js", "http://webpack.host:4000/b/b.css" ]) end it "should use https protocol when https is true" do ::Rails.configuration.webpack.dev_server.https = true expect(webpack_asset_paths(source, extension: 'js').first).to be_starts_with('https:') end it "should use http protocol when https is false" do ::Rails.configuration.webpack.dev_server.https = false expect(webpack_asset_paths(source, extension: 'js').first).to be_starts_with('http:') end it "should have the user talk to the specified dev server if it's enabled for each path returned from the manifest" do ::Rails.configuration.webpack.dev_server.enabled = true ::Rails.configuration.webpack.dev_server.port = 4000 ::Rails.configuration.webpack.dev_server.host = 'webpack.host' expect(webpack_asset_paths source).to eq([ "http://webpack.host:4000/a/a.js", "http://webpack.host:4000/b/b.css" ]) end it "allows for the host to be evaluated at request time" do # Simulate the helper context request = double(:request, host: 'evaluated') ::Rails.configuration.webpack.dev_server.enabled = true ::Rails.configuration.webpack.dev_server.port = 4000 ::Rails.configuration.webpack.dev_server.host = proc { request.host } expect(webpack_asset_paths source).to eq([ "http://evaluated:4000/a/a.js", "http://evaluated:4000/b/b.css" ]) end end webpack-rails-0.9.11/spec/manifest_spec.rb000066400000000000000000000103561314524572300204400ustar00rootroot00000000000000require 'spec_helper' require 'json' describe "Webpack::Rails::Manifest" do let(:manifest) do <<-EOF { "errors": [], "assetsByChunkName": { "entry1": [ "entry1.js", "entry1-a.js" ], "entry2": "entry2.js" } } EOF end shared_examples_for "a valid manifest" do it "should return single entry asset paths from the manifest" do expect(Webpack::Rails::Manifest.asset_paths("entry2")).to eq(["/public_path/entry2.js"]) end it "should return multiple entry asset paths from the manifest" do expect(Webpack::Rails::Manifest.asset_paths("entry1")).to eq(["/public_path/entry1.js", "/public_path/entry1-a.js"]) end it "should error on a missing entry point" do expect { Webpack::Rails::Manifest.asset_paths("herp") }.to raise_error(Webpack::Rails::Manifest::EntryPointMissingError) end end before do # Test that config variables work while we're here ::Rails.configuration.webpack.dev_server.host = 'client-host' ::Rails.configuration.webpack.dev_server.port = 2000 ::Rails.configuration.webpack.dev_server.manifest_host = 'server-host' ::Rails.configuration.webpack.dev_server.manifest_port = 4000 ::Rails.configuration.webpack.manifest_filename = "my_manifest.json" ::Rails.configuration.webpack.public_path = "public_path" ::Rails.configuration.webpack.output_dir = "manifest_output" end context "with dev server enabled" do before do ::Rails.configuration.webpack.dev_server.enabled = true stub_request(:get, "http://server-host:4000/public_path/my_manifest.json").to_return(body: manifest, status: 200) end describe :asset_paths do it_should_behave_like "a valid manifest" it "should error if we can't find the manifest" do ::Rails.configuration.webpack.manifest_filename = "broken.json" stub_request(:get, "http://server-host:4000/public_path/broken.json").to_raise(SocketError) expect { Webpack::Rails::Manifest.asset_paths("entry1") }.to raise_error(Webpack::Rails::Manifest::ManifestLoadError) end describe "webpack errors" do context "when webpack has 'Module build failed' errors in its manifest" do it "should error" do error_manifest = JSON.parse(manifest).merge("errors" => [ "somethingModule build failed something", "I am an error" ]).to_json stub_request(:get, "http://server-host:4000/public_path/my_manifest.json").to_return(body: error_manifest, status: 200) expect { Webpack::Rails::Manifest.asset_paths("entry1") }.to raise_error(Webpack::Rails::Manifest::WebpackError) end end context "when webpack does not have 'Module build failed' errors in its manifest" do it "should not error" do error_manifest = JSON.parse(manifest).merge("errors" => ["something went wrong"]).to_json stub_request(:get, "http://server-host:4000/public_path/my_manifest.json").to_return(body: error_manifest, status: 200) expect { Webpack::Rails::Manifest.asset_paths("entry1") }.to_not raise_error end end it "should not error if errors is present but empty" do error_manifest = JSON.parse(manifest).merge("errors" => []).to_json stub_request(:get, "http://server-host:4000/public_path/my_manifest.json").to_return(body: error_manifest, status: 200) expect { Webpack::Rails::Manifest.asset_paths("entry1") }.to_not raise_error end end end end context "with dev server disabled" do before do ::Rails.configuration.webpack.dev_server.enabled = false allow(File).to receive(:read).with(::Rails.root.join("manifest_output/my_manifest.json")).and_return(manifest) end describe :asset_paths do it_should_behave_like "a valid manifest" it "should error if we can't find the manifest" do ::Rails.configuration.webpack.manifest_filename = "broken.json" allow(File).to receive(:read).with(::Rails.root.join("manifest_output/broken.json")).and_raise(Errno::ENOENT) expect { Webpack::Rails::Manifest.asset_paths("entry1") }.to raise_error(Webpack::Rails::Manifest::ManifestLoadError) end end end end webpack-rails-0.9.11/spec/spec_helper.rb000066400000000000000000000004701314524572300201050ustar00rootroot00000000000000require "rspec" require "rails" require "webpack/rails" require 'webmock/rspec' module Dummy # :nodoc: class Application < Rails::Application config.eager_load = false end end Rails.application.initialize! # Load support files Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f } webpack-rails-0.9.11/webpack-rails.gemspec000066400000000000000000000014741314524572300204330ustar00rootroot00000000000000$:.push File.expand_path("../lib", __FILE__) # Maintain your gem's version: require "webpack/rails/version" # Describe your gem and declare its dependencies: Gem::Specification.new do |s| s.name = "webpack-rails" s.version = Webpack::Rails::VERSION s.authors = ["Michael Pearson"] s.email = ["mipearson@gmail.com"] s.homepage = "http://github.com/mipearson/webpack-rails" s.summary = "No longer maintained - use webpacker instead." s.description = "No longer maintained - use webpacker instead." s.license = "MIT" s.files = Dir["{app,config,db,lib,example}/**/*", "MIT-LICENSE", "Rakefile", "README.md"] s.test_files = Dir["test/**/*"] s.add_dependency "railties", ">= 3.2.0" s.add_development_dependency "rails", ">= 3.2.0" s.required_ruby_version = '>= 2.0.0' end